diff --git a/.gitignore b/.gitignore index 9a9bbe0aafd..861b69b8be0 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ data/ /_maps/map_files/**/*.dmm.backup /_maps/quicksave/* /nano/debug.html +**/__pycache__/* *.db stddef.dm .atom-build.json diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 0b450df9848..ed0845ed33f 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -274,6 +274,7 @@ CREATE TABLE `player` ( `nanoui_fancy` smallint(4) DEFAULT '1', `show_ghostitem_attack` smallint(4) DEFAULT '1', `lastchangelog` varchar(32) NOT NULL DEFAULT '0', + `windowflashing` smallint(4) DEFAULT '1', `exp` mediumtext, PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql index 2489e6cb325..216082157d4 100644 --- a/SQL/paradise_schema_prefixed.sql +++ b/SQL/paradise_schema_prefixed.sql @@ -273,6 +273,7 @@ CREATE TABLE `SS13_player` ( `nanoui_fancy` smallint(4) DEFAULT '1', `show_ghostitem_attack` smallint(4) DEFAULT '1', `lastchangelog` varchar(32) NOT NULL DEFAULT '0', + `windowflashing` smallint(4) DEFAULT '1', `exp` mediumtext, PRIMARY KEY (`id`), UNIQUE KEY `ckey` (`ckey`) diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 89a73aceaaf..e0956c3ebe3 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -1,11 +1,11 @@ "aaa" = (/turf/space,/area/space) "aab" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_n"; name = "north of station"; width = 18},/turf/space,/area/space) -"aac" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) +"aac" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) "aad" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate) "aae" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) "aaf" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_mid"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) "aag" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (NORTH)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) -"aah" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate) +"aah" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate) "aai" = (/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate) "aaj" = (/obj/structure/table,/obj/machinery/kitchen_machine/microwave,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "aak" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) @@ -29,7 +29,7 @@ "aaC" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "aaD" = (/obj/effect/landmark{name = "carpspawn"},/turf/space,/area/space) "aaE" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) -"aaF" = (/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate) +"aaF" = (/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate) "aaG" = (/obj/structure/closet/syndicate/suits,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "aaH" = (/obj/effect/landmark{name = "Syndicate-Uplink"; tag = ""},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "aaI" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) @@ -115,13 +115,13 @@ "ack" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/security/prison) "acl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/twohanded/required/kirbyplants{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acm" = (/obj/machinery/biogenerator,/obj/machinery/light/small{dir = 4},/obj/machinery/camera{c_tag = "Prison Hydroponics"; network = list("SS13","Prison")},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) -"acn" = (/obj/item/seeds/ambrosiavulgarisseed,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acn" = (/obj/item/seeds/ambrosia,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "aco" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/prison) "acp" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acq" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acr" = (/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) -"acs" = (/obj/item/seeds/glowshroom,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) -"act" = (/obj/item/weapon/minihoe,/obj/item/seeds/carrotseed,/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acs" = (/obj/item/seeds/glowshroom,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"act" = (/obj/item/weapon/cultivator,/obj/item/seeds/carrot,/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acu" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/pod_2) "acv" = (/obj/structure/window/full/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/pod_2) "acw" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/shuttle/pod_2) @@ -129,7 +129,7 @@ "acy" = (/obj/docking_port/stationary{dir = 2; dwidth = 2; height = 18; id = "skipjack_nw"; name = "northwest of SS13"; width = 19},/turf/space,/area/space) "acz" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating/airless/catwalk,/area/solar/auxport) "acA" = (/turf/simulated/wall/r_wall,/area/prison/solitary{name = "Prisoner Education Chamber"}) -"acB" = (/obj/item/device/analyzer/plant_analyzer,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acB" = (/obj/item/device/plant_analyzer,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acC" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acD" = (/turf/simulated/floor/plasteel,/area/security/prison) "acE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) @@ -1050,7 +1050,7 @@ "auj" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/camera/autoname{dir = 4; network = list("SS13")},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "auk" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = "90Curve"},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aul" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/terminal,/obj/machinery/light/small{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aum" = (/obj/machinery/door/airlock/maintenance{icon = 'icons/obj/doors/doorint.dmi'; name = "Brig Emergency Storage"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/brig) +"aum" = (/obj/machinery/door/airlock/maintenance{icon = 'icons/obj/doors/Doorint.dmi'; name = "Brig Emergency Storage"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/brig) "aun" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel,/area/security/podbay) "auo" = (/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/maintenance/starboard) "aup" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) @@ -2133,11 +2133,11 @@ "aPa" = (/obj/machinery/door/firedoor,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock{name = "Dormitories"; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/sleep) "aPb" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/crew_quarters/sleep) "aPc" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock{name = "Dormitories"; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/sleep) -"aPd" = (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/rh{pixel_x = 2; pixel_y = 1},/obj/structure/table,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aPd" = (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh{pixel_x = 2; pixel_y = 1},/obj/structure/table,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aPe" = (/obj/machinery/biogenerator,/obj/machinery/firealarm{pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aPf" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/machinery/light{dir = 1},/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aPf" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/machinery/light{dir = 1},/obj/item/device/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aPg" = (/obj/machinery/seed_extractor,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aPh" = (/obj/item/seeds/appleseed,/obj/item/seeds/bananaseed,/obj/item/seeds/cocoapodseed,/obj/item/seeds/grapeseed,/obj/item/seeds/orangeseed,/obj/item/seeds/sugarcaneseed,/obj/item/seeds/wheatseed,/obj/item/seeds/watermelonseed,/obj/structure/table,/obj/item/seeds/towermycelium,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aPh" = (/obj/item/seeds/apple,/obj/item/seeds/banana,/obj/item/seeds/cocoapod,/obj/item/seeds/grape,/obj/item/seeds/orange,/obj/item/seeds/sugarcane,/obj/item/seeds/wheat,/obj/item/seeds/watermelon,/obj/structure/table,/obj/item/seeds/tower,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aPi" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aPj" = (/mob/living/simple_animal/chicken{name = "Featherbottom"; real_name = "Featherbottom"},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aPk" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/item/weapon/wirecutters,/obj/item/weapon/weldingtool,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/starboard) @@ -2287,7 +2287,7 @@ "aRY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=14.5-Recreation"; location = "14.3-Lockers-Dorms"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aRZ" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) "aSa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aSb" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aSb" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aSc" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) "aSd" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/mob/living/simple_animal/chicken{name = "Kentucky"; real_name = "Kentucky"},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aSe" = (/obj/structure/window/reinforced,/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) @@ -2421,7 +2421,7 @@ "aUC" = (/obj/structure/rack,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 4; pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aUD" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aUF" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aUF" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/hydroponics/soil,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aUG" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUH" = (/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUI" = (/obj/structure/rack,/obj/item/clothing/gloves/color/fyellow,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/starboard) @@ -2559,11 +2559,11 @@ "aXk" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "aXl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/crew_quarters/locker) "aXm" = (/obj/structure/rack,/obj/item/weapon/storage/briefcase,/obj/item/weapon/storage/briefcase{pixel_x = 4; pixel_y = -2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/locker) -"aXn" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/paper/hydroponics,/obj/item/weapon/coin/silver,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aXo" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/device/analyzer/plant_analyzer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aXp" = (/obj/structure/table,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aXn" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/paper/hydroponics,/obj/item/weapon/coin/silver,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aXo" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/device/plant_analyzer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aXp" = (/obj/structure/table,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aXq" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) -"aXr" = (/obj/structure/table,/obj/machinery/light,/obj/item/device/analyzer/plant_analyzer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) +"aXr" = (/obj/structure/table,/obj/machinery/light,/obj/item/device/plant_analyzer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/construction{name = "\improper Garden"}) "aXs" = (/obj/item/weapon/book/manual/engineering_hacking{pixel_x = 4; pixel_y = 5},/obj/item/weapon/book/manual/engineering_construction{pixel_x = 0; pixel_y = 3},/obj/structure/closet/crate,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/starboard) "aXt" = (/obj/machinery/power/terminal,/obj/structure/cable,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"; tag = "icon-warnwhite (NORTHEAST)"},/area/engine/engineering) "aXu" = (/obj/machinery/power/terminal,/obj/structure/cable,/turf/simulated/floor/plasteel{dir = 2; icon_state = "warning"},/area/engine/engineering) @@ -3194,7 +3194,7 @@ "bjv" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/robotics{pixel_x = -2; pixel_y = 2},/obj/item/weapon/circuitboard/mecha_control{pixel_x = 1; pixel_y = -1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 1},/area/storage/tech) "bjw" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) "bjx" = (/obj/machinery/vending/assist,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) -"bjy" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) +"bjy" = (/obj/structure/table,/obj/item/device/plant_analyzer,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) "bjz" = (/obj/structure/table,/obj/item/device/analyzer,/obj/item/device/healthanalyzer,/obj/machinery/camera/autoname{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) "bjA" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/obj/item/device/multitool,/obj/item/clothing/glasses/meson,/obj/machinery/light_switch{pixel_x = 0; pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/tech) "bjB" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/storage/tech) @@ -3353,7 +3353,7 @@ "bmy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/junction{dir = 2; icon_state = "pipe-j1"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bmz" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "browncorner"},/area/hallway/primary/port) "bmA" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 2; icon_state = "brown"},/area/hallway/primary/port) -"bmB" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/doorint.dmi'; name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/starboard) +"bmB" = (/obj/machinery/door/airlock{icon = 'icons/obj/doors/Doorint.dmi'; name = "Starboard Emergency Storage"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/starboard) "bmC" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/simple_animal/lizard{name = "Wags-His-Tail"; real_name = "Wags-His-Tail"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) "bmD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/effect/landmark/start{name = "Janitor"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) "bmE" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/mop,/obj/structure/disposalpipe/segment,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/janitor) @@ -3595,7 +3595,7 @@ "brg" = (/obj/machinery/door/window/eastright{dir = 4; name = "MiniSat Walkway Access"; req_access_txt = "13;75"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/construction/hallway{name = "\improper MiniSat Exterior"}) "brh" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) "bri" = (/turf/simulated/wall/r_wall,/area/turret_protected/aisat_interior{name = "\improper MiniSat Central Foyer"}) -"brj" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) +"brj" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1443; icon_state = "on"; id = "air_in"; on = 1},/turf/simulated/floor/plating/airless,/area/construction/hallway{name = "\improper MiniSat Exterior"}) "brk" = (/turf/simulated/wall/r_wall,/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "brl" = (/obj/structure/table/reinforced{tag = "icon-table"; icon_state = "table"},/obj/item/weapon/folder/blue{pixel_x = 5},/obj/item/weapon/pen/multi,/obj/machinery/light/small{tag = "icon-bulb1 (WEST)"; icon_state = "bulb1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "brm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/ai_status_display{pixel_y = -32},/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) @@ -3651,7 +3651,7 @@ "bsk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/primary/central) "bsl" = (/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/central) "bsm" = (/turf/simulated/wall,/area/civilian/barber) -"bsn" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) +"bsn" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating/airless,/area/construction/hallway{name = "\improper MiniSat Exterior"}) "bso" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{icon = 'icons/obj/doors/Doorengglass.dmi'; name = "Barber Shop"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/civilian/barber) "bsp" = (/turf/simulated/wall,/area/crew_quarters/bar) "bsq" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/starboard) @@ -3684,7 +3684,7 @@ "bsR" = (/obj/structure/transit_tube{icon_state = "E-SW"; tag = "icon-E-NW"},/obj/structure/lattice,/turf/space,/area/space) "bsS" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/space,/area/space) "bsT" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/construction/hallway{name = "\improper MiniSat Exterior"}) -"bsU" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) +"bsU" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor/plating/airless,/area/construction/hallway{name = "\improper MiniSat Exterior"}) "bsV" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/teleport/station,/turf/simulated/floor/plasteel{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/turret_protected/tcomfoyer{name = "\improper MiniSat Teleporter Foyer"}) "bsW" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/computer/teleporter,/turf/simulated/floor/plasteel{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/turret_protected/tcomfoyer{name = "\improper MiniSat Teleporter Foyer"}) "bsX" = (/obj/machinery/teleport/hub,/turf/simulated/floor/plasteel{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/turret_protected/tcomfoyer{name = "\improper MiniSat Teleporter Foyer"}) @@ -5028,7 +5028,7 @@ "bSJ" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/pump,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/atmos) "bSK" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1; initialize_directions = 11},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 8},/area/atmos) "bSL" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plasteel,/area/atmos) -"bSM" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 9},/turf/simulated/floor/plasteel,/area/atmos) +"bSM" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 9},/obj/structure/reagent_dispensers/watertank/high,/turf/simulated/floor/plasteel,/area/atmos) "bSN" = (/obj/structure/reagent_dispensers/fueltank,/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -26},/obj/machinery/camera{c_tag = "Atmospherics - Central"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel,/area/atmos) "bSO" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/gloves/color/black,/obj/item/clothing/gloves/color/black,/obj/item/clothing/gloves/color/black,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/simulated/floor/plasteel,/area/atmos) "bSP" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plasteel,/area/atmos) @@ -5447,9 +5447,9 @@ "caM" = (/obj/machinery/reagentgrinder,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) "caN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) "caO" = (/obj/machinery/chem_master/condimaster{name = "BrewMaster 4000"; pixel_x = -4},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) -"caP" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/window/reinforced{dir = 8},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 29},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) -"caQ" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) -"caR" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) +"caP" = (/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/structure/reagent_dispensers/watertank/high,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) +"caQ" = (/obj/structure/window/reinforced{dir = 8},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 29},/obj/structure/reagent_dispensers/watertank/high,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) +"caR" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hydroponics) "caS" = (/obj/structure/closet{name = "spare parts locker"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/item/weapon/rack_parts,/obj/item/weapon/rack_parts,/obj/item/weapon/wrench,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/kitchen) "caT" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/window/eastright{dir = 1; name = "Kitchen Delivery"; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/crew_quarters/kitchen) "caU" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Kitchen"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/crew_quarters/kitchen) @@ -5564,12 +5564,12 @@ "ccZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Botanist"},/turf/simulated/floor/plasteel{dir = 10; icon_state = "green"},/area/hydroponics) "cda" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 6},/area/hydroponics) "cdb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) -"cdc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) -"cdd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) +"cdc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) +"cdd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) "cde" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) "cdf" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) -"cdg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) -"cdh" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) +"cdg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) +"cdh" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) "cdi" = (/obj/machinery/seed_extractor,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hydroponics) "cdj" = (/obj/structure/closet/secure_closet/hydroponics,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/storage/backpack/satchel_hyd,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "cdk" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/firealarm{pixel_y = 29},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) @@ -5634,7 +5634,7 @@ "cer" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) "ces" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) "cet" = (/obj/effect/landmark/start{name = "Botanist"},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) -"ceu" = (/obj/item/seeds/wheatseed,/obj/item/seeds/sugarcaneseed,/obj/item/seeds/potatoseed,/obj/item/seeds/appleseed,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/camera/autoname{dir = 8; network = list("SS13")},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hydroponics) +"ceu" = (/obj/item/seeds/wheat,/obj/item/seeds/sugarcane,/obj/item/seeds/potato,/obj/item/seeds/apple,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/camera/autoname{dir = 8; network = list("SS13")},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hydroponics) "cev" = (/obj/structure/closet/secure_closet/hydroponics,/obj/item/weapon/storage/backpack/satchel_hyd,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "cew" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/effect/landmark/start{name = "Botanist"},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "cex" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2"; icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor/plating,/area/maintenance/starboard) @@ -5693,7 +5693,7 @@ "cfy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) "cfz" = (/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hallway/primary/central) "cfA" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hallway/primary/central) -"cfB" = (/obj/item/weapon/minihoe,/obj/item/weapon/crowbar,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hallway/primary/central) +"cfB" = (/obj/item/weapon/cultivator,/obj/item/weapon/crowbar,/obj/item/device/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hallway/primary/central) "cfC" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 9; icon_state = "green"},/area/hydroponics) "cfD" = (/obj/effect/landmark/start{name = "Botanist"},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) "cfE" = (/obj/machinery/biogenerator,/obj/machinery/light_switch{pixel_x = 26; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/hydroponics) @@ -5841,11 +5841,11 @@ "ciq" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/hallway/primary/central) "cir" = (/obj/machinery/disposal{pixel_x = -2; pixel_y = -2},/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light_switch{pixel_y = -28},/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/hydroponics) "cis" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/hydroponics) -"cit" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) -"ciu" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) -"civ" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "Hydroponics APC"; pixel_x = 0; pixel_y = -28},/obj/structure/cable/yellow,/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) -"ciw" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) -"cix" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) +"cit" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) +"ciu" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) +"civ" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "Hydroponics APC"; pixel_x = 0; pixel_y = -28},/obj/structure/cable/yellow,/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) +"ciw" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) +"cix" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) "ciy" = (/obj/item/weapon/wrench,/obj/item/clothing/suit/apron,/obj/item/clothing/accessory/armband/hydro,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hydroponics) "ciz" = (/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 0; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 8; pixel_y = 8},/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weapon/watertank,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/item/weapon/grenade/chem_grenade/antiweed,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) "ciA" = (/obj/machinery/door/window/eastright{dir = 1; name = "Hydroponics Delivery"; req_access_txt = "35"},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/hydroponics) @@ -7257,7 +7257,7 @@ "cJC" = (/turf/simulated/floor/plating/airless{dir = 8; icon_state = "warnplate"},/area/toxins/test_area) "cJD" = (/turf/simulated/floor/plating/airless{dir = 4; icon_state = "warnplate"},/area/toxins/test_area) "cJE" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plating/airless,/area/toxins/test_area) -"cJF" = (/obj/machinery/botany/extractor,/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) +"cJF" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/plantgenes,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) "cJG" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/toxins/test_area) "cJH" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/virology) "cJI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/carbon/human/monkey,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/virology) @@ -7306,7 +7306,7 @@ "cKz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine,/area/toxins/mixing{name = "\improper Toxins Lab"}) "cKA" = (/obj/machinery/sparker{dir = 2; id = "mixingsparker"; pixel_x = 25},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 0; initialize_directions = 1; internal_pressure_bound = 4000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine,/area/toxins/mixing{name = "\improper Toxins Lab"}) "cKB" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/mixing{name = "\improper Toxins Lab"}) -"cKC" = (/obj/machinery/botany/editor,/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) +"cKC" = (/obj/machinery/light,/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hydroponics) "cKD" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/obj/machinery/embedded_controller/radio/airlock{tag_airpump = "tox_airlock_pump"; tag_exterior_door = "tox_airlock_exterior"; id_tag = "tox_airlock_control"; tag_interior_door = "tox_airlock_interior"; pixel_x = -24; pixel_y = 0; tag_chamber_sensor = "tox_airlock_sensor"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warnwhitecorner"},/area/toxins/mixing{name = "\improper Toxins Lab"}) "cKE" = (/obj/machinery/atmospherics/binary/valve{dir = 4; name = "manual outlet valve"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/toxins/mixing{name = "\improper Toxins Lab"}) "cKF" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/structure/window/reinforced{dir = 1; pixel_y = 2},/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/toxins/mixing{name = "\improper Toxins Lab"}) @@ -7532,7 +7532,7 @@ "cOR" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel{pixel_y = 12},/obj/structure/window/reinforced{dir = 1; pixel_y = 1},/obj/item/weapon/razor{pixel_y = 5},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitehall"},/area/assembly/robotics) "cOS" = (/obj/effect/landmark/start{name = "Roboticist"},/obj/structure/sink{dir = 8; icon_state = "sink"; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "cOT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) -"cOU" = (/obj/machinery/requests_console{department = "Genetics"; departmentType = 0; name = "Genetics Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/box/monkeycubes,/obj/structure/noticeboard{desc = "A board for pinning important notices upon."; name = "notice board"; pixel_x = -32; pixel_y = 32},/obj/structure/table/glass,/obj/item/weapon/storage/box/farwacubes{pixel_y = -2},/obj/item/weapon/storage/box/neaeracubes{pixel_x = 2},/obj/item/weapon/storage/box/stokcubes{pixel_x = -2},/obj/item/weapon/storage/box/wolpincubes{pixel_y = 2},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/genetics) +"cOU" = (/obj/machinery/requests_console{department = "Genetics"; departmentType = 0; name = "Genetics Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/box/monkeycubes,/obj/structure/noticeboard{desc = "A board for pinning important notices upon."; name = "notice board"; pixel_x = -32; pixel_y = 32},/obj/structure/table/glass,/obj/item/weapon/storage/box/monkeycubes/farwacubes{pixel_y = -2},/obj/item/weapon/storage/box/monkeycubes/neaeracubes{pixel_x = 2},/obj/item/weapon/storage/box/monkeycubes/stokcubes{pixel_x = -2},/obj/item/weapon/storage/box/monkeycubes/wolpincubes{pixel_y = 2},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/medical/genetics) "cOV" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/robotics) "cOW" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = 2; pixel_y = 2},/obj/item/borg/upgrade/rename,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/robotics) "cOX" = (/obj/structure/rack,/obj/item/weapon/storage/toolbox/electrical{pixel_x = -1; pixel_y = 4},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 2; pixel_y = -1},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/glasses/welding,/obj/item/device/multitool{pixel_x = 3},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/robotics) @@ -7761,11 +7761,11 @@ "cTm" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cTn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cTo" = (/obj/machinery/biogenerator,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cTp" = (/obj/structure/rack{layer = 2.8},/obj/item/seeds/wheatseed,/obj/item/seeds/watermelonseed,/obj/item/seeds/watermelonseed,/obj/item/seeds/grapeseed,/obj/item/seeds/glowshroom,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cTq" = (/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/minihoe,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/rack{layer = 2.8},/obj/item/seeds/cornseed,/obj/item/seeds/cabbageseed,/obj/item/seeds/ambrosiavulgarisseed,/obj/item/seeds/grassseed,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cTr" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/carrotseed,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cTs" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/glowshroom,/obj/item/seeds/cornseed,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cTt" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/device/analyzer/plant_analyzer,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cTp" = (/obj/structure/rack{layer = 2.8},/obj/item/seeds/wheat,/obj/item/seeds/watermelon,/obj/item/seeds/watermelon,/obj/item/seeds/grape,/obj/item/seeds/glowshroom,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cTq" = (/obj/item/device/plant_analyzer,/obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/rack{layer = 2.8},/obj/item/seeds/corn,/obj/item/seeds/cabbage,/obj/item/seeds/ambrosia,/obj/item/seeds/grass,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cTr" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/carrot,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cTs" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/glowshroom,/obj/item/seeds/corn,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) +"cTt" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/device/plant_analyzer,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) "cTu" = (/obj/machinery/power/solar_control{id = "aftstarboard"; name = "Aft Starboard Solar Control"; track = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cTv" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/starboardsolar) "cTw" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/starboardsolar) @@ -7799,7 +7799,7 @@ "cTY" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cTZ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/preopen{id_tag = "chapelparlourshutters"; name = "chapel shutters"},/turf/simulated/floor/plating,/area/chapel/main) "cUa" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/aft{name = "Aft Maintenance"}) -"cUb" = (/obj/item/seeds/watermelonseed,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cUb" = (/obj/item/seeds/watermelon,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cUc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cUd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/stool/bed/chair,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cUe" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/preopen{id_tag = "chapelspaceshutters"; name = "chapel shutters"},/turf/simulated/floor/plating,/area/chapel/main) @@ -7834,7 +7834,7 @@ "cUH" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cUI" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) "cUJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cUK" = (/obj/item/seeds/berryseed,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"cUK" = (/obj/item/seeds/berry,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cUL" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cUM" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) "cUN" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office) @@ -7864,11 +7864,11 @@ "cVl" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/door/poddoor/preopen{id_tag = "xenobio8"; name = "containment blast door"},/turf/simulated/floor/plating,/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cVm" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable/yellow,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/door/poddoor/preopen{id_tag = "xenobio3"; name = "containment blast door"},/turf/simulated/floor/plating,/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cVn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) -"cVo" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/glowshroom,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) -"cVp" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/weapon/minihoe,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) -"cVq" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/ambrosiavulgarisseed,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) -"cVr" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/watermelonseed,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) -"cVs" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/item/seeds/berryseed,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"cVo" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/glowshroom,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"cVp" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/weapon/cultivator,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"cVq" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/ambrosia,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"cVr" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/watermelon,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) +"cVs" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/item/seeds/berry,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/aft{name = "Aft Maintenance"}) "cVt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/chapel/office) "cVu" = (/obj/machinery/door/airlock/centcom{name = "Chapel Office"; opacity = 1; req_access_txt = "27"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office) "cVv" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "chapel"},/area/chapel/main) @@ -7938,14 +7938,14 @@ "cWH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/stool/bed/chair/comfy/beige{dir = 4},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor/wood,/area/medical/psych) "cWI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/wood,/area/medical/psych) "cWJ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/starboardsolar) -"cWK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/space,/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) -"cWL" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/space,/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) +"cWK" = (/turf/space,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) +"cWL" = (/turf/space,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) "cWM" = (/obj/machinery/door/window/eastleft{dir = 4; name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor/plating,/area/chapel/main) "cWN" = (/obj/structure/stool/bed/chair{pixel_y = -2},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/chapel/main) "cWO" = (/obj/structure/stool/bed/chair{pixel_y = -2},/obj/effect/landmark/start{name = "Chaplain"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/chapel/main) "cWP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "cWQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) -"cWR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/space,/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) +"cWR" = (/turf/space,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) "cWS" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/research) "cWT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) "cWU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{dir = 4; icon_state = "chapel"},/area/chapel/main) @@ -8012,7 +8012,7 @@ "cYd" = (/turf/simulated/shuttle/floor,/area/shuttle/research) "cYe" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/shuttle/research) "cYf" = (/obj/structure/cable,/turf/simulated/floor/plating/airless/catwalk,/area/solar/starboard) -"cYg" = (/obj/machinery/portable_atmospherics/hydroponics/soil{pixel_y = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/main) +"cYg" = (/obj/machinery/hydroponics/soil{pixel_y = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/main) "cYh" = (/obj/machinery/door/morgue{name = "Chapel Garden"; req_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/main) "cYi" = (/obj/machinery/light/small,/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/door_control{id = "chapelparlourshutters"; name = "Window Shutter Control"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/chapel/main) "cYj" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/chapel/main) @@ -8610,7 +8610,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaUNbWcbfdaUNdghdgjdgibBtdgkbBtdgldgmapfbWdbWebWfbWgbWhbWgbWibFpbFpbFpbFpbWjbFpbFpbFpbWkdeJdeHapdbWlbWmapfbWnbWobzKbWpbWqbWrbWsbWtbWubWvbzKbWwbWxbWybzKbzPbfIbWzbMSbQdbTEbWAbWBbQdbOBbWCbWDbWEbWFbMWbWGbWHbWIbWJbWKbWLbWMbWNbWObWPbWQbNhbWRbWSbWTbWUbWVbWWbWXbWYbWZbXabhtbXbbbrbOWbQvbYubXdbXdbXebXfbXgbXhbXibXjbQIbXkbVxbXlbXmbXnbQIbXobXpbXqbXrbEGbNFbQVbQVbQVbQVbQVbXsasJasJbXtbCMbVNbVObRabXubXvbVQbXwbInbSPbXxbRgbXybRibzLabqbzLbXzbXAbXBbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdaXHbdMbeWbeXbeXbeXbeXbIFbIFceqbIFbIFbeXbeXbeXbeXbeYbdMaXOabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqabqabqaUNbUBbUBaUNdgndgjbBtbBtdgobBtdgpdgqapfbXHavUavUavUbDLathatkaoXaqBayBanHbXIauyauCapfapfapfapfapfbXKapfapfbFuatjbzKbXLbXMbXNbXNbWsbXObXPbzKbXQbXRbXSbzKbDQbfIbXTbMSbQdbXUbXVbXWbXXbOBbXYbXZbYabMWbMWbYbbYcbYdbYebYfbNdbYgbSdbYhbYibYjbNhbYkbYlbYmbYnbNUbYobYobYpbNhbYqbhtbYrbbrbOWbQIbYvbYEbYwbStcbacbbbUcbYxbYybYzbYAbYBbYCbYDccrbQIbEGbEGbEGbEGbEGbYFaoGbYGbUraucasJchGchFbYIasJbCMbCMbYJbNRbVPbCNbYKbYLbGGbYMbVRbRgbYNbSUbItbMjbMkbYObVVbYPbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdaXHbdMbeWbeXbeXbeXbeXbeXbeXbdObeXbeXbeXbeXbeXbeXbeYbdMaXOabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabredgrdgtdgsdgvdgudgxdgwdgyapfapfapfapfbWmbYRavUbYSbYTbYUbYVbYVdfibYWbYXbYVbYTbYVbYYbYVbYZbYVaPTbZaapdbzKbZbbZcbZdbZebHrbZfbZgbzKbzKbzKbzKbzKbZhbfIbOvdeEbMSbZjbZjbZjbMSbMSbMWbMWbZkbMWbMWbZlbZlbZlbZmbZlbZnbZnbZobZpbZnbZnbNhbNhbNhbNhbNhbNhbZqbZqbZqbNhbZrdeFbZsbbrbZtbZubZvbZvbZvbZwbZvbZvbZxbZybZvbZvbZvbZvbQIbZzbZAbZBbZCbZDbZEasJbZFbZGaoGbVLbZHbZIasJbYHckgasJarrbCMbZJbJWbZKbCNbCNbCNbZLbGGbZMbZNbRgbUwbRibzLabqbGLbGLbGLbGLbGLabqabqbRmabqbPGabqabeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdaXHbdMbKkbvhbvhbvhbvhbvhbvhbdObvhbvhbvhbvhbvhbvhbvibdMaXOabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgrdgfdgzdgzdgzdgzdgzdgAaaaabqaaabZPbZPbZQbZRbZSapfbZTapfapfapfaYabZUbZUbZUbZUbZUbZUbZUapdbZVbZWbZXbzKbZYbZZcaacabbHrbWscaccadcaeayBapfcafbzPcagcahcaicajcakcakcakcalcamcancaocakcapcaqcaicaicarcascarcarcatcarcaucavcavcawcaxcaycazcaAcaBcakcakcakcaCcaDcavcaEbbrcaFcaGbQAcaIcaJcaKcaLcaMcaNcaKcaOcaPcaQcaRbQIcaScaTcaUcaVcaWcaXcaYbZGcaZaoGaoGaoGaoGaoGcmHbXtbCMbCMbCMcbcbJWbNRcbdcbecbfbKacbgcbhcbibVScbjbPCbHGbIubIvcbkcblcblbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdclHcerbMrbMrbMrbMrbMrcLLcLLcQccLLcLLbMrbMrbMrbMrbMrbNXaWCabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgrdgfdgzdgzdgzdgzdgzdgAaaaabqaaabZPbZPbZQbZRbZSapfbZTapfapfapfaYabZUbZUbZUbZUbZUbZUbZUapdbZVbZWbZXbzKbZYbZZcaacabbHrbWscaccadcaeayBapfcafbzPcagcahcaicajcakcakcakcalcamcancaocakcapcaqcaicaicarcascarcarcatcarcaucavcavcawcaxcaycazcaAcaBcakcakcakcaCcaDcavcaEbbrcaFcaGbQAcaIcaJcaKcaLcaMcaNcaKcaOcaQcaPcaRbQIcaScaTcaUcaVcaWcaXcaYbZGcaZaoGaoGaoGaoGaoGcmHbXtbCMbCMbCMcbcbJWbNRcbdcbecbfbKacbgcbhcbibVScbjbPCbHGbIubIvcbkcblcblbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdclHcerbMrbMrbMrbMrbMrcLLcLLcQccLLcLLbMrbMrbMrbMrbMrbNXaWCabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgrdgJdgzdgzdgzdgzdgDdgraaaabqaaabZScbmcbncbobZSapdcbpbPQcbqapfcbrbZUcbscbtcbucbvcbwbZUapdaoXbZWaoXbzKbzKbzKbzKbzKbzKbzKbzKbzKaxqaoXapfcbxbzPcbycbzbekbekbekbekbekbekbenbekcbAcbBcbCbembekbekbekbvTcbDcbEcbFbekbekbekbekbekcbGcbHbekbekbenbekbekbekbekcbIbekcbAcbJcbKcbLcbMcbNcbOcbNcbPcbPcbQcbRcbScbPcbOcbTbQIbQIbQIbQIcbUcbVasIarrcbWcbXasIcbXcbYcbZaoGayoaoGbCMccaccbcccccdcceccfccfccfbMcbGGbGGbGGbRgccgbRibzLabqbzLcchcciccjbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdaaabPHbsdbsdbsdbPHbNYbbXcUIcUMcUIbbZaXOabqaaaaaaaaaabqaaaabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgrdgzdgzdgzdgzdgzdgzdgraaaabqabqbZSccnccoccpbZSapdccqcmIapfapfccsbZUcctccuccvccwccxbZUapdapdccybYVbYTbYVbYYbYVcczccAccAccAccAccBbcGccCccDccEccFccGccHccIccJccGccGccGccKccGbdabcXccLbcYbcXbcXbcXccMccNbcZbcYbcXbcXbcXbdbccOccPccQccQccQccRccQccQccQccSccTccOccUccVccWccXccYccZcdacdbcdccddcdecdfcdgcdhcdecdibZvcdjcdkbZvcdlcbVasIasIasIasIasIcdmcdncdocdpcdqcdrcdscdtcducdvcdwcdxbGGbGGbGGbGGbGGbInbGGbRgcdybSUbItbMjbMkcdzcblcdAbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdabdabdabdabdabdabdaXHcerbzhcWjbzhbNXaXOabdabdabdabdabdabdabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgrdgrdgBdgFdgFdgFdgrdgraaaabqaaabZScdCcdDcdEbZScdFapdcdGapfcdHcdIbZUcdJcdKcdLcdMcdNbZUbZUbZUbZUbZUbZUcdObZUbZUcdPcdQcdRaoXauycdSauCcdTcdTcdTcdTcdTcdTcdTcdUcdUcdUcdUcdUcdVcdWcdWcdXcdYcdWcdZcdWceacebbbrceccedceecefceecegcehceeceeceibZubbgbbibbicejbZucekbZubSlcembSlbZvcenceocfDcdhcitcescdfcixcdhcetceubZvcevcewbZvcexceycezcdocdocdocdoceAceBceCceDceCceEbPmceFceGceHbGGceIbPwbPwbPwbPwbPwceJbGGbRgbUwceKbCMabqbGLbGLbGLbGLbGLabqaaabFcaaabFbaaabFcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdaaabsdbsdbsdbsdbsdaaaabdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/MetaStation/z2.dmm b/_maps/map_files/MetaStation/z2.dmm index 59ab53037cc..69f2d4a567c 100644 --- a/_maps/map_files/MetaStation/z2.dmm +++ b/_maps/map_files/MetaStation/z2.dmm @@ -19,13 +19,13 @@ "as" = (/turf/unsimulated/wall{tag = "icon-iron10"; icon_state = "iron10"},/area/space) "at" = (/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow,/area/syndicate_mothership) "au" = (/obj/structure/flora/bush,/turf/unsimulated/floor/snow,/area/syndicate_mothership) -"av" = (/obj/structure/flora/tree/pine{pixel_x = 2},/turf/unsimulated/floor/snow,/area/syndicate_mothership) -"aw" = (/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"av" = (/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"aw" = (/obj/docking_port/stationary{area_type = /area/syndicate_mothership; dir = 1; dwidth = 5; height = 14; id = "emergency_syndicate"; name = "404 Not Found"; turf_type = /turf/unsimulated/floor/snow; width = 25},/turf/unsimulated/floor/snow,/area/syndicate_mothership) "ax" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"ay" = (/obj/structure/flora/tree/pine{pixel_x = 0},/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"ay" = (/obj/machinery/door/airlock/external{id_tag = "syndicate_away"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "az" = (/turf/unsimulated/floor/snow,/area/space) -"aA" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"aB" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"aA" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/syndicate_mothership) +"aB" = (/turf/unsimulated/wall/fakeglass{dir = 0; icon_state = "fakewindows"; tag = "icon-fakewindows (EAST)"},/area/syndicate_mothership) "aC" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "aD" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHEAST)"; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "aE" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) @@ -48,7 +48,7 @@ "aV" = (/turf/unsimulated/wall,/area/vox_station) "aW" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (EAST)"; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) "aX" = (/obj/machinery/computer/shuttle/syndicate/recall,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"aY" = (/obj/item/device/radio/intercom/syndicate{pixel_x = 0; pixel_y = 25},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"aY" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) "aZ" = (/obj/structure/flora/ausbushes/fullgrass,/turf/simulated/floor/holofloor{tag = "icon-asteroid"; icon_state = "asteroid"; dir = 2},/area/holodeck/source_desert) "ba" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid8 (EAST)"; icon_state = "asteroid8"; dir = 4},/area/holodeck/source_desert) "bb" = (/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor/grass,/area/holodeck/source_picnicarea) @@ -84,10 +84,10 @@ "bF" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet11-12 (EAST)"; icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_theatre) "bG" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_emptycourt) "bH" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_emptycourt) -"bI" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (EAST)"; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) +"bI" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "bJ" = (/turf/simulated/floor/holofloor{tag = "icon-carpet2-0 (EAST)"; icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre) -"bK" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) -"bL" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"bK" = (/obj/machinery/light{dir = 1; on = 1},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"bL" = (/obj/machinery/light{dir = 4},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "bM" = (/mob/living/simple_animal/pet/cat/Syndi,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "bN" = (/obj/machinery/door/airlock/external{id_tag = "syndicate_away"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "bO" = (/obj/docking_port/stationary{area_type = /area/syndicate_mothership; dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_away"; name = "syndicate recon outpost"; turf_type = /turf/unsimulated/floor/snow; width = 18},/turf/space,/area/space) @@ -98,7 +98,7 @@ "bT" = (/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) "bU" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'FOURTH WALL'."; name = "\improper FOURTH WALL"; pixel_x = -32},/turf/unsimulated/floor/snow,/area/syndicate_mothership) "bV" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid1 (EAST)"; icon_state = "asteroid1"; dir = 4},/area/holodeck/source_desert) -"bW" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"bW" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) "bX" = (/turf/simulated/floor/holofloor{tag = "icon-asteroid3 (EAST)"; icon_state = "asteroid3"; dir = 4},/area/holodeck/source_desert) "bY" = (/turf/simulated/floor/holofloor{tag = "icon-carpet1-0 (EAST)"; icon_state = "carpet1-0"; dir = 4},/area/holodeck/source_theatre) "bZ" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet5-1 (EAST)"; icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_theatre) @@ -116,9 +116,9 @@ "cl" = (/turf/unsimulated/wall{tag = "icon-iron11"; icon_state = "iron11"},/area/space) "cm" = (/obj/structure/sign/double/map/right{pixel_y = -32},/obj/structure/rack/skeletal_bar/right,/obj/item/weapon/reagent_containers/food/drinks/bottle/gin,/turf/unsimulated/floor{dir = 2; icon_state = "wood"},/area/syndicate_mothership) "cn" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) -"co" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) -"cp" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"cq" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"co" = (/obj/machinery/door/airlock/centcom{name = "Shuttle Dock #2"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"cp" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) +"cq" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) "cr" = (/turf/simulated/floor/holofloor{tag = "icon-1 (NORTHEAST)"; icon_state = "1"; dir = 5},/area/holodeck/source_space) "cs" = (/turf/simulated/floor/holofloor{tag = "icon-17 (NORTHEAST)"; icon_state = "17"; dir = 5},/area/holodeck/source_space) "ct" = (/turf/simulated/floor/holofloor{tag = "icon-22 (NORTHEAST)"; icon_state = "22"; dir = 5},/area/holodeck/source_space) @@ -332,7 +332,7 @@ "gt" = (/obj/structure/urinal{pixel_y = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "gu" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/centcom/suppy) "gv" = (/obj/structure/closet/crate,/turf/unsimulated/floor{tag = "icon-plating"; icon_state = "plating"},/area/centcom/suppy) -"gw" = (/obj/item/weapon/mop,/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) +"gw" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (EAST)"; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) "gx" = (/obj/structure/mirror{pixel_x = 28},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "gy" = (/obj/structure/toilet{dir = 8},/obj/structure/window/reinforced/tinted{dir = 1},/obj/machinery/door/window{dir = 8; name = "Tactical Toilet"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "gz" = (/turf/unsimulated/wall/fakeglass,/area/centcom/suppy) @@ -372,10 +372,10 @@ "hh" = (/obj/structure/stool/bed/chair/office/dark,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/evac) "hi" = (/obj/effect/decal/warning_stripes/southeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "hj" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/assault_pod) -"hk" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"hk" = (/obj/item/weapon/storage/fancy/crayons,/obj/machinery/light{dir = 1; on = 1},/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "hl" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/turf/simulated/floor/plating,/area/shuttle/assault_pod) "hm" = (/obj/effect/decal/warning_stripes/southwest,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) -"hn" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"hn" = (/obj/item/device/radio/intercom/syndicate{pixel_x = 0; pixel_y = 25},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ho" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "hp" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "hq" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) @@ -396,7 +396,7 @@ "hF" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/small{tag = "icon-bulb1 (WEST)"; icon_state = "bulb1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) "hG" = (/obj/machinery/computer/shuttle/syndicate/drop_pod,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/assault_pod) "hH" = (/obj/structure/stool/bed/chair,/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) -"hI" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod) +"hI" = (/obj/item/weapon/mop,/obj/structure/mirror{pixel_x = 28},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "hJ" = (/obj/machinery/vending/clothing,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/ferry) "hK" = (/turf/unsimulated/floor/grass,/area/centcom/control) "hL" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) @@ -407,7 +407,7 @@ "hQ" = (/obj/structure/rack,/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/evac) "hR" = (/obj/structure/rack,/obj/item/weapon/storage/fancy/crayons,/obj/item/toy/sword,/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/evac) "hS" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/centcom/evac) -"hT" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"hT" = (/obj/structure/flora/tree/pine{pixel_x = 1},/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow,/area/syndicate_mothership) "hU" = (/obj/effect/decal/warning_stripes/northeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "hV" = (/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "hW" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/obj/docking_port/mobile/assault_pod,/turf/simulated/floor/plating,/area/shuttle/assault_pod) @@ -515,16 +515,29 @@ "jU" = (/obj/machinery/door/poddoor/preopen{id_tag = "CentComPort"; name = "security door"},/turf/unsimulated/floor{tag = "icon-loadingarea (WEST)"; icon_state = "loadingarea"; dir = 8},/area/centcom/control) "jV" = (/turf/unsimulated/floor{dir = 8; heat_capacity = 1; icon_state = "warning"},/area/centcom/evac) "jW" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/unsimulated/wall,/area/centcom/evac) +"jX" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"jY" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"jZ" = (/obj/structure/stool,/obj/effect/landmark{name = "Syndicate-Spawn"},/obj/effect/decal/warning_stripes/east,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"ka" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kb" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"kc" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"kd" = (/obj/machinery/door_control{id = "nukeop_ready"; name = "Mission Launch Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "151"},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ke" = (/turf/unsimulated/floor{tag = "icon-darkgreencorners"; icon_state = "darkgreencorners"},/area/centcom/ferry) "kf" = (/turf/unsimulated/floor{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/centcom/evac) "kg" = (/turf/unsimulated/floor{tag = "icon-yellowsiding"; icon_state = "yellowsiding"},/area/centcom/evac) "kh" = (/turf/unsimulated/floor{tag = "icon-yellowcornersiding (WEST)"; icon_state = "yellowcornersiding"; dir = 8},/area/centcom/evac) +"ki" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod) "kj" = (/turf/unsimulated/wall/fakeglass,/area/centcom/ferry) +"kk" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) "kl" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) "km" = (/turf/unsimulated/floor{tag = "icon-redcorner (WEST)"; icon_state = "redcorner"; dir = 8},/area/centcom/evac) "kn" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/turf/unsimulated/floor{tag = "icon-red (NORTH)"; icon_state = "red"; dir = 1},/area/centcom/evac) "ko" = (/obj/structure/table/reinforced,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-red (NORTH)"; icon_state = "red"; dir = 1},/area/centcom/evac) "kp" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{tag = "icon-red (NORTHEAST)"; icon_state = "red"; dir = 5},/area/centcom/evac) +"kq" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) +"kr" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"ks" = (/obj/structure/stool,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) +"kt" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) "ku" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/centcom/ferry) "kv" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/centcom/ferry) "kw" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/centcom/ferry) @@ -532,6 +545,7 @@ "ky" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "red"},/area/centcom/evac) "kz" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "kA" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{tag = "icon-red (EAST)"; icon_state = "red"; dir = 4},/area/centcom/evac) +"kB" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "kF" = (/obj/structure/dresser,/obj/structure/mirror{pixel_x = 0; pixel_y = 30},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) "kG" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 5},/obj/item/weapon/pen/blue,/turf/unsimulated/floor{dir = 8; icon_state = "vault"},/area/centcom/ferry) "kH" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) @@ -561,7 +575,6 @@ "lD" = (/turf/unsimulated/wall/fakeglass,/area/centcom/evac) "lP" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "lQ" = (/obj/machinery/washing_machine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"lR" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/obj/machinery/light{dir = 1; on = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "lS" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) "lW" = (/turf/unsimulated/floor{tag = "icon-darkred (EAST)"; icon_state = "darkred"; dir = 4},/area/centcom/ferry) "lX" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome/tdomeobserve) @@ -583,7 +596,6 @@ "mL" = (/turf/unsimulated/wall{tag = "icon-uranium5"; icon_state = "uranium5"},/area/wizard_station) "mM" = (/turf/unsimulated/wall{tag = "icon-uranium10"; icon_state = "uranium10"},/area/wizard_station) "mR" = (/obj/structure/noticeboard{pixel_x = -32},/obj/item/weapon/paper/syndimemo,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"mS" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "mT" = (/mob/living/simple_animal/pet/fox/Syndifox,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "mU" = (/obj/effect/decal/warning_stripes/southeastcorner,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "mV" = (/obj/effect/decal/warning_stripes/south,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) @@ -598,7 +610,6 @@ "np" = (/turf/unsimulated/wall{tag = "icon-uranium3"; icon_state = "uranium3"},/area/wizard_station) "nu" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "nv" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"nx" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark{name = "Syndicate-Spawn"},/obj/effect/decal/warning_stripes/east,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ny" = (/obj/machinery/computer/telecrystals/uplinker,/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership) "nB" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = -5},/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey{pixel_x = 5},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/ferry) "nC" = (/turf/unsimulated/floor{tag = "icon-darkblue"; icon_state = "darkblue"; dir = 2},/area/centcom/ferry) @@ -631,7 +642,6 @@ "oz" = (/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cultdamage"; icon_state = "cultdamage"},/area/wizard_station) "oA" = (/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "oD" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership) -"oF" = (/obj/machinery/door_control{id = "nukeop_ready"; name = "Mission Launch Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "151"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "oK" = (/turf/simulated/shuttle/wall{icon_state = "swall0"; dir = 2},/area/wizard_station) "oL" = (/turf/unsimulated/wall/fakedoor{name = "Squad 4 Pod"},/area/wizard_station) "oM" = (/turf/simulated/shuttle/wall{icon_state = "swall4"; dir = 2},/area/wizard_station) @@ -693,7 +703,6 @@ "qC" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/wizard,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "qD" = (/obj/effect/decal/cleanable/blood/splatter,/turf/unsimulated/floor{tag = "icon-cult"; icon_state = "cult"},/area/wizard_station) "qO" = (/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/syndicate_mothership) -"qP" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "qQ" = (/obj/structure/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/saber/red,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "qR" = (/obj/machinery/door/poddoor{id_tag = "thunderdomegen"; name = "General Supply"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena) "qS" = (/obj/effect/landmark{name = "tdome2"},/turf/unsimulated/floor{name = "plating"},/area/tdome/tdome2) @@ -967,56 +976,56 @@ abababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfVabababababababgzgigjgjgjgjgAgvgvgvfVabgkgkgkgkgkgkgkgkgkabababababababababjqjrjrjrjrjrjrjrjsabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfVabababababababfVgFgGgHgjgIfVgvgvgvfVabgkgogkgogkgogkgogkabababababababababjCjEjDjFjFjFjFjGjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfVabababababababfVfVfVfVfVgMfVfVfVfVfVabgkgkgkgkgkgkgkgkgkabgNgNgNgNgNgNababjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababfVfVfVfVfVfVfVgOgPgPgPgQgRgQgPgPgPgOabgkgogkgogkgogkgogkabgNgSgTgTgUgNgOgOjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgVgVgVgVgVgOgPgWgPgXgYgXgPgWgPgOabgkgkgkgkgkgkgkgkgkabgZhahahahajHgYjJjIjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgVhbhchdhegVgPgPgPhfgYhfgPgPgPgOabababababababababababgNhahghhhagNgOgOjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgVhphqhchcgVhrgOhrgOgYgOhrgOhrgOabababgNgNgNgNgNgNgNgNgNhshthuhvgNababjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgVhchchchJgVhKgQhLgYgYgYhMhrhKgOabababgNhNhOhOhOhPhQhRhShahahahagNababjCjEjEjEjKjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgVgVgVgVgVgVgVgVgVgVgVgVgVgVgVgVhXgVgVhKgXhYgYgYgYhZgOhrgOgOgOgOgNiaibibibibibibichahahahagNababjLjrjrjrjrjrjrjrjMabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgViiiiiiiiiiiiiiiiiiiiiiiiiiijikilimgVhKgXhYgYgYgYgYgYinioipipiqgNiaibibibibibibirisitiuivgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgViiiDabababababababababiDiiiEikizimgVhKgXhYgYgYgYhMgOhrgOgOipiGgNiaibibibibibiHiIiJibibiKgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababgViDabababababababababababiZjadlizimgVhKhfhYgYgYgYjbhrhKgOjcjdjegNjfibibibibjgjhjiiJibibiKgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamamamamamatamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgVabababababababababababeojtjuikizjvgVjwgVjxgYgYgYhZgOhrgOhrjyhrgNjzibibibibjAjAjAjBibibiKgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamatamamamamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgViDabababababababababababiZjPikiziljQjRjRgYgYgYgYgYgYinjSipjTipjUjVibibibibibibibibibibiKjWababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamamamauamamamamamamamamamamamamavamamatamawamamiSababababababababababababababababababababababababababgViiiDabababababababababiDiiiEikizkegVjwgVhLgYgYgYhMgOhrgOgOgOgOgNkfibibibibkgkgkgkhibibiKgNgNgNgNgNgNgNgNgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamamamamamamamamamamamamamawamawamamamamawamamamiSababababababababababababababababababababababababababgViiiiiiiiiiiiiiiiiiiiiiiiiikjikilimgVhKgQhYgYgYgYklgQhKgOabababgNkmibibibibknkokpiJibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamamamamamamamamamamamatamamauamamatawamauamamamiSababababababababababababababababababababababababababgVgVgVgVgVgVgVkukvkvkwgVgVgVgVgVkxgVgVhKgXhYgYgYgYklgXhKgOabababgNkyibibibibibkzkAiJibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamaxaxaxaxaxaxaxamamamamayamamatamayamamamatamamamiSabababababababababababababababababababababababababababababgVilkFilililililililkGkHilililgVhKhfhYgYgYgYklhfhKgOabababgNkyibibibibibibibibibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamazabababababababazatamamamamamaAaxaxaBaxaBamamawamiSabababababababababababababababababababababababababababababgVililililiAiliAililililililkUgVkVkVkWkXkYkZlakVkVkVabababgNkyibibibibibibibiLfZiLiMiLisisisiLfZiLfZiLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamabababababababababaCamamamataDiSiSlmlniSiSaEaxaxaxiSabababababababababababababababababababababababababababababgVloilillplplplpiBililililillrgVlsltlulvlwlxlultltkVabababgNlylzlzlzlAlBlClAicibiciKicabababicibicibicababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamabababababababababaCamamamaWiSiSlPlQlQlRiSiSiSiSiSiSiSiSabababababababababababababababababababababababababababgVlSiliClpjNjOlpilililililillWgVltlXlYlvlwlxlYlZltkVabababgNgNgNgNgNgNgNgNgNlDiNlDiNlDababablDfZlDfZlDababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamfmgmhmiaaaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamabababababababababaCamamauaWiSaXmnmnmnmnaYmompiSgtiwgwiSabababababababababababababababababababababababababababgVmuilillplplplpiBilililililmvgVmwltmwlvlwlxmwltmwkVabababababababababababababababababababababiOabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHaamIgamKmLmMaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamazabababababababazamamamambIiSmRmnmSmSmTmnmUmVpcpdpdgxiSiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababgVmYililiFiliFilililililililnagVnbltltlvlwlxltltnckVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHnlnmnnmKnonpaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamabababababbKaxaxamambLaDiSnumSnvixmSmnnxnyiSpdgyiSiSgBgDgCgEgEgJgEgEgKgLiSababababababababababababababababgVnBilililililililnCnDnEnFnanGgVnHnInIlvlwlxnJnJnKkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaanpnXnYnonZoanpaaaaaaaaaaaaaaaaaaaaababababababiSamamamamamamamabababababodoeoeoeoeoelniSmnmSofogmSmnnxnyiSiSiSiSiSgDgChihkhjhlhjhnhmgKiSababababababababababababababababgVgVgVgVgVohgVgVgVgVgVgVgVgVgVgVkVkVkVkVlwkVkVkVkVkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamLmMolomolonooaaaaaaaaaaaaaaaaaaaaababababababiSamamazabababababababababopoqoroqoqoqoqotmnbMmnmnmnmnnxnyiSiSiSiSiSgDhohkhjhwhyhxhjhnhziSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHmHoooyozoAmLaaaaaaaaaaaaaaaaaaaaaaababababababiSamamababababababababababoDbNlmoeoeoelniSoFmSmSmSmnmnnxnylmoeoeoeoeoeoehjhwhyhAhyhxhjhziSabababababababababababababababababababababababababababababababababababkVkYkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaoKoLoMoNoOoPmKoQmHaaaaaaaaaaaaaaaaaaaaababababababiSamamabababababababababababbOabazamambPiSoXoYoZoYiymnpapbhChBhBhDhBhBhChlhyhEhGhFhyhlhziSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaphpipjpkploOmKnYpmpnmHmHaaaaaaaaaaaaaaaaababababababiSbUamababababababababababababababbWamaWiScfpvpwpxpymnmnmnlmoeoeoeoeoeoehjhwhyhHhyhyhjhziSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaamHaaoMpDpDpEoOmKpFnYpnaapGpHaaaaaaaaaaaaaaababababababiSamamababababababababababababababaCamaWiSiSnypPcgcmiSpSmniSiSiSiSiSgDhohIhjhwhyhxhjhThziSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaoQmHaaaamHpTpUnnpVnnoQmHmHaaaaaaaaaaaaaaaaababababababiSamamababababababababababababababaEamamamiSiSiSiSiSiSqcqcqdqeqfqgiSgDhVhUhIhjhWhjhTidieiSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaonqiqjqkqlqmqlqlqiqnqkqlqlqmqlqlaamHaaaaaaaaaaababababababiSamazabababababababababababababababazamamamcncncobPiSqrqsqsqsqsqsiSifgDhVigigihigigieifiSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaqwqxmKmKqxqwqyqzmKmKmKqAqBqwqCozoQqDmHmHaaaaaaababababababiSamabababababababababababababababababaCamamatamamaWqOqsqsqsqsqsqPiSiSiSiSiSiSiSiSiSiSiSiSabababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaqYqZmKmKqZqYqDqDmKmKmKmKraqYrbrcpDpDrdaaaaaaaaababababababiSamabababababababababababababababababaCamamaucpaBaDiSrjrjrjrjrjrkiSababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaarnromKnYmKrppFnYmKgbmKmKrrrnrsrtrurvrwrxaaaaaaababababababiSamabababababababababababababababababaCamamaWiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaarGqZmKnnpFrHnnmKmKrImKmKmKrGrJrKrdrLoKaaaaaaaaababababababiSamabababababababababababababababababcqamamamiSababababababababababababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaamirWmKmKrWmirXmKnYnnmKmKrXmirYrZsasbaaaaaaaaaaababababababiSamabababababababababababababababababaCamamamiSababababababababababababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaamLqisfqkqlsgqlqiolsholqkqlsgqlqimHmHmHaaaaaaaaababababababiSamabababababamabababababamabababababaCamamamiSababababababababababababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaapTnYaamHaamHsooPpTaaaamHaaaaaaaamHaaaaaaaaababababababiSamabababababamazabababazamabababababaCamamamiSababababababababababababababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaamHmHaastnYaasusvpTmHaapFaaaaaaaaaaaaaaaaaaababababababiSamazabababazamamamamamamamazabababazamamamamiSabababababababababababababababababababababababababababababababababababababababababababababababababsJsJsJsJsJsJsJsJiPsJsJsJsJsJsJsJsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHmHaasBnYsCaaaaaamHaaaaaaaaaaaaaaaaababababababiSamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababababababababababababababababababababababababababababsJiQiRiRiRiRiRiQiQiQiRiRiRiRiRiQsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHqmqisIqkqmmHaamHmHaaaaaaaaaaaaaaababababababiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSabababababababababababababababababababababababababababababababababababababababababababababababababiTiQiQiQiUiQiQiQiQiQiQiQiUiQiQiQiTababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaqwsMsNsOqwstrcplsPsQmHaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababsJiQiRiRiRiRiRiQiQiQiRiRiRiRiRiQsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaolsVsWsXolnYsYpksZmKnpaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababsJsxsysysysysysysysysysysysysyszsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaoPmHmitatbtcminntdpksZaamHaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqtqtqtqtqtqtqtqtquqvqvqvqvqvqvqvqvqvqvqvqvqvquqtqtqtqtqtqtqtqtqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHqmteqiolqkteqmtftgsZaamHaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHqwmKtitjtimKqwaatkaaaamHaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSrlqSrlqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWrmqWrmqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaamHnYtxmKmKmKmKmKtxaaaaaaaanYaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSrCqSqSqTqUqvqvqvqvqvrDrErDqvqvqvqvqvqVqTqWqWrFqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaamHmHoPmKmitBmKmKmKtBmiaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvrDrVrDqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaamHqlqltHtItItItItItJaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSrlqSrlqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWrmqWrmqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamLqitMtMtMqkooaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatPtPtPaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqtqtssssssssssqtquqvqvqvqvqvqvqvqvqvqvqvqvqvquqtssssssssssqtqtqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtswswswswswkVkZqhqhqhqhqhqhqhqhqhqhqhqhqhkXkVsAsAsAsAsAqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababababababababababfVfVfVfVfVfVfVgOgPgPgPgQgRgQgPgPgPgOabgkgogkgogkgogkgogkabgNgSgTgTgUgNgOgOjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamamamamamamamamamamamamamamamamamatamamamamamamamamamamamamamamiSababababababababababababababababababababababababababababababababababababgVgVgVgVgVgOgPgWgPgXgYgXgPgWgPgOabgkgkgkgkgkgkgkgkgkabgZhahahahajHgYjJjIjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamamamamamamatamamamamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababababababababababababgVhbhchdhegVgPgPgPhfgYhfgPgPgPgOabababababababababababgNhahghhhagNgOgOjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamamamatavamamamavamamamamatamavamamamamamamamatamamavamamamatamiSababababababababababababababababababababababababababababababababababababgVhphqhchcgVhrgOhrgOgYgOhrgOhrgOabababgNgNgNgNgNgNgNgNgNhshthuhvgNababjCjEjEjEjEjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamavamatamamavamamamavamamamamamatamamavamamamamamamamatavamamamiSababababababababababababababababababababababababababababababababababababgVhchchchJgVhKgQhLgYgYgYhMhrhKgOabababgNhNhOhOhOhPhQhRhShahahahagNababjCjEjEjEjKjEjEjEjCabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgVgVgVgVgVgVgVgVgVgVgVgVgVgVgVgVhXgVgVhKgXhYgYgYgYhZgOhrgOgOgOgOgNiaibibibibibibichahahahagNababjLjrjrjrjrjrjrjrjMabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +abababababababababababababababababababababababababababababababababababababababababababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViiiiiiiiiiiiiiiiiiiiiiiiiiijikilimgVhKgXhYgYgYgYgYgYinioipipiqgNiaibibibibibibirisitiuivgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViiiDabababababababababiDiiiEikizimgVhKgXhYgYgYgYhMgOhrgOgOipiGgNiaibibibibibiHiIiJibibiKgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViDabababababababababababiZjadlizimgVhKhfhYgYgYgYjbhrhKgOjcjdjegNjfibibibibjgjhjiiJibibiKgNfYfYababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgVabababababababababababeojtjuikizjvgVjwgVjxgYgYgYhZgOhrgOhrjyhrgNjzibibibibjAjAjAjBibibiKgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViDabababababababababababiZjPikiziljQjRjRgYgYgYgYgYgYinjSipjTipjUjVibibibibibibibibibibiKjWababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViiiDabababababababababiDiiiEikizkegVjwgVhLgYgYgYhMgOhrgOgOgOgOgNkfibibibibkgkgkgkhibibiKgNgNgNgNgNgNgNgNgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgViiiiiiiiiiiiiiiiiiiiiiiiiikjikilimgVhKgQhYgYgYgYklgQhKgOabababgNkmibibibibknkokpiJibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSabababababababababababababababababababababababgVgVgVgVgVgVgVkukvkvkwgVgVgVgVgVkxgVgVhKgXhYgYgYgYklgXhKgOabababgNkyibibibibibkzkAiJibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgVilkFilililililililkGkHilililgVhKhfhYgYgYgYklhfhKgOabababgNkyibibibibibibibibibibibibibibibibibibibgNababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgVililililiAiliAililililililkUgVkVkVkWkXkYkZlakVkVkVabababgNkyibibibibibibibiLfZiLiMiLisisisiLfZiLfZiLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgVloilillplplplpiBililililillrgVlsltlulvlwlxlultltkVabababgNlylzlzlzlAlBlClAicibiciKicabababicibicibicababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamawamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababgVlSiliClpjNjOlpilililililillWgVltlXlYlvlwlxlYlZltkVabababgNgNgNgNgNgNgNgNgNlDiNlDiNlDababablDfZlDfZlDababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamfmgmhmiaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamiSayiSayiSaCamaWiSayiSayiSaCamamamamamamamatamiSababababababababababababababababababababababababababgVmuilillplplplpiBilililililmvgVmwltmwlvlwlxmwltmwkVabababababababababababababababababababababiOabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHaamIgamKmLmMaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamaAmnaAmnaAaCamaWaAmnaAmnaAaCamamatamamamamamamiSababababababababababababababababababababababababababgVmYililiFiliFilililililililnagVnbltltlvlwlxltltnckVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHnlnmnnmKnonpaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamavamaBmnaBmnaBaEaxaDaBmnaBmnaBaEavaxaxamamavamamamiSababababababababababababababababababababababababababgVnBilililililililnCnDnEnFnanGgVnHnInIlvlwlxnJnJnKkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaanpnXnYnonZoanpaaaaaaaaaaaaaaaaaaaaabababababababiSamavamamatavamamaWiSayiSayiSaYoelniSayiSayiSiSiSiSiSbIamamatamamiSababababababababababababababababababababababababababgVgVgVgVgVohgVgVgVgVgVgVgVgVgVgVkVkVkVkVlwkVkVkVkVkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamLmMolomolonooaaaaaaaaaaaaaaaaaaaaabababababababiSamamavamamamamataWiSbKmnmnmnbKmnmnmnbKmnmnmnbKmnmniSaCamamamavamiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHmHoooyozoAmLaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamavamamamaWiSmnmnmnmnmnmnmnmnmnmnmnmnmnmnmniSaCatamamamamiSabababababababababababababababababababababababababababababababababababababababababababababkVkYkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaoKoLoMoNoOoPmKoQmHaaaaaaaaaaaaaaaaaaaaabababababababiSavamamamamavamavaWiSaYoeoeoeoeoeoeoeoeoeoeoelniSbLiSaCamavamatamiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaphpipjpkploOmKnYpmpnmHmHaaaaaaaaaaaaaaaaabababababababiSamamavatamamaxaxaxbWbWbWbWcncncncncncncncncnbPiSmniSbIamatamamamiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaamHaaoMpDpDpEoOmKpFnYpnaapGpHaaaaaaaaaaaaaaabababababababiSamamamamamazabababababababazatamamavamamaxaxaDiSmniSaCamamamamamiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaoQmHaaaamHpTpUnnpVnnoQmHmHaaaaaaaaaaaaaaaaabababababababiSatavamamamabababababababababbIamamamataDiSiSqOiScoiScpaxcqaxcqaxiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaonqiqjqkqlqmqlqlqiqnqkqlqlqmqlqlaamHaaaaaaaaaaabababababababiSamamamamamabababababababababaCamamamaWiSiSlPlQhkmniSiSiSiSiSiSiSiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaqwqxmKmKqxqwqyqzmKmKmKqAqBqwqCozoQqDmHmHaaaaaaabababababababiSamamamamamabababababababababaCavamauaWiSaXmnmnmnmnhnmompiSgtiwhIiSabababababababababababababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaqYqZmKmKqZqYqDqDmKmKmKmKraqYrbrcpDpDrdaaaaaaaaabababababababiSamhTamamamazabababababababazamamamamgwiSmRmnjYjYmTmnmUmVpcpdpdgxiSiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaarnromKnYmKrppFnYmKgbmKmKrrrnrsrtrurvrwrxaaaaaaabababababababiSamamamamamamamabababababcpaxaxaxaxcqaDiSnujYnvixjYmnjZnyiSpdgyiSiSgBgDgCgEgEgJgEgEgKgLiSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaarGqZmKnnpFrHnnmKmKrImKmKmKrGrJrKrdrLoKaaaaaaaaabababababababiSamamamavamamamabababababodoeoeoeoeoelniSkajYofogjYmnjZnyiSiSiSiSiSgDgChijXhjhlhjkbhmgKiSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaamirWmKmKrWmirXmKnYnnmKmKrXmirYrZsasbaaaaaaaaaaabababababababiSatamazabababababababababopoqoroqoqoqoqotmnbMmnmnmnmnjZnyiSiSiSiSiSgDhojXhjhwhyhxhjkbhziSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaamLqisfqkqlsgqlqiolsholqkqlsgqlqimHmHmHaaaaaaaaabababababababiSamamababababababababababoDbNlmoeoeoelniSkdjYjYjYkamnjZnylmoeoeoeoeoeoehjhwhyhAhyhxhjhziSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaapTnYaamHaamHsooPpTaaaamHaaaaaaaamHaaaaaaaaabababababababiSamamabababababababababababbOabazamambPiSoXoYoZoYiymnpapbhChBhBhDhBhBhChlhyhEhGhFhyhlhziSababababababababababababababababababababababababababababababababababkVlwkVabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaamHmHaastnYaasusvpTmHaapFaaaaaaaaaaaaaaaaaaabababababababiSbUamababababababababababababababkcamaWiScfpvpwpxpymnmnmnlmoeoeoeoeoeoehjhwhyhHhyhyhjhziSabababababababababababababababababababababababababababsJsJsJsJsJsJsJsJiPsJsJsJsJsJsJsJsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHmHaasBnYsCaaaaaamHaaaaaaaaaaaaaaaaabababababababiSavamababababababababababababababaCamaWiSiSnypPcgcmiSpSmniSiSiSiSiSgDhokihjhwhyhxhjkkhziSabababababababababababababababababababababababababababsJiQiRiRiRiRiRiQiQiQiRiRiRiRiRiQsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamHqmqisIqkqmmHaamHmHaaaaaaaaaaaaaaabababababababiSamamababababababababababababababaEamamamiSiSiSiSiSiSqcqcqdqeqfqgiSgDhVhUkihjhWhjkkidieiSabababababababababababababababababababababababababababiTiQiQiQiUiQiQiQiQiQiQiQiUiQiQiQiTababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaqwsMsNsOqwstrcplsPsQmHaaaaaaaaaaabababababababiSamazabababababababababababababababazamamamcncnkqbPiSqrqsqsqsqsqsiSifgDhVigigihigigieifiSabababababababababababababababababababababababababababsJiQiRiRiRiRiRiQiQiQiRiRiRiRiRiQsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaolsVsWsXolnYsYpksZmKnpaaaaaaaaaaabababababababiSamabababababababababababababababababaCamamatamamaWqOqsqsqsqsqsksiSiSiSiSiSiSiSiSiSiSiSiSabababababababababababababababababababababababababababsJsxsysysysysysysysysysysysysyszsJababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaoPmHmitatbtcminntdpksZaamHaaaaaaaaaaabababababababiSamabababababababababababababababababaCamamaukrktaDiSrjrjrjrjrjrkiSababababababababababababababababababababababababababababababqtqtqtqtqtqtqtqtqtquqvqvqvqvqvqvqvqvqvqvqvqvqvquqtqtqtqtqtqtqtqtqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHqmteqiolqkteqmtftgsZaamHaaaaaaaaaaabababababababiSamabababababababababababababababababaCamamaWiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaamHqwmKtitjtimKqwaatkaaaamHaaaaaaaaaaabababababababiSamabababababababababababababababababkBavamamiSababababababababababababababababababababababababababababababababababababababababqtqQqRqSrlqSrlqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWrmqWrmqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaamHnYtxmKmKmKmKmKtxaaaaaaaanYaaaaaaaaaaabababababababiSamabababababababababababababababababaCamamamiSababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSrCqSqSqTqUqvqvqvqvqvrDrErDqvqvqvqvqvqVqTqWqWrFqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaamHmHoPmKmitBmKmKmKtBmiaaaaaaaaaaaaaaaaaaaaabababababababiSamabababababamabababababamabababababaCamamamiSababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvrDrVrDqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaamHqlqltHtItItItItItJaaaaaaaaaaaaaaaaaaaaabababababababiSamabababababamazabababazamabababababaCamamamiSababababababababababababababababababababababababababababababababababababababababqtqQqRqSrlqSrlqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWrmqWrmqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaamLqitMtMtMqkooaaaaaaaaaaaaaaaaaaaaabababababababiSamazabababazamamamamamamamazabababazamamavamiSababababababababababababababababababababababababababababababababababababababababqtqQqRqSqSqSqSqSqTqUqvqvqvqvqvqvqvqvqvqvqvqvqvqVqTqWqWqWqWqWqRqXqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatPtPtPaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSamamamamamamamamamamamamamamamamamamamamamamiSababababababababababababababababababababababababababababababababababababababababqtqtqtssssssssssqtquqvqvqvqvqvqvqvqvqvqvqvqvqvquqtssssssssssqtqtqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSiSababababababababababababababababababababababababababababababababababababababababababqtswswswswswkVkZqhqhqhqhqhqhqhqhqhqhqhqhqhkXkVsAsAsAsAsAqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababqtqtqtqtqtqtkViViWiWiWiWiWiXjjiYiWiWiWiWiWiVkVqtqtqtqtqtqtababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababkViViViVjkiVltltltltltiVjkiViViVkVababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababkVkVjlkVkVkVkVjmjojnkVkVkVkVjlkVkVababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab diff --git a/_maps/map_files/MetaStation/z5.dmm b/_maps/map_files/MetaStation/z5.dmm index 186dfe33844..6e619cc2478 100644 --- a/_maps/map_files/MetaStation/z5.dmm +++ b/_maps/map_files/MetaStation/z5.dmm @@ -10,8 +10,8 @@ "aj" = (/obj/machinery/light/small,/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/unexplored) "ak" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/unexplored) "al" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/mineral,/area/mine/dangerous/unexplored) -"am" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/space,/area/research_outpost/hallway) -"an" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"am" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/space,/area/research_outpost/hallway) +"an" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "ao" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/space,/area/space) "ap" = (/obj/structure/transit_tube{icon_state = "D-NW"},/obj/structure/lattice,/turf/space,/area/space) "aq" = (/turf/simulated/wall/r_wall,/area/research_outpost/spectro) @@ -21,10 +21,10 @@ "au" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "av" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/mineral,/area/mine/dangerous/unexplored) "aw" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/unexplored) -"ax" = (/obj/structure/transit_tube,/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/hallway) +"ax" = (/obj/structure/transit_tube,/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/hallway) "ay" = (/obj/structure/transit_tube/station,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) "az" = (/obj/structure/transit_tube,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"aA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"aA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "aB" = (/obj/structure/transit_tube,/obj/structure/lattice,/turf/space,/area/space) "aC" = (/obj/structure/transit_tube{icon_state = "W-SE"},/obj/structure/lattice,/turf/space,/area/space) "aD" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) @@ -35,7 +35,7 @@ "aI" = (/obj/structure/table,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter{pixel_x = 2; pixel_y = 2},/obj/item/device/assembly/igniter{pixel_x = -3; pixel_y = 3},/obj/item/device/assembly/igniter{pixel_x = -4; pixel_y = -4},/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "aJ" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "aK" = (/obj/structure/closet/hydrant{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aL" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/stock_parts/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) +"aL" = (/obj/structure/table,/obj/item/device/plant_analyzer,/obj/item/weapon/stock_parts/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "aM" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "aN" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "aO" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) @@ -72,17 +72,17 @@ "bt" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "bu" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "Mass Spectrometry APC"; pixel_x = 24; pixel_y = 0; pixel_x = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) "bv" = (/obj/structure/table,/obj/item/stack/sheet/mineral/plasma,/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) -"bw" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weedkiller/triclopyr,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) +"bw" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "bx" = (/obj/machinery/light/small,/obj/structure/closet/walllocker/emerglocker/north{dir = 1; pixel_y = -32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "by" = (/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"bz" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_access_txt = "0"; req_one_access_txt = "65;12"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/maintstore1) +"bz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_access_txt = "0"; req_one_access_txt = "65;12"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/maintstore1) "bA" = (/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "bB" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "bC" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/camera{c_tag = "Research Outpost Auxiliary Storage"; dir = 8; network = list("Research Outpost")},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "bD" = (/obj/structure/table,/turf/simulated/floor/carpet,/area/research_outpost/hallway) "bE" = (/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bF" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rminingdorm1"; name = "Dorm 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) -"bG" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) +"bF" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rminingdorm1"; name = "Dorm 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) +"bG" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) "bH" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/lattice,/turf/space,/area/space) "bI" = (/turf/simulated/mineral/random,/area/mine/dangerous/unexplored) "bJ" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SE"},/turf/space,/area/space) @@ -99,21 +99,21 @@ "bU" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel,/area/research_outpost/hallway) "bV" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitecorner"},/area/research_outpost/hallway) "bW" = (/turf/simulated/wall/r_wall,/area/research_outpost/atmos) -"bX" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"bY" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) +"bX" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/atmos) +"bY" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/atmos) "bZ" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "S-NE"},/turf/space,/area/space) "ca" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"},/area/research_outpost/spectro) "cb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; layer = 2.4; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"},/area/research_outpost/spectro) "cc" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitegreen"},/area/research_outpost/spectro) -"cd" = (/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) +"cd" = (/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "ce" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cf" = (/obj/structure/sign/nosmoking_2{pixel_y = 32},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cg" = (/obj/structure/table,/obj/machinery/light{dir = 1},/obj/machinery/reagentgrinder,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "ch" = (/obj/structure/table,/obj/item/weapon/storage/box/solution_trays,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/sample) "ci" = (/obj/machinery/door/window/westleft{dir = 1; name = "Sample Preparation Loading"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteblue"},/area/research_outpost/sample) "cj" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/computer/reconstitutor,/turf/simulated/floor/plasteel{dir = 1; icon_state = "bluecorner"},/area/research_outpost/sample) -"ck" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) -"cl" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) +"ck" = (/obj/machinery/hydroponics/soil,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) +"cl" = (/obj/machinery/hydroponics/soil,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) "cm" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) "cn" = (/obj/structure/sink{pixel_y = 30},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "co" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) @@ -126,7 +126,7 @@ "cv" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister,/obj/machinery/camera{c_tag = "Research Outpost Atmospherics"; dir = 2; network = list("Research Outpost")},/turf/simulated/floor/plating,/area/research_outpost/atmos) "cw" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel,/area/research_outpost/atmos) "cx" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/atmos) -"cy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) +"cy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "cz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/research_outpost/spectro) "cA" = (/obj/machinery/power/apc{dir = 4; name = "Chem Storage APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "cB" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/chem_master,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) @@ -134,12 +134,12 @@ "cD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cE" = (/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/sample) "cF" = (/obj/structure/disposaloutlet{dir = 8},/obj/structure/disposalpipe/trunk{dir = 2},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"cG" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) +"cG" = (/obj/machinery/hydroponics/soil,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) "cH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) "cI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area/research_outpost/hallway) "cJ" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "cK" = (/obj/machinery/door_control{id = "rbath"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) +"cL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "cM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "cN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "cO" = (/obj/machinery/light/small{dir = 8},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 5; level = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -158,7 +158,7 @@ "db" = (/obj/machinery/light/small{dir = 4},/obj/machinery/power/apc{dir = 4; name = "Sample Preparation APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "dc" = (/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) "dd" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) -"de" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/anomaly) +"de" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/anomaly) "df" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dh" = (/obj/machinery/atmospherics/unary/heat_reservoir/heater{dir = 4},/obj/structure/sign/nosmoking_1{pixel_x = -32},/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -166,7 +166,7 @@ "dj" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/unary/tank/air{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dk" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/research_outpost/atmos) "dl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"dm" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) +"dm" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "dn" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "do" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; layer = 2.4; on = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "dp" = (/obj/machinery/chem_heater,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) @@ -174,23 +174,23 @@ "dr" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/camera{c_tag = "Research Outpost Sample Preparation"; dir = 1; network = list("Research Outpost")},/obj/item/weapon/reagent_containers/glass/beaker/water,/obj/item/weapon/reagent_containers/glass/beaker/fuel,/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 3; pixel_x = 2; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) "ds" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) "dt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"du" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"du" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "dv" = (/obj/machinery/power/apc{dir = 1; name = "Anomalous Materials APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) "dw" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dy" = (/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dz" = (/obj/machinery/light{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dA" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) -"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 1; layer = 2.6; name = "Firelock North"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"dC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/door/firedoor{dir = 1; layer = 2.6; name = "Firelock North"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) +"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) +"dC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dD" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dE" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) "dF" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; layer = 2.4; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8; initialize_directions = 11; level = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dG" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/unary/tank/air{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"dI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) +"dI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Chem Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "dJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/sample) -"dK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) +"dK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "dL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/research_outpost/sample) "dM" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dN" = (/obj/structure/table,/obj/item/weapon/lighter/random,/obj/item/weapon/crowbar,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) @@ -200,7 +200,7 @@ "dR" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/structure/plasticflaps,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) "dS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"dU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/atmos) +"dU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dV" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dW" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) "dX" = (/obj/machinery/meter,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -214,7 +214,7 @@ "ef" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"ei" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) +"ei" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "ej" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "ek" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/sign/chemistry{desc = "A warning sign which reads 'SAMPLE PREPARATION'"; name = "\improper SAMPLE PREPARATION"; pixel_y = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "el" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) @@ -227,7 +227,7 @@ "es" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "et" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) "eu" = (/turf/simulated/wall/r_wall,/area/research_outpost/power) -"ev" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plasteel,/area/research_outpost/power) +"ev" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plasteel,/area/research_outpost/power) "ew" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/wall/r_wall,/area/research_outpost/power) "ex" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/wall/r_wall,/area/research_outpost/power) "ey" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/mineral,/area/mine/dangerous/unexplored) @@ -242,17 +242,17 @@ "eH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"eK" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock East"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) +"eK" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) "eL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "eM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) -"eN" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"eN" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "eO" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) "eP" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "eQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "eR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "eS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "eT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"eU" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"eU" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "eV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/research_outpost/hallway) "eW" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) "eX" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/power) @@ -279,7 +279,7 @@ "fs" = (/obj/machinery/camera{c_tag = "Research Outpost Anomalous Materials Lab"; dir = 8; network = list("Research Outpost")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "ft" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = -32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "fu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"fv" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) +"fv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) "fw" = (/turf/simulated/floor/plating,/area/research_outpost/power) "fx" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable,/turf/simulated/floor/plating,/area/research_outpost/power) "fy" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) @@ -291,17 +291,17 @@ "fE" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp/granted,/turf/simulated/floor/wood,/area/research_outpost/hallway) "fF" = (/turf/simulated/floor/wood,/area/research_outpost/hallway) "fG" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"fI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"fJ" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) -"fK" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"fH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) +"fI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"fJ" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"fK" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "fL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/camera{c_tag = "Research Outpost Hallway Engineering"; dir = 4; network = list("Research Outpost")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "fM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) "fN" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/power/apc{dir = 8; name = "Outpost Power APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/research_outpost/power) "fO" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/research_outpost/power) "fP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/research_outpost/power) "fQ" = (/obj/machinery/portable_atmospherics/scrubber,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/research_outpost/power) -"fR" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/power) +"fR" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/power) "fS" = (/obj/machinery/mass_driver{dir = 4; id_tag = "Research Outpost"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/unexplored) "fT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/firealarm{dir = 4; pixel_x = -28; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "fU" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/power/apc{dir = 2; name = "Outpost Lobby APC"; pixel_x = 0; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor/wood,/area/research_outpost/hallway) @@ -326,11 +326,11 @@ "gn" = (/obj/machinery/conveyor_switch{id = "archgunc"},/turf/simulated/floor/plating,/area/research_outpost/power) "go" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plating,/area/research_outpost/power) "gp" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/wall,/area/research_outpost/entry) -"gq" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"gq" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "gr" = (/obj/machinery/door/airlock/external{id_tag = "science_away"; name = "Research Outpost Dock Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/research_outpost/entry) "gs" = (/obj/structure/sign/science,/turf/simulated/wall,/area/research_outpost/entry) -"gt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"gu" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"gt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"gu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "gv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/turf/simulated/floor/wood,/area/research_outpost/hallway) "gw" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/turf/simulated/floor/wood,/area/research_outpost/hallway) "gx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) @@ -348,11 +348,11 @@ "gJ" = (/obj/machinery/driver_button{id_tag = "Research Outpost"; pixel_x = 6; pixel_y = -26},/obj/machinery/conveyor{dir = 4; id = "archgunc"},/turf/simulated/floor/plating,/area/research_outpost/power) "gK" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) "gL" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power) -"gM" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"gM" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "gN" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) "gO" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) "gP" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) -"gQ" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"gQ" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "gR" = (/obj/machinery/computer/shuttle/science,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/research_outpost/entry) "gS" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "gT" = (/obj/machinery/light{dir = 4},/obj/machinery/camera{c_tag = "Shuttle Docking Foyer"; dir = 8; network = list("MINE")},/obj/machinery/newscaster{pixel_x = 30; pixel_y = 1},/obj/machinery/computer/shuttle/mining,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/mine/production) @@ -379,34 +379,34 @@ "ho" = (/obj/structure/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/color/latex,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/anomaly) "hp" = (/obj/machinery/door/window/westleft{dir = 2; name = "Monkey Pen"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "hq" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) -"hr" = (/obj/machinery/door/firedoor{layer = 2.6; name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"hs" = (/obj/machinery/door/firedoor{layer = 2.6; name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"ht" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) +"hr" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"hs" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"ht" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) "hu" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) "hv" = (/obj/structure/transit_tube{icon_state = "E-NW"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) "hw" = (/obj/structure/transit_tube/station,/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = 32; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) "hx" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "hy" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "hz" = (/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"hA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/harvesting) +"hA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/harvesting) "hB" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"hC" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"hC" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "hD" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/research_outpost/entry) "hE" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"hF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"hF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "hG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "hH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "hI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"hJ" = (/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_medical{id_tag = ""; name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) +"hJ" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_medical{id_tag = ""; name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "hK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "hL" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "hM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/conveyor_switch{id = "anotempload"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "hN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "hO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"hP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) +"hP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "hQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "hR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"hS" = (/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"hS" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "hT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "hU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "hV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) @@ -419,7 +419,7 @@ "ic" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) "id" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellow"},/area/research_outpost/hallway) "ie" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"if" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"if" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "ig" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/hallway) "ih" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "ii" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Airlock"; dir = 2; network = list("Research Outpost")},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) @@ -429,7 +429,7 @@ "im" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/research_outpost/harvesting) "in" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) "io" = (/obj/machinery/artifact_harvester,/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) -"ip" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "D-NE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"ip" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "D-NE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "iq" = (/obj/structure/transit_tube{icon_state = "S-NW"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/entry) "ir" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "is" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Research Outpost Shuttle Dock"; dir = 8; network = list("Research Outpost")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/research_outpost/entry) @@ -446,7 +446,7 @@ "iD" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/research_outpost/tempstorage) "iE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "iF" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"iG" = (/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) +"iG" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "iH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "iI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "iJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM ONE'"; name = "\improper ISOLATION ROOM ONE"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) @@ -457,14 +457,14 @@ "iO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) "iP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM THREE'"; name = "\improper ISOLATION ROOM THREE"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) "iQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"iR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 8; layer = 2.6; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"iR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/firealarm{pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/biohazard{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "iU" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitepurple"},/area/research_outpost/hallway) -"iV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) +"iV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "iW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/harvesting) "iX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"iY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) +"iY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "iZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) "ja" = (/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) "jb" = (/obj/structure/table,/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) @@ -484,7 +484,7 @@ "jp" = (/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) "jq" = (/obj/machinery/conveyor{dir = 9; id = "anotempload"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/research_outpost/tempstorage) "jr" = (/turf/simulated/wall/r_wall,/area/research_outpost/maint) -"js" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plating,/area/research_outpost/maint) +"js" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/maint) "jt" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso1) "ju" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/iso1) "jv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation room one"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/iso1) @@ -494,10 +494,10 @@ "jz" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso3) "jA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/iso3) "jB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation Room Three"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/iso3) -"jC" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) +"jC" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) "jD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) "jE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage) -"jF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) +"jF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) "jG" = (/obj/machinery/alarm{dir = 1; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "jH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "jI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) @@ -505,13 +505,13 @@ "jK" = (/turf/simulated/wall,/area/mine/dangerous/unexplored) "jL" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) "jM" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall,/area/research_outpost/entry) -"jN" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SW"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"jN" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/transit_tube{icon_state = "N-SW"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "jO" = (/turf/simulated/wall,/area/research_outpost/entry) "jP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/research_outpost/entry) -"jQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access_txt = "65"},/turf/simulated/floor/plating,/area/research_outpost/entry) +"jQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access_txt = "65"},/turf/simulated/floor/plating,/area/research_outpost/entry) "jR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/research_outpost/entry) "jS" = (/turf/simulated/wall,/area/research_outpost/tempstorage) -"jT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) +"jT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "jU" = (/obj/structure/plasticflaps/mining,/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating,/area/research_outpost/maint) "jV" = (/obj/machinery/conveyor{dir = 5; id = "anosample"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/maint) "jW" = (/obj/machinery/conveyor{dir = 4; id = "anosample"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maint) @@ -545,11 +545,11 @@ "ky" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "kz" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "kA" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) -"kB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Loading area"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) +"kB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Loading area"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) "kC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/camera{c_tag = "Research Outpost Loading Area"; dir = 2; network = list("Research Outpost")},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) "kD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/power/apc{dir = 1; name = "Temporary Storage APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) "kE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/research_outpost/tempstorage) -"kF" = (/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) +"kF" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) "kG" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) "kH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) "kI" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) @@ -619,7 +619,7 @@ "lU" = (/obj/structure/closet/excavation,/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "lV" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "lW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) -"lX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/glass_mining{name = "Equipment storage"; req_access_txt = "47"},/obj/machinery/door/firedoor{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) +"lX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/glass_mining{name = "Equipment storage"; req_access_txt = "47"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "lY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "lZ" = (/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "ma" = (/obj/machinery/conveyor_switch{id = "anotempload"},/turf/simulated/floor/plasteel/airless{tag = "icon-asteroidwarning (NORTH)"; icon_state = "asteroidwarning"; dir = 1},/area/mine/dangerous/explored) @@ -700,7 +700,7 @@ "nx" = (/obj/machinery/door/window/westleft,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) "ny" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"; tag = "icon-closed (EAST)"},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/mine/dangerous/explored) "nz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area/space) -"nA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) +"nA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/gearstore) "nB" = (/obj/machinery/door/airlock/external,/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "nC" = (/obj/structure/transit_tube{tag = "icon-D-SE"; icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) "nD" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) @@ -820,7 +820,7 @@ "pN" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/mine/abandoned) "pO" = (/obj/structure/sink{pixel_y = 30},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/abandoned) "pP" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/abandoned) -"pQ" = (/obj/structure/table,/obj/item/weapon/paper/crumpled,/obj/item/seeds/cherryseed,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/abandoned) +"pQ" = (/obj/structure/table,/obj/item/weapon/paper/crumpled,/obj/item/seeds/cherry,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/abandoned) "pR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "pS" = (/obj/structure/alien/resin/membrane,/obj/structure/alien/weeds,/turf/simulated/floor/plating/airless,/area/mine/abandoned) "pT" = (/obj/structure/table,/obj/item/weapon/pickaxe,/turf/simulated/floor/plasteel,/area/mine/north_outpost) @@ -1469,15 +1469,15 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadaaaaaaaaaaaaaaaaaaaabIbIbIadbIaaaabZbMaeaeaeaeaeadaqcacbccaraZaZcdcecfcgchcicjckclcmbjcncobjcpcqcrcsctcucvcwcxbXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadadaaaaaaaaaaaaaaaaaabIbIbIbIbIaaaaaVaaaaaaaaaaaaadaqaqcyczaraZcAarcBcececCcDcEcFcGcHcIcJcKcLcMcNbWcOcPcQcRcScTbXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadadadadadadadadadaaaaaaaaaaaaaaaabIbIbIbIaaaaaVaaaaaaaaaaaaadaQcUcVcUarcWcXarcCcYcZdadbdcdddcdedcdcdcdcdfdgbWdhcPdidjdkcxbXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadadadbIbIbIbIbIadadadadadadaaaaaaaaaaaaaabIbIbIaaaeaVaaaaaaaaaaaaadaQcUdlcUdmdndoardpdqdrdsdtdudvdwdxdydzdAdcdBdCbWdDdEdFdGbWbYbXaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadadadbIbIbIbIbIadadadadadadaaaaaaaaaaaaaabIbIbIaaaeaVaaaaaaaaaaaaadaQcUdlcUdmdndoardpdqdrdsdtdudvdwdxdydzdAdcdCdBbWdDdEdFdGbWbYbXaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadbIbIbIbIbIbIbIbIbIbIadadadadadaaaaaaaaaaaabIbIbIaaaeaVaaaeaeaeaeaeadaQcUdlcUaQdHdIaQbPbPdJdKdLdcdMdNdOdPdQdRdcdSdTdUdVdWdXdYbWdZadaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIadadadadadaaaaaaaabIbIbIaaaaaVaaaaaaaaaaaaaabjebdlcUecedeeefegeheiejekdcelemeneoepeqereseteueueuevewexezeyeyeAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIadadadadadbIaaaaaaaabIaaaaaVaaaaaaaaaaaaaaaneBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeueXeYeZfaeufbadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIadadadbIbIaaaaaaaaaaaaaVaaaaaaaaaaaaaaanfccUfdfefffgfhfifjaQfkflfmfnfofpfqfrfsdcftfufvfwfwfxfyfzfBfAadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadbIbIbIbIbIbIfCbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaaaVaaaaaaaaaaaaaaanfccUfdfefDfEfhfFfGaQfHfIdcfJdcdcdcdcfKdcfLfMeufNfOfPfQfRdZfSacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadbIbIbIbIbIbIfCbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaaaVaaaaaaaaaaaaaaanfccUfdfefDfEfhfFfGaQfIfHdcfJdcdcdcdcfKdcfLfMeufNfOfPfQfRdZfSacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaaaVaaaaaaeaaaaaaabjfTcUfUfefVfWfhfXfYaQfZgagbgcgdgegfdcggghgigjgkglgmgngofRdZadadadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaagpgqgqgqgrgqgqgqgsgtgubjgvgwaQaQaQaQaQgxgygzgcgAgegBdcgCgDgEgFgGgHgIgJgKgLgMgNaQgObKaBaBaBaBaBaBaCgPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaadadadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaagQgRgSgUgUgUgVgWgXgYgZhahbhchdhehfhghhhihjhkhlhmhnhodchphqhrhseueuhteueueuhuhvhwhxhyhzhzhAhzhzhzhBbqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaagpgqgqgqgrgqgqgqgsgugtbjgvgwaQaQaQaQaQgxgygzgcgAgegBdcgCgDgEgFgGgHgIgJgKgLgMgNaQgObKaBaBaBaBaBaBaCgPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaadadadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIaaaaaaaaaaaagQgRgSgUgUgUgVgWgXgYgZhahbhchdhehfhghhhihjhkhlhmhnhodchphqhshreueuhteueueuhuhvhwhxhyhzhzhAhzhzhzhBbqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIadadadaaaaaaaaaahChDgUgUgUgUhEhFhGhHhIhJhKhLhdhMhNhOhPhQhRhShThUhVhWhXhYhVhZiaibicidieibifibhVigihiiijikiliminiohzbHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIadadadaaaaaaaaaaipiqgUgUirgUisitiuiviwixiyizhdiAiBiCiDiEiFiGiHiIiJiKiLiMiNiKiOiLiPiKiLiQiRiSiTiUiViWiXiYiZjajajbhzbHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadadadadadbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIbIfCbIbIbIbIadadadadaaaaaaaagqjcgUjdjejfjgjhjijjjkjljmjnhdjojpjqjrjrjrjrjsjtjujvjtjwjxjyjwjzjAjBjzjzjCjDjEjFhzjGjHhzjIjajajJhzbHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm index 0635ad2bcc7..0be703c0465 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm @@ -49,7 +49,7 @@ "aW" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/syringe,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) "aX" = (/obj/structure/table/reinforced,/obj/item/weapon/grenade/chem_grenade/antiweed{pixel_x = 3; pixel_y = 5},/obj/item/weapon/grenade/chem_grenade/antiweed{pixel_x = 4},/obj/item/weapon/grenade/chem_grenade/antiweed{pixel_x = -3; pixel_y = -1},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) "aY" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/temperature,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) -"aZ" = (/obj/structure/table/reinforced,/obj/item/weapon/minihoe,/obj/item/weapon/shovel,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) +"aZ" = (/obj/structure/table/reinforced,/obj/item/weapon/cultivator,/obj/item/weapon/shovel,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) "ba" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ruin/unpowered) "bb" = (/obj/machinery/door/airlock/hatch{name = "Bio-Research Station"},/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/ruin/unpowered) @@ -122,3 +122,4 @@ agbvbvbvbvakbKatbGbGataaakbHbvbObvbPaaaa abacacacacbQbRaaaaaaaaaabSacbTbUbPaabVaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWaaaaaaaa "} + diff --git a/_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm index c53640a6726..ce7c6587e01 100644 --- a/_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm +++ b/_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm @@ -10,7 +10,7 @@ "aj" = (/obj/structure/closet/cardboard,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight/flare,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/weapon/shovel,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "ak" = (/obj/structure/closet/cardboard,/obj/item/device/flashlight/lantern,/obj/item/device/flashlight/lantern,/obj/item/device/flashlight/lantern,/obj/item/device/tape/random,/obj/item/device/tape/random,/obj/item/device/tape/random,/obj/item/weapon/storage/box/rxglasses,/obj/item/weapon/extinguisher,/obj/item/weapon/extinguisher,/obj/item/clothing/glasses/night,/obj/item/clothing/glasses/night,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "al" = (/obj/structure/closet/cardboard,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/box/bodybags,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plasteel,/area/ruin/unpowered) -"am" = (/obj/structure/closet/cardboard,/obj/item/weapon/kitchen/knife,/obj/item/weapon/kitchen/knife,/obj/item/weapon/hatchet,/obj/item/weapon/kitchen/rollingpin,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel,/area/ruin/unpowered) +"am" = (/obj/structure/closet/cardboard,/obj/item/weapon/kitchen/knife,/obj/item/weapon/kitchen/knife,/obj/item/weapon/hatchet,/obj/item/weapon/kitchen/rollingpin,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "an" = (/obj/structure/closet/cardboard,/obj/item/weapon/defibrillator,/obj/item/weapon/storage/box/autoinjectors,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "ao" = (/obj/structure/closet/cardboard,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/ammo_box/c9mm,/obj/item/ammo_box/c9mm,/obj/item/ammo_box/c9mm,/obj/item/ammo_box/c9mm,/obj/item/ammo_box/c9mm,/obj/item/ammo_box/c9mm,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "ap" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/turf/simulated/floor/plasteel,/area/ruin/unpowered) @@ -64,15 +64,15 @@ "bl" = (/obj/structure/table,/obj/item/weapon/storage/box/matches,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bm" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bn" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor/plasteel,/area/ruin/unpowered) -"bo" = (/obj/machinery/portable_atmospherics/hydroponics{pixel_y = 9},/obj/machinery/light{dir = 1},/turf/simulated/floor/light,/area/ruin/unpowered) -"bp" = (/obj/machinery/portable_atmospherics/hydroponics{pixel_y = 9},/turf/simulated/floor/light,/area/ruin/unpowered) +"bo" = (/obj/machinery/hydroponics/constructable{pixel_y = 9},/turf/simulated/floor/light,/area/ruin/unpowered) +"bp" = (/obj/machinery/hydroponics/constructable{pixel_y = 9},/obj/machinery/light{dir = 1},/turf/simulated/floor/light,/area/ruin/unpowered) "bq" = (/obj/machinery/blackbox_recorder,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "br" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bs" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/power/smes,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bt" = (/obj/machinery/telecomms/relay/preset/telecomms,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bu" = (/obj/machinery/light/small{dir = 1},/obj/structure/dispenser/oxygen,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bv" = (/obj/machinery/biogenerator,/turf/simulated/floor/plasteel,/area/ruin/unpowered) -"bw" = (/obj/machinery/light,/obj/machinery/portable_atmospherics/hydroponics{pixel_y = 9},/turf/simulated/floor/light,/area/ruin/unpowered) +"bw" = (/obj/machinery/light,/obj/machinery/hydroponics/constructable{pixel_y = 9},/turf/simulated/floor/light,/area/ruin/unpowered) "bx" = (/obj/machinery/autolathe,/turf/simulated/floor/plasteel,/area/ruin/unpowered) "by" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/turf/simulated/floor/plasteel,/area/ruin/unpowered) "bz" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel,/area/ruin/unpowered) @@ -152,9 +152,9 @@ aaaaababababababababababababababababababababababababacaQaRaSacaTaUacaVararararar aaaaaaabababababababababababababababababababababababacaYaZbaacbbaUacacbcbcaubcbcacacaXararbdbdbdacababababababababababababababababababababababababababababababababaaaaaaaa aaaaaaaaabababababababababababababababababababacacacacacauacacacbeacbfarararararauararararbdbdbdacabababababababababababababababababababababababababababababababababaaaaaa aaaaaaaaabababababababababababababababababababacbgaracarararbhararararararararbiacacacacacacacacacabababababababababababababababababababababababababababababababababaaaaaa -aaaaaaaaabababababababababababababababababababacbjarauarararararararbkblbmbnararacbobpbpboacababababababababababababababababababababababababababababababababababababaaaaaa +aaaaaaaaabababababababababababababababababababacbjarauarararararararbkblbmbnararacbpbobobpacababababababababababababababababababababababababababababababababababababaaaaaa aaaaaaaaabababababababababababababababababababacacacacacacauacacararacacacacararauararararacabababababababababababababababababababababababababababababababababababababaaaa -aaaaaaaaaaababababababababababababababababababacbqbrbsbtararbuacarararararararbvacbwbpbpbwacabababababababababababababababababababababababababababababababababababababaaaa +aaaaaaaaaaababababababababababababababababababacbqbrbsbtararbuacarararararararbvacbwbobobwacabababababababababababababababababababababababababababababababababababababaaaa aaaaaaaaaaaaabababababababababababababababababacbxarbyarararbzacbAbBbCbDbEararbFacacacacacacabababababababababababababababababababababababababababababababababababababaaaa aaaaaaaaaaaaabababababababababababababababababacbGbHbIarararbJacbKbBbLbMbEararbNacabababababababababababababababababababababababababababababababababababababababababababaa aaaaaaaaaaaaaaababababababababababababababababacbOararararbPbQacbRbSbBbBbBararbTacabababababababababababababababababababababababababababababababababababababababababababaa @@ -177,3 +177,4 @@ aaaaaaaaaaaaaaaaaaaaaaabababababababababababababcececececeababababababababababab aaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababcececececeababababababababaaaaaaababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababcececececeababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/RandomZLevels/academy.dmm b/_maps/map_files/RandomZLevels/academy.dmm index 500720c279f..4bc70976af3 100644 --- a/_maps/map_files/RandomZLevels/academy.dmm +++ b/_maps/map_files/RandomZLevels/academy.dmm @@ -191,7 +191,7 @@ "dI" = (/obj/item/seeds/replicapod,/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) "dJ" = (/obj/structure/table/woodentable,/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) "dK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) -"dL" = (/obj/item/seeds/bluespacetomatoseed,/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) +"dL" = (/obj/item/seeds/tomato/blue/bluespace,/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) "dM" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel,/area/awaymission/academy/classrooms) "dN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/awaymission/academy/classrooms) "dO" = (/obj/machinery/door/airlock/freezer,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/academy/classrooms) diff --git a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm index 8f413b01937..18c5b156d3a 100644 --- a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm +++ b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm @@ -101,6 +101,7 @@ "bW" = (/obj/machinery/light,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "bX" = (/obj/machinery/door_control{id = "packerMed"; pixel_y = -24},/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "bY" = (/obj/machinery/sleeper{dir = 1},/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) +"bZ" = (/obj/machinery/seed_extractor,/obj/item/seeds/plump/walkingmushroom,/turf/simulated/floor/plasteel{tag = "icon-green"; icon_state = "green"},/area/awaymission/BMPship/Midship) "ca" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) "cb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/item/weapon/hand_labeler,/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) "cc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) @@ -196,7 +197,6 @@ "dO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{tag = "icon-carpet"; icon_state = "carpet"},/area/awaymission/BMPship/Fore) "dP" = (/turf/simulated/floor/plasteel{tag = "icon-green (SOUTHWEST)"; icon_state = "green"; dir = 10},/area/awaymission/BMPship/Midship) "dQ" = (/turf/simulated/floor/plasteel{tag = "icon-green"; icon_state = "green"},/area/awaymission/BMPship/Midship) -"dR" = (/obj/machinery/seed_extractor,/obj/item/seeds/walkingmushroommycelium,/turf/simulated/floor/plasteel{tag = "icon-green"; icon_state = "green"},/area/awaymission/BMPship/Midship) "dS" = (/turf/simulated/floor/plasteel{tag = "icon-green (SOUTHEAST)"; icon_state = "green"; dir = 6},/area/awaymission/BMPship/Midship) "dT" = (/turf/simulated/shuttle/wall{tag = "icon-swall2"; icon_state = "swall2"},/area/awaymission/BMPship/Midship) "dU" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaymission/BMPship/Midship) @@ -516,7 +516,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCcDcCcEcFcGcHcIcJcKcIcLcGcMcNcOcPcQcRcMcMcMcMcScTcUcScVcWaxaxaxaxaxaxaxaxayaAcXaCcncoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcYcZcYdacCcEcMdbcHdcdcdcdccLcMcMdddedededfcMcMcMcMdgdgcMdgcMdhdididjdkdldmdldnaPdodpdqdrazaxaycoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCdsdtdsdudvcEcMcMcHdcdwdcdccLcMcMdxdydzdAdBcMcMcMcMcMcMcMcMcMaPdjdCdjbJdDdEdFdGaPdHdpdododIdJcWazaxcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCdKdLdMdNdOcEcMcMdPdQdQdRdQdScMcMdTcMdUdVdVdVdVdVdVdVdVdVdWcMdhdjdXdjdraxaxaxaxbVdHdYdZeaebecbbedeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCdKdLdMdNdOcEcMcMdPdQdQbZdQdScMcMdTcMdUdVdVdVdVdVdVdVdVdVdWcMdhdjdXdjdraxaxaxaxbVdHdYdZeaebecbbedeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciegegegeheiejekelddemeneoeoeoeoeoeodWcMddcMepcMeqerererererererepcMaPdjesdjdjdjdjdjetaPeuevbdewbdexeyezeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeAeBeCegcYcZcYcZeDeEeoeFererererereGeHcMeIcMepeJeKeLeKeKeKeKeMeNeOePbbdjeseQeReReSdjdjaPeTeUbdeVeWeXbJezeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeYeZfaegfbdtdsdtfcdTcMcMerfdfefdfffgepfhepcMepcMfierererererererepfjfkflfmfnfofpfqdjdjaPfreUbdewbdfscWayaxftaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/RandomZLevels/centcomAway.dmm b/_maps/map_files/RandomZLevels/centcomAway.dmm index 2cc70f5d3ee..773b57ce861 100644 --- a/_maps/map_files/RandomZLevels/centcomAway.dmm +++ b/_maps/map_files/RandomZLevels/centcomAway.dmm @@ -18,7 +18,7 @@ "ar" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/kitchen/rollingpin,/turf/simulated/floor/plasteel{tag = "icon-greenfull (NORTH)"; icon_state = "greenfull"; dir = 1},/area/awaymission/centcomAway/cafe) "as" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/food/condiment/enzyme,/turf/simulated/floor/plasteel{tag = "icon-greenfull (NORTH)"; icon_state = "greenfull"; dir = 1},/area/awaymission/centcomAway/cafe) "at" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/awaymission/centcomAway/cafe) -"au" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/centcomAway/cafe) +"au" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/centcomAway/cafe) "av" = (/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/centcomAway/cafe) "aw" = (/turf/simulated/floor/plasteel{tag = "icon-greenfull (NORTH)"; icon_state = "greenfull"; dir = 1},/area/awaymission/centcomAway/cafe) "ax" = (/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/awaymission/centcomAway/cafe) diff --git a/_maps/map_files/RandomZLevels/evil_santa.dmm b/_maps/map_files/RandomZLevels/evil_santa.dmm index 7d56e430210..0fc16a7eaa7 100644 --- a/_maps/map_files/RandomZLevels/evil_santa.dmm +++ b/_maps/map_files/RandomZLevels/evil_santa.dmm @@ -20,7 +20,7 @@ "at" = (/obj/structure/table/woodentable,/obj/item/weapon/newton,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "au" = (/obj/structure/grille,/obj/structure/window/full/basic,/turf/simulated/floor/plating,/area/awaymission/challenge/main) "av" = (/mob/living/simple_animal/hostile/winter/reindeer,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) -"aw" = (/obj/machinery/gun_turret/grenade{desc = "Winterized 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead."; faction = "winter"; name = "winterized mounted grenade launcher (40mm)"},/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) +"aw" = (/obj/machinery/porta_turret/syndicate/grenade{desc = "Winterized 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead."; faction = "winter"; name = "winterized mounted grenade launcher (40mm)"},/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "ax" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "ay" = (/obj/structure/table/woodentable,/obj/structure/safe/floor,/obj/item/weapon/gun/projectile/shotgun/automatic/combat,/obj/item/weapon/gun/projectile/automatic/mini_uzi,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "az" = (/obj/machinery/recharge_station,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) @@ -30,7 +30,7 @@ "aD" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "aE" = (/obj/machinery/floodlight,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "aF" = (/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) -"aG" = (/obj/machinery/gun_turret/exterior{desc = "Winterized exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets."; faction = "winter"; name = "winterized machine gun turret (7.62)"},/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) +"aG" = (/obj/machinery/porta_turret/syndicate/exterior{desc = "Winterized exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets."; faction = "winter"; name = "winterized machine gun turret (7.62)"},/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "aH" = (/mob/living/simple_animal/hostile/winter/snowman,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "aI" = (/obj/structure/flora/bush,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "aJ" = (/obj/item/weapon/pickaxe/gold,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) @@ -73,7 +73,7 @@ "bu" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "bv" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "bw" = (/obj/machinery/autolathe,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) -"bx" = (/obj/machinery/gun_turret/interior{density = 0; desc = "Winterized interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; faction = "winter"; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) +"bx" = (/obj/machinery/porta_turret/syndicate/interior{density = 0; desc = "Winterized interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; faction = "winter"; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "by" = (/obj/structure/table,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/plasteel,/area/awaymission/challenge/main) "bz" = (/obj/item/clothing/head/cone,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) "bA" = (/mob/living/simple_animal/walrus,/turf/simulated/floor/snow{carbon_dioxide = 21.8366; nitrogen = 0; oxygen = 82.1472; temperature = 73},/area/awaymission/challenge/main) diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 38617fb1dd0..38e5f6b3f97 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -536,7 +536,7 @@ "kp" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kq" = (/obj/structure/table,/obj/item/weapon/kitchen/rollingpin,/obj/item/weapon/kitchen/knife,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kr" = (/obj/structure/table,/obj/item/weapon/book/manual/chef_recipes{pixel_x = 2; pixel_y = 6},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) -"ks" = (/obj/effect/decal/cleanable/fruit_smudge,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"ks" = (/obj/effect/decal/cleanable/plant_smudge,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kt" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/processor,/obj/machinery/alarm/monitor{dir = 8; frequency = 1439; locked = 0; pixel_x = 23; pixel_y = 0; req_access = null},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "ku" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/item/weapon/reagent_containers/glass/rag{pixel_y = 5},/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "awaykitchen"; name = "Serving Hatch"},/turf/simulated/floor/carpet,/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "kv" = (/obj/structure/closet/crate/bin,/obj/item/trash/candy,/obj/item/trash/can,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index c09808a51f8..84a4b089ea2 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -483,7 +483,7 @@ "jo" = (/obj/effect/decal/remains/human,/obj/item/clothing/head/soft/red,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "jp" = (/obj/item/toy/prize/honk,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "jq" = (/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) -"jr" = (/obj/item/weapon/bananapeel,/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) +"jr" = (/obj/item/weapon/grown/bananapeel,/obj/item/toy/spinningtoy,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "js" = (/obj/structure/barricade/wooden,/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "jt" = (/obj/machinery/door/airlock/glass,/obj/item/tape/engineering{icon_state = "engineering_door"; layer = 3.2},/turf/unsimulated/floor/carpet,/area/awaymission/spacehotel) "ju" = (/obj/machinery/gateway{dir = 10},/turf/unsimulated/floor{icon_state = "warning"; dir = 10},/area/awaymission/spacehotel) diff --git a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm index cb8cb4e6227..5a76cbedb96 100644 --- a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm @@ -100,7 +100,7 @@ "bV" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 14; tag = "icon-manifold-r-f (NORTH)"},/turf/simulated/wall/rust,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "bW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; level = 1},/turf/simulated/wall,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "bX" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"bY" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"bY" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "bZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "ca" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "cb" = (/turf/simulated/floor/plating{burnt = 1; icon_state = "panelscorched"; tag = "icon-panelscorched"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) @@ -192,7 +192,7 @@ "dJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dK" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sink{pixel_y = 25},/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dL" = (/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 2; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) -"dM" = (/obj/structure/closet/secure_closet{icon_broken = "hydrosecurebroken"; icon_closed = "hydrosecure"; icon_locked = "hydrosecure1"; icon_off = "hydrosecureoff"; icon_opened = "hydrosecureopen"; icon_state = "hydrosecure"; locked = 0; name = "botanist's locker"; req_access_txt = "201"},/obj/item/device/analyzer/plant_analyzer,/obj/item/clothing/mask/bandana,/obj/item/weapon/hatchet,/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) +"dM" = (/obj/structure/closet/secure_closet{icon_broken = "hydrosecurebroken"; icon_closed = "hydrosecure"; icon_locked = "hydrosecure1"; icon_off = "hydrosecureoff"; icon_opened = "hydrosecureopen"; icon_state = "hydrosecure"; locked = 0; name = "botanist's locker"; req_access_txt = "201"},/obj/item/device/plant_analyzer,/obj/item/clothing/mask/bandana,/obj/item/weapon/hatchet,/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dN" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "green"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{burnt = 1; icon_state = "panelscorched"; tag = "icon-panelscorched"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dP" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 7; tag = "icon-manifold-r-f (WEST)"},/obj/structure/stool/bed/chair,/obj/structure/reagent_dispensers/peppertank{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 1; icon_state = "red"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) @@ -208,9 +208,9 @@ "dZ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "ea" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access_txt = "201"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "eb" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) -"ec" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{ icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) +"ec" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{ icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "ed" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) -"ee" = (/obj/structure/closet/secure_closet{icon_broken = "hydrosecurebroken"; icon_closed = "hydrosecure"; icon_locked = "hydrosecure1"; icon_off = "hydrosecureoff"; icon_opened = "hydrosecureopen"; icon_state = "hydrosecure"; locked = 0; name = "botanist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/apron,/obj/item/clothing/mask/bandana,/obj/item/weapon/minihoe,/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) +"ee" = (/obj/structure/closet/secure_closet{icon_broken = "hydrosecurebroken"; icon_closed = "hydrosecure"; icon_locked = "hydrosecure1"; icon_off = "hydrosecureoff"; icon_opened = "hydrosecureopen"; icon_state = "hydrosecure"; locked = 0; name = "botanist's locker"; req_access_txt = "201"},/obj/item/clothing/suit/apron,/obj/item/clothing/mask/bandana,/obj/item/weapon/cultivator,/turf/simulated/floor/plasteel{dir = 4; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "ef" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Security Checkpoint Maintenance"; req_access_txt = "201"; req_one_access_txt = "0"},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "eg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "eh" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) @@ -1260,30 +1260,30 @@ "yl" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "ym" = (/obj/structure/ore_box,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yn" = (/obj/structure/closet/crate,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yo" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yo" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/structure/stool/bed/nest,/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yp" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/effect/glowshroom/single,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yq" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yr" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib2_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ys" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yt" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse,/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yt" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse/miner/rig,/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yu" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/glowshroom/single,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yv" = (/obj/structure/alien/weeds,/obj/structure/stool/bed/nest,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yw" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yx" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yy" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yz" = (/obj/structure/alien/resin/membrane,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yA" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yA" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yB" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yC" = (/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gib1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yD" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yE" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/splatter{color = "red"},/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yD" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yE" = (/obj/structure/alien/weeds{tag = "icon-weeds2"; icon_state = "weeds2"},/obj/effect/decal/cleanable/blood/splatter{color = "red"},/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yF" = (/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gibdown1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yG" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 4; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yH" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; dir = 5; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yI" = (/obj/effect/decal/cleanable/blood/splatter{color = "red"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "yJ" = (/obj/structure/alien/weeds,/obj/effect/decal/cleanable/blood/gibs{color = "red"; icon_state = "gibdown1_flesh"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yK" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) -"yL" = (/obj/structure/alien/weeds,/obj/effect/landmark/corpse,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yK" = (/obj/structure/alien/weeds{tag = "icon-weeds1"; icon_state = "weeds1"},/obj/effect/landmark/corpse/miner/rig,/obj/effect/decal/cleanable/blood/tracks{color = "red"; desc = "Your instincts say you shouldn't be following these."; icon = 'icons/effects/blood.dmi'; icon_state = "tracks"},/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) +"yL" = (/obj/structure/alien/weeds,/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/plating/airless/asteroid,/area/awaycontent/a7{always_unpowered = 1; has_gravity = 1; name = "UO45 Caves"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/RandomZLevels/wildwest.dmm b/_maps/map_files/RandomZLevels/wildwest.dmm index 113bf83c346..07acec7105d 100644 --- a/_maps/map_files/RandomZLevels/wildwest.dmm +++ b/_maps/map_files/RandomZLevels/wildwest.dmm @@ -68,7 +68,7 @@ "bp" = (/obj/structure/lattice,/turf/space,/area/space) "bq" = (/obj/effect/mine/dnascramble,/obj/item/ammo_box/c10mm,/turf/simulated/floor/wood,/area/awaymission/wwmines) "br" = (/obj/structure/closet/crate,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/awaymission/wwrefine) -"bs" = (/turf/simulated/wall/mineral/sandstone,/area/awaymission/wwmines) +"bs" = (/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "bt" = (/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/turf/space,/area/space) "bu" = (/obj/structure/lattice,/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/turf/space,/area/space) "bv" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) @@ -125,7 +125,7 @@ "cu" = (/obj/item/weapon/moneybag,/turf/simulated/floor/carpet,/area/awaymission/wwgov) "cv" = (/obj/structure/stool/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/awaymission/wwgov) "cw" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/wood,/area/awaymission/wwmines) -"cx" = (/obj/effect/mine/plasma,/obj/item/ammo_box/c10mm,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) +"cx" = (/obj/effect/mine/gas/plasma,/obj/item/ammo_box/c10mm,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "cy" = (/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor/wood,/area/awaymission/wwgov) "cz" = (/obj/item/clothing/gloves/color/yellow,/obj/item/device/multitool,/turf/simulated/floor/wood,/area/awaymission/wwgov) "cA" = (/obj/structure/stool/bed/chair/wood/normal{dir = 4},/turf/simulated/floor/wood,/area/awaymission/wwgov) @@ -166,7 +166,7 @@ "dj" = (/obj/item/weapon/reagent_containers/food/drinks/bottle/patron,/turf/simulated/floor/plasteel{tag = "icon-stage_bleft"; icon_state = "stage_bleft"},/area/awaymission/wwgov) "dk" = (/obj/effect/decal/cleanable/blood/tracks,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "dl" = (/obj/effect/decal/cleanable/blood/tracks,/turf/simulated/floor/wood,/area/awaymission/wwmines) -"dm" = (/obj/effect/mine/plasma,/obj/item/ammo_box/c10mm,/turf/simulated/floor/wood,/area/awaymission/wwmines) +"dm" = (/obj/effect/mine/gas/plasma,/obj/item/ammo_box/c10mm,/turf/simulated/floor/wood,/area/awaymission/wwmines) "dn" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "do" = (/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand4"; icon_state = "ironsand4"},/area/awaymission/wwgov) "dp" = (/obj/effect/landmark/corpse/miner/rig,/turf/simulated/floor/wood,/area/awaymission/wwmines) @@ -195,10 +195,10 @@ "dM" = (/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "dN" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "dO" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 4},/turf/simulated/floor/carpet,/area/awaymission/wwmines) -"dP" = (/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly,/turf/simulated/floor/carpet,/area/awaymission/wwmines) +"dP" = (/obj/item/weapon/reagent_containers/food/snacks/donut,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "dQ" = (/obj/item/weapon/reagent_containers/food/drinks/coffee,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "dR" = (/obj/item/weapon/reagent_containers/food/snacks/donut/jelly,/turf/simulated/floor/carpet,/area/awaymission/wwmines) -"dS" = (/obj/item/weapon/reagent_containers/food/snacks/donut/normal,/turf/simulated/floor/carpet,/area/awaymission/wwmines) +"dS" = (/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "dT" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 8},/turf/simulated/floor/carpet,/area/awaymission/wwmines) "dU" = (/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/turf/space,/area/space) "dV" = (/obj/structure/lattice,/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/turf/space,/area/space) @@ -207,7 +207,7 @@ "dY" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwgov) "dZ" = (/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/turf/space,/area/space) "ea" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) -"eb" = (/obj/effect/mine/plasma,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) +"eb" = (/obj/effect/mine/gas/plasma,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "ec" = (/obj/effect/decal/cleanable/blood,/obj/machinery/washing_machine,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaymission/wwmines) "ed" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/obj/item/ammo_box/a357,/turf/simulated/floor/wood,/area/awaymission/wwmines) "ee" = (/obj/structure/stool/bed/chair/comfy/brown{tag = "icon-comfychair_brown (EAST)"; icon_state = "comfychair_brown"; dir = 4},/turf/simulated/floor/carpet,/area/awaymission/wwmines) @@ -228,7 +228,6 @@ "et" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand12"; icon_state = "ironsand12"},/area/awaymission/wwgov) "eu" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/obj/item/weapon/gun/projectile,/turf/simulated/floor/wood,/area/awaymission/wwmines) "ev" = (/obj/effect/decal/cleanable/blood,/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/turf/simulated/floor/wood,/area/awaymission/wwmines) -"ew" = (/obj/item/weapon/reagent_containers/food/drinks/coffee,/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly,/turf/simulated/floor/carpet,/area/awaymission/wwmines) "ex" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 8},/obj/effect/decal/cleanable/blood/gibs/body{tag = "icon-gibdown1"; icon_state = "gibdown1"},/turf/simulated/floor/carpet,/area/awaymission/wwmines) "ey" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand7"; icon_state = "ironsand7"},/area/awaymission/wwgov) "ez" = (/obj/structure/sign/vacuum,/turf/simulated/wall/r_wall,/area/awaymission/wwrefine) @@ -239,7 +238,7 @@ "eE" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) "eF" = (/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) "eG" = (/obj/structure/window/reinforced{tag = "icon-fwindow (EAST)"; icon_state = "fwindow"; dir = 4},/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) -"eH" = (/obj/effect/mine/plasma,/turf/simulated/floor/wood,/area/awaymission/wwmines) +"eH" = (/obj/effect/mine/gas/plasma,/turf/simulated/floor/wood,/area/awaymission/wwmines) "eI" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 1; icon_state = "comfychair_beige"; tag = ""},/turf/simulated/floor/carpet,/area/awaymission/wwmines) "eJ" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/turf/simulated/floor/carpet,/area/awaymission/wwmines) "eK" = (/obj/effect/decal/cleanable/blood/gibs/body{tag = "icon-gibup1"; icon_state = "gibup1"},/turf/simulated/floor/carpet,/area/awaymission/wwmines) @@ -268,7 +267,7 @@ "fh" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/turf/space,/area/space) "fi" = (/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/turf/space,/area/space) "fj" = (/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/window/reinforced{tag = "icon-fwindow (EAST)"; icon_state = "fwindow"; dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) -"fk" = (/obj/effect/mine/plasma,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) +"fk" = (/obj/effect/mine/gas/plasma,/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "fl" = (/obj/effect/decal/cleanable/blood/gibs/body{tag = "icon-gibdown1"; icon_state = "gibdown1"},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "fm" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/wood,/area/awaymission/wwmines) "fn" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/wood,/area/awaymission/wwmines) @@ -582,48 +581,48 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbabababababaaUaLaRaRaXaRaRbhbhbhbnbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbkbhaRaRaRaRaRaRaXaRaRaRaRaRaLaLaLaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaIaUbababobababfaUaLaRaRaRaRaRbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbkbhbhbhbhbhbhbibhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaIaUaUbabababfbabaaUaLaRaRaRaRaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbqbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpaaaaaaaabpbpbpbpbpbpbpbpbpbpaabpaabpbpbpbpaaaaaabpbpbpbpbpbpbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbrbabababababaaUaLaRaRaRaRaRbkbhbhbhaRbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsaRbhbhbhbhaRbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaLaLaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaabpbtbububububububtbtbtbtbtbububtbtbtbubtbtbtbtbubububububtbtbtbtbtaabpaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaRbsbvbwbwbxbwbwbwbsbybzeSbzbBbsaRbhbhbCbhaRbsbDbDbDfQbDbDbDgEbBbBbEcebFbGbBgFbhbhbhbhgGbwbwbHgHbJbwbKbsaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaLaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbLbMbNbObObObObObObObObObObObObObObObObObObObObObObObObObObObObPbMbQaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaIaUbabababfbababaaUaLaRaRaRaRaRbhbhbhbhaRbsgIbRbwbwbwbSgJbsbhbhbhbhbhbsaRbhbhbhbhaRbsbDbDbDbDbDbDbDbhbhbhbhbhbhbhbhbhbhbhbhbhbhbwbwbwbwbwbwbwbsaRbhbhbhbhaRaXaRaRaRaRaRaRaRaRaRaRaRaLaLaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbTbUbVbVbVbVbVbVbVbVbVbWbVbVbVbVbVbVbVbVbVbVbWbVbVbVbVbVbVbVbVbVbXbQaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbfbababababfbaaUaLaRaWaRaRbdbhbhbhbhaRbsbwbwbwbwbwbwbwbsbhbhbhbhbhbsaRbhbkbhbhaRbsbDbDbDbDbDbDbDbBbBbBbBbBbBbBbAbBbYbBbBbBbZbwbwbwbwcabwbwbsaRbhbhbhbhaRaRaRaRaRaRaRaXaRaRaRaRaRaRaLaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbVccbQaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbkbhaRbsgIbRcdbwbwbSgJbsbsbsbsbscfbsaRbhbnbhbhaRbsgKcgbDbDchcgbDbBcicicicicicicicibhbhbhbhbBbwbwbwbwbwbwgJbsaRbhbhbCbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMcjcjcjcjcjcjbMckclgLclclckgMclckckgLckclbMcmcngNcncpbMbVcccqaaaaaaaaaaaabpcrbpaaaaaaaaaaaaaaaaaaaGaGaIaUbababababababmaUaLaRaRaRaRaRbibhbhbhaRbsbwbwbwbwbwbwbwcfbhbhbhbhbhbsaRbhbhbhbhaRbsbDbDbDcsbDbDbDbBbhbhbhbhbhbhbhbhbhbhbhbhbBbwbwbwbwbwbwbwbsaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaLaLaRaLaIaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMckckckclckckbMckctctctctcuctcuckcvcvclckbMcncncncncnbMbWcccqaaaaaaaaaabpbpbpbpbpbpaaaaaaaaaaaaaaaGaGaIaUbabmbabmbababaaUaLaRaRaRaRaRbhbhbhbhaRbsbsbsbsbsbsbsbsbsbhbhbhbhgObsaRbhcwbhbhaRbsbDbDbDbDbDbDbDbBbhbhbhbhgPbhbhgPbhbhbhbhbBbwbwbwbwbwbwbwbsaRbhbhbhbhaRaRcxaRaRaRaRaRaRaRaRaLaLaLaLaIaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpbpbLcbbVbMgQczckckckgRbMgScuctctctctctctcAckckckgRbMgTcncBcCgUbMbVcccqbpbpaabpbpbpaaaaaabpbpbpbpaaaaaaaaaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaRbscDbhgVbhbhbhgVbhbhbhbhbhbhbsaRbhbhbhbhaRbsbBbBbBbBbBbBbBbBbhbhbhgWbsgXgObsgXbhbhbhbBbBbBcEcFbBbBbBbsaRbkbhbnbhaRaRaRaRaRaRaRaRaRaRaRaRaLaLaLaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpaabTcbbVbMcGcHckckcIckcJckctctctctcKctctcAckckckckbMcncncncncnbMbWccbQaacrbpbpaaaaaaaaaaaaaaaabpbpbpaaaaaGaGaGaIaUbfbabababababaaUaLaRaRaRaRaRbhbibhbhaRbscDbhbhbsbsbhbhbsbsbhbhbsbsbsaRbhbhbhbhaRbsbhcicicicicicibhbhbhbhbhgVbhbhgVbhbhbhbhbhcicicicicicibhbsaRbhbhbhbhaRaRaRaRaRaRaRaRaWaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpaabTcLbVbMcyczckckckckbMckctctctctctctctcMckckckckcJcncncncncnbMbVcNbQaabpaaaaaaaaaaaaaaaaaaaaaaaabpaaaGaGaGaGaIaUbabfbacObababaaUaLaRaYaRaRaXbhbhbhbhaRbscDbCbhcDbsbhbhbsbhbhbhbhbhbsaRbhbhbhbhaRbsbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbsaRbhbhbhbhaRaRaRaXaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpaabLbMbVbMckckckckckckbMckctctcPctctctctcMckckckckbMcncQcRcScnbMbVbMbQaabpaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaRbscDbhbhcDbsbhbhbsgYbhbhbhgZbsaRbhbhbhbkaRbscVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhbsaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaacrbpbLcXbVbMgSckcIckclgRbMgSctctctctctctctcMckckckgRbMhacncYcngUbMbVcZbQaabpbpaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaIaIaUbababababfbabaaUaLaRaRaRaRaRbhbhbkbhaRbscDbhgPcDbsbhbhbscTbhbhbhcUbsaRbkbhbhbhaRbsbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbhbsaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaabpbpaabTcbbVbMckckckckckclbMckcuctdactctctctckckckckckbMcncncncncnbMbVccbQbpbpbpbpaaaaaaaaaaaaaaaaaGaGaGaGaGaGaIaIaUaUbabababababadbaUaLaRaRaRaRaRbhbhbhbhaRbsbsbsbsbsbscfcfbsbsdcdcbsbsbsaRbhbhbjbhaRbsbsbsbsdcdcdcbsbsbsbsbsbsbsdddebsbsbsbsbsbsbsdcdcdcbsbsbsbsaRcwbhbkbhaRaRaRaYaRaRaRaRaRaRaRaRaRaLaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpaaaaaaaabpbpbpbpbpbpbpbpbpbpaabpaabpbpbpbpaaaaaabpbpbpbpbpbpbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbrbabababababaaUaLaRaRaRaRaRbkbhbhbhaReXeXeXeXeXeXeXeXeXeXeXeXeXeXeXaRbhbhbhbhaReXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaLaLaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaabpbtbububububububtbtbtbtbtbububtbtbtbubtbtbtbtbubububububtbtbtbtbtaabpaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaReXbvbwbwbxbwbwbweXbybzeSbzbBeXaRbhbhbCbhaReXbDbDbDfQbDbDbDgEbBbBbEcebFbGbBgFbhbhbhbhgGbwbwbHgHbJbwbKeXaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaLaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbLbMbNbObObObObObObObObObObObObObObObObObObObObObObObObObObObObPbMbQaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaIaUbabababfbababaaUaLaRaRaRaRaRbhbhbhbhaReXgIbRbwbwbwbSgJeXbhbhbhbhbheXaRbhbhbhbhaReXbDbDbDbDbDbDbDbhbhbhbhbhbhbhbhbhbhbhbhbhbhbwbwbwbwbwbwbweXaRbhbhbhbhaRaXaRaRaRaRaRaRaRaRaRaRaRaLaLaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbTbUbVbVbVbVbVbVbVbVbVbWbVbVbVbVbVbVbVbVbVbVbWbVbVbVbVbVbVbVbVbVbXbQaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbfbababababfbaaUaLaRaWaRaRbdbhbhbhbhaReXbwbwbwbwbwbwbweXbhbhbhbhbheXaRbhbkbhbhaReXbDbDbDbDbDbDbDbBbBbBbBbBbBbBbAbBbYbBbBbBbZbwbwbwbwcabwbweXaRbhbhbhbhaRaRaRaRaRaRaRaXaRaRaRaRaRaRaLaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbVccbQaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaaaaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbkbhaReXgIbRcdbwbwbSgJeXeXeXeXeXcfeXaRbhbnbhbhaReXgKcgbDbDchcgbDbBcicicicicicicicibhbhbhbhbBbwbwbwbwbwbwgJeXaRbhbhbCbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMcjcjcjcjcjcjbMckclgLclclckgMclckckgLckclbMcmcngNcncpbMbVcccqaaaaaaaaaaaabpcrbpaaaaaaaaaaaaaaaaaaaGaGaIaUbababababababmaUaLaRaRaRaRaRbibhbhbhaReXbwbwbwbwbwbwbwcfbhbhbhbhbheXaRbhbhbhbhaReXbDbDbDcsbDbDbDbBbhbhbhbhbhbhbhbhbhbhbhbhbBbwbwbwbwbwbwbweXaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaLaLaRaLaIaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbTcbbVbMckckckclckckbMckctctctctcuctcuckcvcvclckbMcncncncncnbMbWcccqaaaaaaaaaabpbpbpbpbpbpaaaaaaaaaaaaaaaGaGaIaUbabmbabmbababaaUaLaRaRaRaRaRbhbhbhbhaReXeXeXeXeXeXeXeXeXbhbhbhbhgOeXaRbhcwbhbhaReXbDbDbDbDbDbDbDbBbhbhbhbhgPbhbhgPbhbhbhbhbBbwbwbwbwbwbwbweXaRbhbhbhbhaRaRcxaRaRaRaRaRaRaRaRaLaLaLaLaIaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpbpbLcbbVbMgQczckckckgRbMgScuctctctctctctcAckckckgRbMgTcncBcCgUbMbVcccqbpbpaabpbpbpaaaaaabpbpbpbpaaaaaaaaaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaReXcDbhgVbhbhbhgVbhbhbhbhbhbheXaRbhbhbhbhaReXbBbBbBbBbBbBbBbBbhbhbhgWeXgXgOeXgXbhbhbhbBbBbBcEcFbBbBbBeXaRbkbhbnbhaRaRaRaRaRaRaRaRaRaRaRaRaLaLaLaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpaabTcbbVbMcGcHckckcIckcJckctctctctcKctctcAckckckckbMcncncncncnbMbWccbQaacrbpbpaaaaaaaaaaaaaaaabpbpbpaaaaaGaGaGaIaUbfbabababababaaUaLaRaRaRaRaRbhbibhbhaReXcDbhbheXeXbhbheXeXbhbheXeXeXaRbhbhbhbhaReXbhcicicicicicibhbhbhbhbhgVbhbhgVbhbhbhbhbhcicicicicicibheXaRbhbhbhbhaRaRaRaRaRaRaRaRaWaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpaabTcLbVbMcyczckckckckbMckctctctctctctctcMckckckckcJcncncncncnbMbVcNbQaabpaaaaaaaaaaaaaaaaaaaaaaaabpaaaGaGaGaGaIaUbabfbacObababaaUaLaRaYaRaRaXbhbhbhbhaReXcDbCbhcDeXbhbheXbhbhbhbhbheXaRbhbhbhbhaReXbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbheXaRbhbhbhbhaRaRaRaXaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpaabLbMbVbMckckckckckckbMckctctcPctctctctcMckckckckbMcncQcRcScnbMbVbMbQaabpaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaIaUbababababababaaUaLaRaRaRaRaRbhbhbhbhaReXcDbhbhcDeXbhbheXgYbhbhbhgZeXaRbhbhbhbkaReXcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbhcVbBcWbheXaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaacrbpbLcXbVbMgSckcIckclgRbMgSctctctctctctctcMckckckgRbMhacncYcngUbMbVcZbQaabpbpaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaIaIaUbababababfbabaaUaLaRaRaRaRaRbhbhbkbhaReXcDbhgPcDeXbhbheXcTbhbhbhcUeXaRbkbhbhbhaReXbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbhbhbhbhhbbheXaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaabpbpaabTcbbVbMckckckckckclbMckcuctdactctctctckckckckckbMcncncncncnbMbVccbQbpbpbpbpaaaaaaaaaaaaaaaaaGaGaGaGaGaGaIaIaUaUbabababababadbaUaLaRaRaRaRaRbhbhbhbhaReXeXeXeXeXeXcfcfeXeXdcdceXeXeXaRbhbhbjbhaReXeXeXeXdcdcdceXeXeXeXeXeXeXdddeeXeXeXeXeXeXeXdcdcdceXeXeXeXaRcwbhbkbhaRaRaRaYaRaRaRaRaRaRaRaRaRaLaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbMckdgclckckckbMckckhcckckckhccIckckhcckckbMdhdhhddjdjbMbVcccqbpaaaabpbpbpbpaaaaaaaGaGaGaGaGaGaGaGaIaUaUbfbmbabababmbabaaUaLaRaRaRaRaRbhbhbhbhaRaRaRaRaRaRhedkaRheaRaRaRaRaRaRaRbhbhbhbhaRaRaRaRheaRaRaRheaRaRaRaRaRheaXdkheaRaRaRaRaRheaRaRaRheaRaRaRaRbhbhbhbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbMbMbMbMbMbMbMbMbMbMbMcJcJbMbMbMbMbMbMbMbMbMbMbMbMbMbMbMbVcccqaaaaaaaaaaaabpbpbpaGaIaIaIaIaIaIaIaIaIaUaZbabababababababfaUaLaRaRaRaRaRbhbhbibhbhbhbhbhbhbhbhdlbkbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhdmbhbhbhbhbhdlbhbhbhbkbhbhbhbhbhbhbhbhbhbhbhbjbhbhbhaRaRaRaRdnaRaRaRaRaRaRaRaRaLaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbVbVbVbVbVbVdobVbVbVhfbVbVhfbVbVbVbVbVbVbVbVbVbVbVbVbVbVdocccqbpaaaaaaaaaaaaaaaGaGaIaUaUaUaUaUaUaUaUaUbabababababfbaaUaUaUaLaRaRaRaRaRbhbhdpbhbhbhbhbhbhbhbhdlbhbhbhbhbhbhbhbhbhbhbhbhcwbhbhbhbhbhbhbhbhbhbhbhbibhbhbhbhdlbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhaRaRaRaRaRaRaRaXaRaRaRaRaRaLaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVdobVbVbVbVbVbVbVbVbVbVbVdqbVbVbVbVbVbVdobVbVbVdrbVbVbVbVbVccbQbpaaaaaaaaaaaaaaaGaGaIaUaZbabmbababfbabababababababmbaaUaNaLaLaRaRaRaRaRbibhbhbhbhbhbhbhbhbhbhbhbhbhbhbibhbhbhbhbhbhbhbhbhbhbhbhbhbkbhbhbhbhbhbhbhbhbhbhbhdlbhbhbhbhbjbhbhcwbhbkbhbhbhbhbhbhbhbkbhaRaRaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbVbVbMbMbMbVbVbVbVbVbVbVbWbVbVbVbVbVbVdqbVdrbVbVbVbVbWbVbVccbQbpaaaaaaaaaaaaaGaGaGaIaUbababababababababmbababfbaaUaUaUaLaLaRaRaWaRaRaRbqbhbhbhbhbhbhbnbhbhbhbhbhbhbhdlbhbkbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhbhdlbhbhbhbhbhbhbhbhbhbhbhbhbhbhbnbhbhbhbhaRaRaRaRhgaRaRhgaRaRaRaRaRaLaLaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbVbVbMdsbMbVbVbVdrbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVdtbVbVbVccbQbpbpaaaaaaaaaaaGaGaGaIaUbabfbababablbabababababaaUaUaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRhgdkaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbhbhdpbhbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsdcdcbsbsbsbsbsaLaLaNaGaGaGaGaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaabpbpaadfcbdrbVbVbMdubMbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVdobVbVdrbVbVbWbVccbQbpbpbpaaaaaGaGaGaGaGaIaUbabababababababababfbabaaUaNaNaLaLaRaRaRaRaRaRaRaWaRaRaRaRaRaRbsbsbsbsbsbsbsbscfbsbsbsbsbsbsbsaRaRbsbsbsbsbsbsbsbsbsbsbsbsbsaRbjbhbhbhbsbhbhbhgVbhbhgVbibhbhbsdvhhdvdvdvbhdvbsbhbhgVbhbhbhgVbhbhbsaLaNaNaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpbpdfcLbVbVbVbVbVhfbVbVbVbVbVbVbVbVbVbVbVdwbVbVbVbVbVbVbVbVbVbVbVbVcNbQbpaabpbpbpaGaGaGaGaGaIaUbmbabababfbabababaaUaUaUaUaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsbwhibwbwhibwbsbhbshjbwbwbwbwbsaRaRbsbhdygVdybhdybhdygVdybhbsaRbhbhbhbhbsbhbDdzbDdAdBbDbDbDbhdCbhbhbhbhbhbhbhbsdDcwdEbhbjbhdFdGbhdHaLaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpdfbMdIdJdJdJdJdJdJdJdJdJdJdKdLdLdIdJdJdJdJdJdJdJdJdJdJdJdJdJdJdKbMbQbpaaaabpaGaGaGaGaGaGaIaUbababababababmbabaaUaNaNaNaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsdMbwbwbwbwdNbsbhbsdxbwbwbwbwbsaRaRbsbhbhbhbhbhbhbhbhbhbhbhbsaRbkbhbhbhbsbhbDdOdPdQdRdSdTbDbhbsbhbhbhbhdGbhbhbsbBbhdEbhbhbhdFbhbhbsaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpbpaadUdUdUdUdUdUdUdUdUdUdUdVdWdXdYdZdUdUdUdUdUdUdVdUdUdUdUdUdUdVdUdUbpcraaaabpbpbpaGaIaIaIaIaUbbbbaUaUaUaUbabmaUaUaNaNaLaLaRaRaRaRaXaRaRaRaRaReaaRaRaXaRaRaRbsdMbxebbwbwdNbsgObsecbwebbwbwbsaRaRbsbhdybhdybhdybhedbhdybhbsaRbhbhbhbhbsgXbDeedQbDbDdQefdzgObsdvbhbhbhbhbhbhbsdDbhdEbhbhcwdFbhbhdHaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaabpbpbpbpdfeheibQaaaaaaaaaaaabpbpbpbpbpbpbpbpbpbpbpbpbpaaaaaacraIaIejejejejekekejejejaUaUaUaUaNaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsdMbwbwelbwdNbsbhbsdxbwbwbxbwbsaRaRbsgXbhbibhbhbhbhbhbhbhgObsaRbhbhbhbhbsbhbDdOdSbDbDdSdTembhbsdvdvbhbhbhhkbhdCbhbhbhdGbhbhdFbhbhbsaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpaaaaaaaaaaaabpbpaaaaaadfeneobQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpbpbpejejejepeqerekekekekejejejejaNaNaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsdMhlbwbwhldNbsbhbshjbwbwbwbwbsaRaRbsbhbhbhbhbhbCbhbhbhbhbhcfaRbhbhbnbhbsbhbDeedRbDbDdRefbDbhbsbsbsbsbsbsbsbsbsbhesesesesbhdFbhbhdHaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpbpbpbpbpbpaaaaaaaadfdXetbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaejekekekekekekekekekekekekejaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaXaRaRaRaRbsbsbsbwbwbsbsbscfbsbsbwbwbsbsbsaWaRbsbheubhdybhdybhevbhdybhbshmbhbhbhbhbshnbDdOdQbDbDewexbDgObsbyhobybybyhobybsbhdDhpbBdDbhgPbhbhbsaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfeheybQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezekekekekekekekekekekekekejaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsbhbhbhbhbhbhbhbhbhbhbhbhbhbhbsdkaRbsgXbhbhbhbhbhbhbhbhbhgObsaRbhdpbhbhbsbhbDeedSdQdPdRefeAbhbsbhbhbhbhbhbhbhbsbsbsbsbsbseBbsbsbsbsaLaNaNaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfeCdYbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeDeEeFeGekekekekekekekekekekekekejaNaNaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbsbhbheHbhbsbsbsbsbsbsbhbhbhbhbsdkaWbsbhdybhevbhdybhdybhdybhbsaRbhbhbhbhbsbhbDbDbDeIeJeKbDbDbhdCbhcwbhbhbjbhbhdCeLhqeMeNeOeOePhreLbsaLaNaNaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfdXeQbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeRekekeRekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaXaRaRaRaRaRaRaNaNaRaRaRaRaRaRbsgXbhbhbhbhhshshshsbhbhbhbhgObsdkaRbsbhbhbhbhbhbhbhbhbhbhbhbsaRbhbhbhbhbsbhbhbhgPbhbhgPbhbhbhbsbhbhbhbhbhbhbhbseLeLeLeTeUeVeLeLeLbsaLaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfendYbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeDeEeEeWekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaRaRaRbsbhbhbhgPdpbibhbhbhbhgPbhbhbhbsdkaRbsbhbhgPbhbhbhbhbhgPbhbhbsaRbhbhbhbhbsbsbsbsbseXeXbsbsbsbsbsbsbsbsbsbsbsbsbseLeLeYeLeLeVeLeLhtbsaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfdXeibQaaaaaaaaaaaaaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaeZekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaRaRaRaRbdaRaRaRaNaNaNaRaRaRaRbsfabsfabsfabsfabsbsfabsfabsfbbsaRaXfcbsbsbseBbsbsbsbsbsbsbsbsaRbhbhcwbhfdfebhgVbBbhbhbsbhbhgVbhbhbsbhbhgVbhbhbsffeLfgeLffeLfgeLeLbsaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaabtbtbtbtbtbtbtbtbtbtbtbtbtbtfhdLdLfibtbtbtbtbtbtaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaNaNaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaRbsbsbsbsbsbsbsbsbsbsbsfcbsbsbsbsaRaRfkaRaWaRaRaRaRflaRaWaRaRaRaRbhbhbhgObshubhbhbBfmbhbsbhfnbBfmbhbsbhfobBfpbhbseLeLeLfqeLeLeLfqeLbsaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfrfsfsfsfsfsfsfsfsfsfsfsfsfsfsftftfsfsfsfsfsfsfufvbpbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaejekekekekekekfwekekekekekejaNaLaLaPaRaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReaaWfxfcbsbsbsbsbseBbsbsbsbsbsbsaRbjbhbhfycfbhbhbhbBbhbhbsbhbhegbhbCbsbjbhbhbhbhbsdcdcdcbsdCbseLfzeLbsaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBfvbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaaafCekekekekekekekekekekekekejaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaRaRaRaRaRaRbsbsbsbsbsbsbsbsbsbsbsbsfcdkbsfDbhbhbhbhgVbhbhbhbhbhbsaRbhfEbhbhcfbhbhbhbBfmgObsbhfnbBfmbjbsbhfobBfpbhbsbhbhbhbhbhdceLeLhtbsaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftfFfFfGfHfIfIbpbpbpaaaaaaaaaaaaaaaaaaaaaaeZekekekekekekfJekekekekekejaNaLaRaRaRaRaRaRaRaRaRaRaPaRaNaNaNaNaNaNaNaRaRaRaRaRaRbsfKbhbhbhbhgVbhbhbhbhbhbsdkeBbhbhbhbhdpcwbhbhbhbhbhddaRbhbjbhgObshubjbhbBbhbhbsgXbhbBbhgObsgXcwfLbhgObsbsbsbsbhbhdceLfMeLbsaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftfNftfNfIfIfIbpbpaaaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaNaLaRaRaRaRaRaRaNaNaNaNaNaNaNaNaNaNaNaNaNaRaRaRaRaRaRbsbhbhbhbhbjbhfObhbjdGbhbsflbsbhbhdGbhbhbhbhbhbhcwbhbshmbhfPbhbhbsfebhbhbBbhbhbsbhfnbBfmbhbsbhfobBfpbhbshvbhbshnbhdceLeLeLbsaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftfSftftftftftftftftftftftftftftftftftfsfsfTfHfIbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaejekekekekekekekekekekekekejaLaLaRaRaRaRaLaLaLaLaLaLaLaLaLaLaLaLaLfUaLaLaRaRaRaRaRbsbhbhbhbhbhfPfVdpbhfWbhcfaRbsgXbhbhbhbhbhfRbhbhbhgObsdnbhbhbhbheBfXbhbhbBfmgObsbhbhbhbhbhbsbhbhbhbhbhbsfYbhcfbhbhdceLfZeLbsaLaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBfvbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaafCekekekekekekekekekekekekejaLaPaRaRaLaLaLaLaRaRaRaRaRaRaRaRdnaRaRaRaLaLaLaRaRaRaRbsgXdpbhbhbhbhbhbhgabhgOeBhmbsbhbhbhbhbhbhdpbhbhdGbheBaRbhbhbhbhbsfebhbhbBbhbhbsbsbscfbseBbsbsbscfbsbsbsbseBbsbhbhdceLeLhtbsaLaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekekekekekekekekekekekekejaLaLaLaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaReaaRaLaLaLaRaRaRbsbhbhbjbhbnbhbhdpbhbhbhbsaWbsbhbhcwbhbhbhbibhbhbhbhbsaRaRaRaRaRbsgXbhcwbBbBbhbsbhbhbjbhbhcwbhbhbhbhbhbhbhbhbhbjbhbseLfMeLbsaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaGaNaNaLaLaRaRaRaRaRaLaLaLfUaRaRaRaRaRaRaRaRaRaLaLaRaRbsbhbhbhbhbhbhbhbhdGbhbhbsaRbsbhbhbhgPbhbhgPbhbhbhbhfcaRaXaRaRaRbsbhbhgPbhbhcwcfbhbhgPbhdGbhbhbhgPbhbhfPcwbhgPbhbhbseLeLeLbsaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftgdftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaejgeeEeWeRgfggezgeeEghejejejaGaNaNaLaRaRaRaRaRaRaLaLaLaLaLaLaLaRaRaReaaRaRaRaLaLaLbsbsbsbsbsfcaRbsbsbsbsbsbsaRbsbsbsbseBdcdcbsbsbsbsbsbsaRaRaRaRaRbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsbsaLaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekeZaaaaaaaaaaaGaGaGaGaNaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaLaRaRaRaRaRfUaLaLaRaRaRaRaRaRfcbsbsaRaRaRaRaRaRaRaRheaRaRheaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaabpaaaadfcbbVbVbVbMdsbMbVbVbVdrbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVdtbVbVbVccbQbpbpaaaaaaaaaaaGaGaGaIaUbabfbababablbabababababaaUaUaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRhgdkaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRbhbhdpbheXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXdcdceXeXeXeXeXaLaLaNaGaGaGaGaaaaaaaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaabpbpaadfcbdrbVbVbMdubMbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVbVdobVbVdrbVbVbWbVccbQbpbpbpaaaaaGaGaGaGaGaIaUbabababababababababfbabaaUaNaNaLaLaRaRaRaRaRaRaRaWaRaRaRaRaRaReXeXeXeXeXeXeXeXcfeXeXeXeXeXeXeXaRaReXeXeXeXeXeXeXeXeXeXeXeXeXaRbjbhbhbheXbhbhbhgVbhbhgVbibhbheXdvhhdvdvdvbhdveXbhbhgVbhbhbhgVbhbheXaLaNaNaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpbpdfcLbVbVbVbVbVhfbVbVbVbVbVbVbVbVbVbVbVdwbVbVbVbVbVbVbVbVbVbVbVbVcNbQbpaabpbpbpaGaGaGaGaGaIaUbmbabababfbabababaaUaUaUaUaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXbwhibwbwhibweXbheXhjbwbwbwbweXaRaReXbhdygVdybhdybhdygVdybheXaRbhbhbhbheXbhbDdzbDdAdBbDbDbDbhdCbhbhbhbhbhbhbheXdDcwdEbhbjbhdFdGbhdHaLaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpdfbMdIdJdJdJdJdJdJdJdJdJdJdKdLdLdIdJdJdJdJdJdJdJdJdJdJdJdJdJdJdKbMbQbpaaaabpaGaGaGaGaGaGaIaUbababababababmbabaaUaNaNaNaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXdMbwbwbwbwdNeXbheXdxbwbwbwbweXaRaReXbhbhbhbhbhbhbhbhbhbhbheXaRbkbhbhbheXbhbDdObsdQdRdPdTbDbheXbhbhbhbhdGbhbheXbBbhdEbhbhbhdFbhbheXaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpbpaadUdUdUdUdUdUdUdUdUdUdUdVdWdXdYdZdUdUdUdUdUdUdVdUdUdUdUdUdUdVdUdUbpcraaaabpbpbpaGaIaIaIaIaUbbbbaUaUaUaUbabmaUaUaNaNaLaLaRaRaRaRaXaRaRaRaRaReaaRaRaXaRaRaReXdMbxebbwbwdNeXgOeXecbwebbwbweXaRaReXbhdybhdybhdybhedbhdybheXaRbhbhbhbheXgXbDeedQbDbDdQefdzgOeXdvbhbhbhbhbhbheXdDbhdEbhbhcwdFbhbhdHaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaabpbpbpbpdfeheibQaaaaaaaaaaaabpbpbpbpbpbpbpbpbpbpbpbpbpaaaaaacraIaIejejejejekekejejejaUaUaUaUaNaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXdMbwbwelbwdNeXbheXdxbwbwbxbweXaRaReXgXbhbibhbhbhbhbhbhbhgOeXaRbhbhbhbheXbhbDdOdPbDbDdPdTembheXdvdvbhbhbhhkbhdCbhbhbhdGbhbhdFbhbheXaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpaaaaaaaaaaaabpbpaaaaaadfeneobQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpbpbpejejejepeqerekekekekejejejejaNaNaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXdMhlbwbwhldNeXbheXhjbwbwbwbweXaRaReXbhbhbhbhbhbCbhbhbhbhbhcfaRbhbhbnbheXbhbDeedRbDbDdRefbDbheXeXeXeXeXeXeXeXeXbhesesesesbhdFbhbhdHaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpbpbpbpbpbpbpbpaaaaaaaadfdXetbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaejekekekekekekekekekekekekejaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaXaRaRaRaReXeXeXbwbweXeXeXcfeXeXbwbweXeXeXaWaReXbheubhdybhdybhevbhdybheXhmbhbhbhbheXhnbDdOdQbDbDdSexbDgOeXbyhobybybyhobyeXbhdDhpbBdDbhgPbhbheXaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfeheybQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezekekekekekekekekekekekekejaNaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXbhbhbhbhbhbhbhbhbhbhbhbhbhbheXdkaReXgXbhbhbhbhbhbhbhbhbhgOeXaRbhdpbhbheXbhbDeedPdQbsdRefeAbheXbhbhbhbhbhbhbheXeXeXeXeXeXeBeXeXeXeXaLaNaNaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfeCdYbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeDeEeFeGekekekekekekekekekekekekejaNaNaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReXbhbheHbheXeXeXeXeXeXbhbhbhbheXdkaWeXbhdybhevbhdybhdybhdybheXaRbhbhbhbheXbhbDbDbDeIeJeKbDbDbhdCbhcwbhbhbjbhbhdCeLhqeMeNeOeOePhreLeXaLaNaNaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfdXeQbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeRekekeRekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaXaRaRaRaRaRaRaNaNaRaRaRaRaRaReXgXbhbhbhbhhshshshsbhbhbhbhgOeXdkaReXbhbhbhbhbhbhbhbhbhbhbheXaRbhbhbhbheXbhbhbhgPbhbhgPbhbhbheXbhbhbhbhbhbhbheXeLeLeLeTeUeVeLeLeLeXaLaNaNaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfendYbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeDeEeEeWekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaRaRaReXbhbhbhgPdpbibhbhbhbhgPbhbhbheXdkaReXbhbhgPbhbhbhbhbhgPbhbheXaRbhbhbhbheXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeLeLeYeLeLeVeLeLhteXaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfdXeibQaaaaaaaaaaaaaaaaaaaaaabpbpaaaaaaaaaaaaaaaaaaaaeZekekekekekekekekekekekekejaNaNaNaLaRaRaRaRaRaRaRaRbdaRaRaRaNaNaNaRaRaRaReXfaeXfaeXfaeXfaeXeXfaeXfaeXfbeXaRaXfceXeXeXeBeXeXeXeXeXeXeXeXaRbhbhcwbhfdfebhgVbBbhbheXbhbhgVbhbheXbhbhgVbhbheXffeLfgeLffeLfgeLeLeXaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaabtbtbtbtbtbtbtbtbtbtbtbtbtbtfhdLdLfibtbtbtbtbtbtaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaNaNaLaLaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaReXeXeXeXeXeXeXeXeXeXeXfceXeXeXeXaRaRfkaRaWaRaRaRaRflaRaWaRaRaRaRbhbhbhgOeXhubhbhbBfmbheXbhfnbBfmbheXbhfobBfpbheXeLeLeLfqeLeLeLfqeLeXaLaNaNaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfrfsfsfsfsfsfsfsfsfsfsfsfsfsfsftftfsfsfsfsfsfsfufvbpbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaejekekekekekekfwekekekekekejaNaLaLaPaRaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaNaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaReaaWfxfceXeXeXeXeXeBeXeXeXeXeXeXaRbjbhbhfycfbhbhbhbBbhbheXbhbhegbhbCeXbjbhbhbhbheXdcdcdceXdCeXeLfzeLeXaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBfvbpbpbpbpaaaaaaaaaaaaaaaaaaaaaaaafCekekekekekekekekekekekekejaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaNaNaRaRaRaRaRaReXeXeXeXeXeXeXeXeXeXeXeXfcdkeXfDbhbhbhbhgVbhbhbhbhbheXaRbhfEbhbhcfbhbhbhbBfmgOeXbhfnbBfmbjeXbhfobBfpbheXbhbhbhbhbhdceLeLhteXaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftfFfFfGfHfIfIbpbpbpaaaaaaaaaaaaaaaaaaaaaaeZekekekekekekfJekekekekekejaNaLaRaRaRaRaRaRaRaRaRaRaPaRaNaNaNaNaNaNaNaRaRaRaRaRaReXfKbhbhbhbhgVbhbhbhbhbheXdkeBbhbhbhbhdpcwbhbhbhbhbhddaRbhbjbhgOeXhubjbhbBbhbheXgXbhbBbhgOeXgXcwfLbhgOeXeXeXeXbhbhdceLfMeLeXaLaNaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftfNftfNfIfIfIbpbpaaaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaNaLaRaRaRaRaRaRaNaNaNaNaNaNaNaNaNaNaNaNaNaRaRaRaRaRaReXbhbhbhbhbjbhfObhbjdGbheXfleXbhbhdGbhbhbhbhbhbhcwbheXhmbhfPbhbheXfebhbhbBbhbheXbhfnbBfmbheXbhfobBfpbheXhvbheXhnbhdceLeLeLeXaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftfSftftftftftftftftftftftftftftftftftfsfsfTfHfIbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaejekekekekekekekekekekekekejaLaLaRaRaRaRaLaLaLaLaLaLaLaLaLaLaLaLaLfUaLaLaRaRaRaRaReXbhbhbhbhbhfPfVdpbhfWbhcfaReXgXbhbhbhbhbhfRbhbhbhgOeXdnbhbhbhbheBfXbhbhbBfmgOeXbhbhbhbhbheXbhbhbhbhbheXfYbhcfbhbhdceLfZeLeXaLaNaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBfvbpbpaaaaaaaaaaaaaaaaaaaaaaaaaaaafCekekekekekekekekekekekekejaLaPaRaRaLaLaLaLaRaRaRaRaRaRaRaRdnaRaRaRaLaLaLaRaRaRaReXgXdpbhbhbhbhbhbhgabhgOeBhmeXbhbhbhbhbhbhdpbhbhdGbheBaRbhbhbhbheXfebhbhbBbhbheXeXeXcfeXeBeXeXeXcfeXeXeXeXeBeXbhbhdceLeLhteXaLaNaNaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekekekekekekekekekekekekejaLaLaLaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaReaaRaLaLaLaRaRaReXbhbhbjbhbnbhbhdpbhbhbheXaWeXbhbhcwbhbhbhbibhbhbhbheXaRaRaRaRaReXgXbhcwbBbBbheXbhbhbjbhbhcwbhbhbhbhbhbhbhbhbhbjbheXeLfMeLeXaLaNaNaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafjekekekekekekekekekekekekejaGaNaNaLaLaRaRaRaRaRaLaLaLfUaRaRaRaRaRaRaRaRaRaLaLaRaReXbhbhbhbhbhbhbhbhdGbhbheXaReXbhbhbhgPbhbhgPbhbhbhbhfcaRaXaRaRaReXbhbhgPbhbhcwcfbhbhgPbhdGbhbhbhgPbhbhfPcwbhgPbhbheXeLeLeLeXaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftgdftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaejgeeEeWeRgfggezgeeEghejejejaGaNaNaLaRaRaRaRaRaRaLaLaLaLaLaLaLaRaRaReaaRaRaRaLaLaLeXeXeXeXeXfcaReXeXeXeXeXeXaReXeXeXeXeBdcdceXeXeXeXeXeXaRaRaRaRaReXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXaLaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekeZaaaaaaaaaaaGaGaGaGaNaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaLaRaRaRaRaRfUaLaLaRaRaRaRaRaRfceXeXaRaRaRaRaRaRaRaRheaRaRheaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftfSftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekeZaaaaaaaaaGaGaGaGaGaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRfUaLaLaLaRaRaReaaRaRaLaRaReaaRaLaLaLaLaLaLaLaLaRaRaLaLaLaLaLaRaRaLaLaRaRaLaRaRaRaRaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaabTgigjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgkbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagleRglaaaaaaaaaGaGaGaGaNaNaLaLaLaLaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaRaRaRaRgmaRaWaRaRfUaNaNaNaNaNaNaLaLaLaLaNaNaNaLaLaLaLaLaLaLaLaRaLaLaLaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaadUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagbgogpgqgrgogcaaaaaaaGaGaGaNaNaNaLaLaLaLaLaLfUaLaLaRaRaRaRaRaRaRaRaLaLaLaLaRaRaWeaaRaRaRaRaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaNaLaLaLaGaGaGaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index ba174a3771b..ce097d44c26 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -1,6 +1,6 @@ "aaa" = (/turf/space,/area/space) "aab" = (/obj/structure/lattice,/turf/space,/area/space) -"aac" = (/turf/simulated/floor/plating/airless,/area/space) +"aac" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "aad" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/abandoned) "aae" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/abandoned) "aaf" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"; dir = 2},/area/shuttle/abandoned) @@ -83,12 +83,12 @@ "abE" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/plating,/area/shuttle/abandoned) "abF" = (/obj/structure/spacepoddoor,/obj/machinery/door/poddoor/multi_tile/two_tile_ver{id_tag = "whiteshippoddoor"; layer = 3.1},/turf/simulated/shuttle/plating,/area/shuttle/abandoned) "abG" = (/obj/machinery/door_control{id = "whiteshippoddoor"; name = "Pod Door Control"; pixel_y = -24},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) -"abH" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) +"abH" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) "abI" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate) "abJ" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) "abK" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_mid"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_mid"; dir = 2},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) "abL" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (NORTH)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) -"abM" = (/turf/space,/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate) +"abM" = (/turf/space,/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate) "abN" = (/turf/simulated/wall/r_wall,/area/security/permabrig) "abO" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/permabrig) "abP" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/wall/r_wall,/area/security/permabrig) @@ -102,22 +102,22 @@ "abX" = (/obj/machinery/computer/shuttle/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "abY" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "abZ" = (/obj/structure/computerframe,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) -"aca" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/appleseed,/obj/item/seeds/appleseed,/obj/item/seeds/appleseed,/turf/simulated/floor/grass,/area/security/permabrig) -"acb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"acc" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/orangeseed,/obj/item/seeds/orangeseed,/obj/item/seeds/orangeseed,/turf/simulated/floor/grass,/area/security/permabrig) +"aca" = (/obj/machinery/hydroponics/soil,/obj/item/seeds/apple,/obj/item/seeds/apple,/obj/item/seeds/apple,/turf/simulated/floor/grass,/area/security/permabrig) +"acb" = (/obj/effect/decal/warning_stripes/north,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/security/podbay) +"acc" = (/obj/machinery/hydroponics/soil,/obj/item/seeds/orange,/obj/item/seeds/orange,/obj/item/seeds/orange,/turf/simulated/floor/grass,/area/security/permabrig) "acd" = (/obj/structure/table,/obj/item/weapon/storage/box/syndidonkpockets,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "ace" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acf" = (/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) -"acg" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/cornseed,/obj/item/seeds/cornseed,/obj/item/seeds/cornseed,/obj/item/device/radio/intercom/locked/prison{pixel_x = 0; pixel_y = 25},/turf/simulated/floor/grass,/area/security/permabrig) +"acg" = (/obj/machinery/hydroponics/soil,/obj/item/seeds/corn,/obj/item/seeds/corn,/obj/item/seeds/corn,/obj/item/device/radio/intercom/locked/prison{pixel_x = 0; pixel_y = 25},/turf/simulated/floor/grass,/area/security/permabrig) "ach" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "aci" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"acj" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/riceseed,/obj/item/seeds/riceseed,/obj/item/seeds/riceseed,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/grass,/area/security/permabrig) +"acj" = (/obj/machinery/hydroponics/soil,/obj/item/seeds/wheat/rice,/obj/item/seeds/wheat/rice,/obj/item/seeds/wheat/rice,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/grass,/area/security/permabrig) "ack" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 10},/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acl" = (/obj/machinery/light/spot,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acm" = (/obj/item/device/radio/intercom/syndicate{pixel_y = -28},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acn" = (/obj/structure/closet/syndicate/personal,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "aco" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/permabrig) -"acp" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/security/permabrig) +"acp" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/security/permabrig) "acq" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/syndicate) "acr" = (/obj/machinery/door/window{dir = 2; name = "Cockpit"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acs" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/syndicate) @@ -139,16 +139,16 @@ "acI" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acJ" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "acK" = (/obj/machinery/portable_atmospherics/scrubber/huge/stationary,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"acL" = (/obj/structure/table/glass,/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/plantspray/pests,/obj/item/weapon/plantspray/pests,/obj/item/weapon/plantspray/pests,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) +"acL" = (/obj/structure/table/glass,/obj/structure/table/glass,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/reagent_containers/spray/pestspray,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "acM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"acN" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/obj/structure/table/glass,/obj/item/weapon/minihoe,/obj/item/device/analyzer/plant_analyzer,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) +"acN" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/obj/structure/table/glass,/obj/item/weapon/cultivator,/obj/item/device/plant_analyzer,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "acO" = (/obj/item/weapon/soap/nanotrasen,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/permabrig) "acP" = (/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/permabrig) "acQ" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/permabrig) "acR" = (/obj/machinery/door/airlock{name = "Toilet"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/permabrig) "acS" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/permabrig) "acT" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate) -"acU" = (/obj/machinery/gun_turret,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate) +"acU" = (/obj/machinery/porta_turret/syndicate,/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate) "acV" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/security/permabrig) "acW" = (/turf/simulated/wall,/area/security/permabrig) "acX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/glass{name = "Prison Garden"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) @@ -275,8 +275,8 @@ "afo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/security/permabrig) "afp" = (/obj/machinery/flasher{id = "permaflash3"; pixel_x = 28; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "afq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area/security/permabrig) -"afr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/item/clothing/mask/gas/clown_hat,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) -"afs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"afr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/item/clothing/mask/gas/clown_hat,/turf/simulated/floor/plating/airless,/area/space) +"afs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plating/airless,/area/space) "aft" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/holofloor{dir = 10; icon_state = "red"},/area/security/permabrig) "afu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/holofloor{dir = 2; icon_state = "red"},/area/security/permabrig) "afv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/holofloor{dir = 2; icon_state = "red"},/area/security/permabrig) @@ -298,7 +298,7 @@ "afL" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Prison Gate"; name = "Prison Blast Doors"; opacity = 0},/obj/machinery/door/airlock/glass_security{name = "Prison Wing"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/permabrig) "afM" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "afN" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"afO" = (/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"afO" = (/turf/simulated/floor/plating/airless,/area/space) "afP" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "afQ" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access_txt = "150"},/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "afR" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/syndicate,/obj/item/weapon/crowbar/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) @@ -307,8 +307,8 @@ "afU" = (/obj/machinery/door/airlock/glass_security{name = "Prison 1"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "afV" = (/obj/machinery/door/airlock/glass_security{name = "Prison 2"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "afW" = (/obj/machinery/door/airlock/glass_security{name = "Prison 3"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) -"afX" = (/obj/structure/grille,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) -"afY" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"afX" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/space) +"afY" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/simulated/floor/plating/airless,/area/space) "afZ" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/vox) "aga" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access_txt = "152"},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox) "agb" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_northwest_lock"; locked = 1; req_access_txt = "152"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) @@ -412,7 +412,7 @@ "ahV" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/permabrig) "ahW" = (/obj/structure/table,/obj/item/weapon/paper,/obj/item/weapon/pen,/obj/machinery/light/small,/turf/simulated/floor/plating,/area/security/permabrig) "ahX" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior North"; dir = 4; network = list("SS13")},/turf/space,/area/security/permabrig) -"ahY" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = -32},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"ahY" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = -32},/turf/simulated/floor/plating/airless,/area/space) "ahZ" = (/obj/machinery/door/airlock/hatch{req_access_txt = "152"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "aia" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/table,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "aib" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) @@ -424,7 +424,7 @@ "aih" = (/turf/simulated/wall/r_wall,/area/security/hos) "aii" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/hos) "aij" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/hos) -"aik" = (/obj/structure/lattice{layer = 2.4},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"aik" = (/obj/structure/lattice{layer = 2.4},/turf/simulated/floor/plating/airless,/area/space) "ail" = (/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "aim" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "ain" = (/obj/machinery/camera{c_tag = "Prison Execution Chamber"; dir = 4; network = list("Prison","SS13")},/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = -1; pixel_y = -2},/obj/item/device/radio/intercom/department/security{pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) @@ -468,7 +468,7 @@ "aiZ" = (/obj/structure/stool/bed/chair/comfy/black,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "aja" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "ajb" = (/turf/simulated/wall/r_wall,/area/security/podbay) -"ajc" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"ajc" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating/airless,/area/space) "ajd" = (/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "aje" = (/obj/item/weapon/skeleton/r_arm,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "ajf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig) @@ -557,10 +557,10 @@ "akK" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "akL" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,/obj/machinery/camera{c_tag = "Brig Head of Security's Office"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "akM" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/unary/vent_pump,/obj/effect/decal/warning_stripes/yellow/hollow,/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plasteel,/area/security/podbay) -"akN" = (/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plasteel,/area/security/podbay) +"akN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/camera{c_tag = "Brig North Hallway"; dir = 2; network = list("SS13")},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "akO" = (/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/security/podbay) "akP" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plasteel,/area/security/podbay) -"akQ" = (/obj/structure/grille,/obj/structure/sign/securearea,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/space) +"akQ" = (/obj/structure/grille,/obj/structure/sign/securearea,/turf/simulated/floor/plating/airless,/area/space) "akR" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "akS" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (NORTH)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 1},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "akT" = (/obj/effect/decal/warning_stripes/northwest,/turf/simulated/floor/plasteel,/area/security/range) @@ -618,7 +618,7 @@ "alT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "alU" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "alV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) -"alW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/camera{c_tag = "Brig North Hallway"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) +"alW" = (/obj/item/device/flashlight/lamp,/obj/item/device/taperecorder{pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/interrogation) "alX" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "alY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/securehallway) "alZ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/security/securehallway) @@ -812,7 +812,7 @@ "apF" = (/turf/simulated/wall/r_wall,/area/security/medbay) "apG" = (/turf/simulated/wall,/area/security/medbay) "apH" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/interrogation) -"apI" = (/obj/structure/table/reinforced{tag = "icon-table"; icon_state = "table"},/obj/item/device/flashlight/lamp,/obj/item/device/taperecorder{pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redfull"; tag = "icon-redfull (NORTHWEST)"},/area/security/interrogation) +"apI" = (/obj/machinery/door/window/brigdoor{dir = 4; name = "Warden's Desk"; req_access_txt = "3"},/obj/machinery/door/window/westright{name = "Reception Door"; req_access = null; req_access_txt = "0"},/obj/machinery/door/firedoor,/obj/structure/table/reinforced,/turf/simulated/floor/plating,/area/security/warden) "apJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/interrogation) "apK" = (/turf/simulated/wall,/area/security/interrogationhallway) "apL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d2 = 2; icon_state = "0-2"},/obj/machinery/camera{c_tag = "Interrogation Hallway"; dir = 4; network = list("SS13")},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/interrogationhallway) @@ -908,13 +908,13 @@ "arx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{name = "Interrogation"; req_access = null; req_access_txt = "63"},/turf/simulated/floor/plasteel,/area/security/interrogation) "ary" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area/security/interrogationhallway) "arz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/interrogationhallway) -"arA" = (/obj/structure/table/reinforced{tag = "icon-table_vertical"; icon_state = "table_vertical"},/obj/machinery/door/window/brigdoor{dir = 4; name = "Warden's Desk"; req_access_txt = "3"},/obj/machinery/door/window/westright{name = "Reception Door"; req_access = null; req_access_txt = "0"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/security/warden) +"arA" = (/obj/machinery/door/window/brigdoor/southleft{dir = 4; req_access_txt = "63"},/obj/machinery/door/window/brigdoor{dir = 8; name = "Warden's Desk"; req_access_txt = "3"},/obj/machinery/door/firedoor,/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "arB" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "arC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "arD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "arE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "arF" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) -"arG" = (/obj/structure/table/reinforced{tag = "icon-table"; icon_state = "table"},/obj/machinery/door/window/brigdoor/southleft{dir = 4; req_access_txt = "63"},/obj/machinery/door/window/brigdoor{dir = 8; name = "Warden's Desk"; req_access_txt = "3"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) +"arG" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "1"},/turf/simulated/floor/plasteel,/area/security/range) "arH" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/seceqstorage) "arI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/recharger/wallcharger{pixel_y = 25},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/recharger/wallcharger{pixel_y = 35},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/seceqstorage) "arJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/security/seceqstorage) @@ -984,9 +984,9 @@ "asV" = (/obj/structure/grille,/obj/structure/window/full/shuttle{dir = 10; icon_state = "9"},/turf/simulated/floor/plating,/area/shuttle/siberia) "asW" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "window8"},/turf/simulated/floor/plating,/area/shuttle/siberia) "asX" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/siberia) -"asY" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "1"},/turf/simulated/floor/plasteel,/area/security/range) +"asY" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "1"},/turf/simulated/floor/plasteel,/area/security/range) "asZ" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/security/range) -"ata" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "1"},/turf/simulated/floor/plasteel,/area/security/range) +"ata" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 4; pixel_y = 0},/obj/item/device/radio/intercom/department/security{pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prisonershuttle) "atb" = (/obj/structure/closet/secure_closet/brigdoc,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/security/medbay) "atc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay) "atd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/medbay) @@ -1261,7 +1261,7 @@ "aym" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/shuttle/siberia) "ayn" = (/obj/machinery/door/airlock/shuttle{id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock"; req_access_txt = "0"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 5; id = "laborcamp"; name = "labor camp shuttle"; rebuildable = 1; width = 9},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 5; id = "laborcamp_home"; name = "fore bay 1"; width = 9},/turf/simulated/shuttle/floor,/area/shuttle/siberia) "ayo" = (/obj/machinery/light,/turf/simulated/floor/plating,/area/security/prisonershuttle) -"ayp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 4; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prisonershuttle) +"ayp" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/window/brigdoor/southleft{req_access_txt = "63"},/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/security/lobby) "ayq" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/courtroomdandp) "ayr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel,/area/security/courtroomdandp) "ays" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel,/area/security/courtroomdandp) @@ -1334,7 +1334,7 @@ "azH" = (/obj/structure/stool/bed,/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/prison/cell_block/A) "azI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/lobby) "azJ" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/security/lobby) -"azK" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/table/reinforced{tag = "icon-table"; icon_state = "table"},/obj/machinery/door/window/brigdoor/southleft{req_access_txt = "63"},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/security/lobby) +"azK" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "azL" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plating,/area/security/lobby) "azM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/wall,/area/security/processing) "azN" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/security/processing) @@ -1584,8 +1584,8 @@ "aEx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/security/prison/cell_block/A) "aEy" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/security/lobby) "aEz" = (/obj/structure/disposalpipe/segment,/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/security/lobby) -"aEA" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/security/lobby) -"aEB" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor,/area/security/lobby) +"aEA" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aEB" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/security/lobby) "aEC" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Security Lobby"; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/security/lobby) "aED" = (/obj/machinery/light_switch{pixel_x = -25},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/evidence) "aEE" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/closet{name = "Evidence Closet"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/evidence) @@ -1960,9 +1960,9 @@ "aLJ" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "aLK" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "aLL" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aLM" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aLM" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aLN" = (/obj/machinery/cryopod,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) -"aLO" = (/obj/structure/cryofeed,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aLO" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aLP" = (/turf/simulated/wall,/area/crew_quarters/sleep) "aLQ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 9},/area/crew_quarters/fitness) "aLR" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness) @@ -1983,7 +1983,7 @@ "aMg" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "station intercom (General)"; pixel_y = 25},/obj/structure/closet/lasertag/blue,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aMh" = (/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/disposal,/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aMi" = (/obj/machinery/door/airlock/external{frequency = 1450; icon_state = "door_locked"; id_tag = "bar_maint_inner"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aMj" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) +"aMj" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aMk" = (/obj/structure/table,/obj/effect/spawner/lootdrop/maintenance{lootcount = 3; name = "3maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aMm" = (/obj/structure/door_assembly/door_assembly_mai,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -1996,7 +1996,7 @@ "aMt" = (/obj/structure/stool/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/shuttle/floor,/area/shuttle/pod_1) "aMu" = (/obj/structure/stool/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/shuttle/floor,/area/shuttle/pod_2) "aMv" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "arrivals_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"aMw" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aMw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aMx" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aMy" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aMz" = (/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -2019,7 +2019,7 @@ "aMQ" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "aMR" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "aMS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/sleep) -"aMT" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aMT" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aMU" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aMV" = (/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aMW" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) @@ -2060,9 +2060,9 @@ "aNF" = (/obj/structure/closet,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aNG" = (/obj/structure/grille,/obj/structure/window/basic,/obj/structure/window/basic{dir = 1},/obj/structure/window/basic{dir = 8},/obj/structure/window/basic{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aNH" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) -"aNI" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) +"aNI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32},/turf/space,/area/space) "aNJ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless/catwalk,/area/maintenance/fpmaint) -"aNK" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/maintenance/fpmaint) +"aNK" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/fpmaint) "aNL" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eva_pump"},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aNM" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eva_airlock"; name = "EVA Airlock Console"; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"; tag_airpump = "eva_pump"; tag_chamber_sensor = "eva_sensor"; tag_exterior_door = "eva_outer"; tag_interior_door = "eva_inner"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "aNN" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_inner"; locked = 1; name = "EVA Internal Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fpmaint) @@ -2091,7 +2091,7 @@ "aOk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/hallway/primary/fore) "aOl" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aOm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/sleep) -"aOn" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = -28},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aOn" = (/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aOo" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aOp" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aOq" = (/obj/structure/window/reinforced{dir = 8},/obj/effect/landmark/start{name = "Civilian"},/obj/machinery/door/window/westright{dir = 1; name = "Boxing Ring"},/turf/simulated/floor/wood,/area/crew_quarters/fitness) @@ -2103,8 +2103,8 @@ "aOw" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/crew_quarters/fitness) "aOx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aOy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness) -"aOz" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) -"aOA" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aOz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aOA" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aOB" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "station intercom (General)"; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aOC" = (/obj/machinery/camera{c_tag = "Holodeck"; network = list("SS13")},/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aOD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/fitness) @@ -2179,8 +2179,8 @@ "aPU" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 1; name = "north bump Engineering"; pixel_x = 0; pixel_y = 24; shock_proof = 1},/turf/simulated/floor/plating,/area/maintenance/electrical) "aPV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/electrical) "aPW" = (/obj/structure/table,/obj/item/clothing/gloves/color/fyellow,/obj/item/weapon/storage/toolbox/electrical,/obj/item/device/multitool,/obj/item/device/radio/intercom{pixel_x = 25},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/electrical) -"aPX" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) -"aPY" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"aPX" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"aPY" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) "aPZ" = (/obj/machinery/door/airlock/external{name = "Escape Pod"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "aQa" = (/obj/structure/sign/pods,/turf/simulated/wall,/area/hallway/secondary/entry) "aQb" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -2210,7 +2210,7 @@ "aQz" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/fore) "aQA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/hallway/primary/fore) "aQB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aQC" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aQC" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aQD" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aQE" = (/obj/structure/table/woodentable,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aQF" = (/obj/structure/table/woodentable,/obj/item/toy/cards/deck,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) @@ -2279,8 +2279,8 @@ "aRQ" = (/obj/structure/window/reinforced,/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/crew_quarters/fitness) "aRR" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/crew_quarters/fitness) "aRS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness) -"aRT" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) -"aRU" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aRT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) +"aRU" = (/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/hallway/secondary/entry) "aRV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light/small,/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aRW" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aRX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -2298,7 +2298,7 @@ "aSj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "aSk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 2},/area/hallway/secondary/entry) "aSl" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) -"aSm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) +"aSm" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry) "aSn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry) "aSo" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry) "aSp" = (/obj/structure/closet/wardrobe/white,/obj/item/clothing/shoes/jackboots,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/food/drinks/cans/badminbrew,/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -2328,8 +2328,8 @@ "aSN" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore) "aSO" = (/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/fore) "aSP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aSQ" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) -"aSR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aSQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aSR" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aSS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/crew_quarters/sleep) "aST" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aSU" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) @@ -2351,7 +2351,7 @@ "aTk" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plating,/area/maintenance/electrical) "aTl" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plating,/area/maintenance/electrical) "aTm" = (/obj/machinery/power/terminal,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/electrical) -"aTn" = (/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"aTn" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry) "aTo" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry) "aTp" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/entry) "aTq" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry) @@ -2402,15 +2402,15 @@ "aUj" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/computer/monitor{name = "Backup Power Monitoring Console"},/turf/simulated/floor/plating,/area/maintenance/electrical) "aUk" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes{charge = 0},/turf/simulated/floor/plating,/area/maintenance/electrical) "aUl" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/hallway/secondary/entry) -"aUm" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"aUm" = (/obj/machinery/door/firedoor,/obj/machinery/door/window/brigdoor{dir = 1; name = "Security Checkpoint"; req_access_txt = "1"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/security/checkpoint2) "aUn" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry) "aUo" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) "aUp" = (/obj/machinery/camera{c_tag = "Arrivals North"; dir = 1},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry) "aUq" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/hallway/secondary/entry) -"aUr" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) -"aUs" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry) -"aUt" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry) -"aUu" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) +"aUr" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/security/checkpoint2) +"aUs" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) +"aUt" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"aUu" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUv" = (/obj/machinery/light{dir = 1},/obj/structure/sink{pixel_y = 30},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aUx" = (/obj/machinery/seed_extractor,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) @@ -2447,7 +2447,7 @@ "aVc" = (/turf/simulated/wall,/area/security/checkpoint2) "aVd" = (/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) "aVe" = (/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) -"aVf" = (/obj/structure/table/glass,/obj/item/seeds/appleseed,/obj/item/seeds/bananaseed,/obj/item/seeds/cocoapodseed,/obj/item/seeds/grapeseed,/obj/item/seeds/orangeseed,/obj/item/seeds/sugarcaneseed,/obj/item/seeds/wheatseed,/obj/item/seeds/watermelonseed,/obj/item/seeds/towermycelium,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) +"aVf" = (/obj/structure/table/glass,/obj/item/seeds/apple,/obj/item/seeds/banana,/obj/item/seeds/cocoapod,/obj/item/seeds/grape,/obj/item/seeds/orange,/obj/item/seeds/sugarcane,/obj/item/seeds/wheat,/obj/item/seeds/watermelon,/obj/item/seeds/tower,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aVg" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/storage/primary) "aVh" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "aVi" = (/turf/simulated/wall,/area/storage/primary) @@ -2467,7 +2467,7 @@ "aVw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/camera{c_tag = "EVA East"; dir = 8; network = list("SS13")},/obj/structure/table/reinforced,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aVx" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) "aVy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"aVz" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) +"aVz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/cryopod,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aVA" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aVB" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aVC" = (/obj/structure/urinal{pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/toilet) @@ -2658,8 +2658,8 @@ "aZf" = (/obj/structure/table/reinforced,/obj/machinery/computer/skills,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/checkpoint2) "aZg" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/checkpoint2) "aZh" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/checkpoint2) -"aZi" = (/obj/item/device/radio,/obj/item/device/radio/intercom/department/security{pixel_x = 0; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 6},/area/security/checkpoint2) -"aZj" = (/obj/machinery/light/small{dir = 8},/obj/structure/table/glass,/obj/item/weapon/minihoe,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) +"aZi" = (/obj/item/device/radio,/obj/item/device/radio/intercom/department/security{pixel_x = 0; pixel_y = -28},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 6},/area/security/checkpoint2) +"aZj" = (/obj/machinery/light/small{dir = 8},/obj/structure/table/glass,/obj/item/weapon/cultivator,/obj/item/weapon/hatchet,/obj/item/weapon/crowbar,/obj/item/device/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aZk" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aZl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "aZm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) @@ -2757,12 +2757,12 @@ "bba" = (/obj/effect/landmark{name = "Observer-Start"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "bbb" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/entry) "bbc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/security{name = "Security Checkpoint"; req_access = null; req_access_txt = "1"},/turf/simulated/floor/plasteel,/area/security/checkpoint2) -"bbd" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/security/checkpoint2) -"bbe" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Security Checkpoint"; req_access_txt = "1"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/security/checkpoint2) +"bbd" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "neutralcorner"; dir = 2},/area/hallway/secondary/entry) +"bbe" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) "bbf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/maintenance/fpmaint2) "bbg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "bbh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) -"bbi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/table/glass,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/plantspray/pests,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/rh,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) +"bbi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/table/glass,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) "bbj" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor/plasteel,/area/storage/primary) "bbk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/storage/primary) "bbl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plasteel,/area/storage/primary) @@ -2847,7 +2847,7 @@ "bcM" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/shuttle/arrival/station) "bcN" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "bcO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"bcP" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) +"bcP" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/hallway/primary/port) "bcQ" = (/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/entry) "bcR" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/entry) "bcS" = (/turf/simulated/floor/plasteel{icon_state = "bot"},/area/hallway/secondary/entry) @@ -2856,9 +2856,9 @@ "bcV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/sign/double/map/left{pixel_y = 31},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bcW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/sign/double/map/right{pixel_y = 31},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bcX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/hallway/secondary/construction{name = "\improper Garden"}) -"bcY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/table/glass,/obj/item/weapon/hatchet,/obj/item/weapon/minihoe,/obj/item/weapon/crowbar,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) +"bcY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/table/glass,/obj/item/weapon/hatchet,/obj/item/weapon/cultivator,/obj/item/weapon/crowbar,/obj/item/device/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"}) "bcZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) -"bda" = (/obj/structure/table/glass,/obj/item/weapon/storage/bag/plants/portaseeder,/obj/item/device/analyzer/plant_analyzer,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -6; pixel_y = -25},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) +"bda" = (/obj/structure/table/glass,/obj/item/weapon/storage/bag/plants/portaseeder,/obj/item/device/plant_analyzer,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -6; pixel_y = -25},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"}) "bdb" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/item/device/analyzer,/turf/simulated/floor/plasteel,/area/storage/primary) "bdc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/storage/primary) "bdd" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/storage/primary) @@ -2869,7 +2869,7 @@ "bdi" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/storage/primary) "bdj" = (/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 8; location = "Tool Storage"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/storage/primary) "bdk" = (/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/turf/simulated/floor/plasteel,/area/storage/primary) -"bdl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"bdl" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable,/turf/simulated/floor/plating,/area/hallway/primary/port) "bdm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/hallway/primary/port) "bdn" = (/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel,/area/gateway) "bdo" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/door_control{id = "stationawaygate"; name = "Gateway Shutters Access Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "62"},/turf/simulated/floor/plasteel,/area/gateway) @@ -2947,7 +2947,7 @@ "beI" = (/obj/machinery/requests_console{department = "Arrival Shuttle"; name = "Arrival Shuttle Requests Console"; pixel_y = -30},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "beJ" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 8},/turf/space,/area/shuttle/arrival/station) "beK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"beL" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/turf/simulated/floor/plasteel{icon_state = "neutralcorner"; dir = 2},/area/hallway/secondary/entry) +"beL" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) "beM" = (/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/hallway/secondary/entry) "beN" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/hallway/secondary/entry) "beO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralcorner"},/area/hallway/secondary/entry) @@ -2957,15 +2957,15 @@ "beS" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Primary Tool Storage"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/storage/primary) "beT" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Primary Tool Storage"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/storage/primary) "beU" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/storage/primary) -"beV" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/hallway/primary/port) -"beW" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) -"beX" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 4; icon_state = "0-4"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable,/turf/simulated/floor/plating,/area/hallway/primary/port) +"beV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Gateway Access"; req_access_txt = "62"},/turf/simulated/floor/plasteel,/area/gateway) +"beW" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor/plasteel,/area/gateway) +"beX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor/plasteel,/area/gateway) "beY" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/hallway/primary/port) -"beZ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"beZ" = (/obj/machinery/door/firedoor,/obj/machinery/light{dir = 1},/obj/structure/sign/directions/evac{dir = 4; icon_state = "direction_evac"; pixel_y = 24; tag = "icon-direction_evac (EAST)"},/obj/structure/sign/directions/medical{dir = 4; icon_state = "direction_med"; pixel_y = 32; tag = "icon-direction_med (EAST)"},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bfa" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/fpmaint) -"bfb" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Gateway Access"; req_access_txt = "62"},/turf/simulated/floor/plasteel,/area/gateway) -"bfc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor/plasteel,/area/gateway) -"bfd" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "stationawaygate"; name = "Gateway Access Shutters"},/turf/simulated/floor/plasteel,/area/gateway) +"bfb" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bfc" = (/obj/machinery/light{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 8},/area/hallway/primary/port) +"bfd" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bfe" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/gateway) "bff" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fpmaint) "bfg" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) @@ -2994,13 +2994,13 @@ "bfD" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bfE" = (/mob/living/simple_animal/hostile/retaliate/goat,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bfF" = (/obj/machinery/door/window/eastright{tag = "icon-right"; name = "Hydroponics Delivery"; icon_state = "right"; dir = 2; req_access_txt = "35"},/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) -"bfG" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/machinery/alarm{pixel_y = 22},/obj/machinery/camera{c_tag = "Hydroponics Pasture"; network = list("SS13")},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) -"bfH" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) -"bfI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/grass,/area/hydroponics) -"bfJ" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) -"bfK" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) -"bfL" = (/obj/machinery/atmospherics/binary/valve{dir = 4},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) -"bfM" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/visible{dir = 10},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) +"bfG" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/machinery/alarm{pixel_y = 22},/obj/machinery/camera{c_tag = "Hydroponics Pasture"; network = list("SS13")},/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) +"bfH" = (/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) +"bfI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/hydroponics/soil,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/grass,/area/hydroponics) +"bfJ" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) +"bfK" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) +"bfL" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) +"bfM" = (/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bfN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/closet/secure_closet/hydroponics,/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bfO" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/closet/secure_closet/hydroponics,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bfP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/closet/secure_closet/hydroponics,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) @@ -3037,8 +3037,8 @@ "bgu" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry) "bgv" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/secondary/entry) "bgw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/secondary/entry) -"bgx" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/light{dir = 1},/obj/structure/sign/directions/evac{dir = 4; icon_state = "direction_evac"; pixel_y = 24; tag = "icon-direction_evac (EAST)"},/obj/structure/sign/directions/medical{dir = 4; icon_state = "direction_med"; pixel_y = 32; tag = "icon-direction_med (EAST)"},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"bgy" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bgx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"bgy" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bgz" = (/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgA" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgB" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3046,7 +3046,7 @@ "bgD" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgF" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/port) -"bgG" = (/obj/machinery/light{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 8},/area/hallway/primary/port) +"bgG" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgH" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/primary/port) "bgI" = (/obj/machinery/camera{c_tag = "Port Hallway 2"; dir = 2},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/primary/port) "bgJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/primary/port) @@ -3055,9 +3055,9 @@ "bgM" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgN" = (/obj/machinery/light{dir = 1},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bgO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/port) -"bgP" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bgP" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bgQ" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) -"bgR" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) +"bgR" = (/obj/structure/closet/emcloset,/obj/machinery/light{dir = 1; on = 1},/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bgS" = (/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bgT" = (/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = 30},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bgU" = (/obj/machinery/camera{c_tag = "Central Hallway North-West"; dir = 2; network = list("SS13")},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) @@ -3103,8 +3103,8 @@ "bhI" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "asteroid"; tag = "icon-asteroid (NORTH)"},/turf/simulated/floor/plasteel{tag = "icon-siding2 (NORTH)"; icon_state = "siding2"; dir = 1},/turf/simulated/floor/plasteel{tag = "icon-siding1 (NORTH)"; icon_state = "siding1"; dir = 1},/area/hydroponics) "bhJ" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Hydroponics Pasture"; req_access_txt = "35"},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bhK" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) -"bhL" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/visible{dir = 5},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) -"bhM" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) +"bhL" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) +"bhM" = (/obj/machinery/light{dir = 1},/obj/structure/reagent_dispensers/watertank/high,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bhN" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = -31},/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bhO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bhP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) @@ -3132,7 +3132,7 @@ "bil" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/escape) "bim" = (/obj/machinery/light/spot,/turf/simulated/shuttle/floor,/area/shuttle/escape) "bin" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/escape) -"bio" = (/obj/machinery/door/firedoor{dir = 2},/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"bio" = (/obj/structure/reagent_dispensers/water_cooler,/obj/machinery/camera{c_tag = "Departure Lounge Security"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bip" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/device/radio/intercom{dir = 0; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry) "biq" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bir" = (/obj/structure/table/woodentable,/obj/item/toy/cards/deck,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry) @@ -3141,7 +3141,7 @@ "biu" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 8},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry) "biv" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/secondary/entry) "biw" = (/turf/simulated/floor/plasteel{desc = "\"This is a plaque in honour of our comrades on the G4407 Stations. Hopefully TG4407 model can live up to your fame and fortune.\" Scratched in beneath that is a crude image of a meteor and a spaceman. The spaceman is laughing. The meteor is exploding."; dir = 4; icon_state = "plaque"; name = "Comemmorative Plaque"},/area/hallway/secondary/entry) -"bix" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) +"bix" = (/obj/structure/closet/emcloset,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/effect/decal/warning_stripes/east,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "biy" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=CHW"; location = "Lockers"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biz" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3152,7 +3152,7 @@ "biF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biH" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) -"biI" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"biI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biK" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "biL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3196,7 +3196,7 @@ "bjx" = (/mob/living/simple_animal/cow{name = "Betsy"},/turf/simulated/floor/grass,/area/hydroponics) "bjy" = (/obj/structure/flora/ausbushes/sparsegrass,/turf/simulated/floor/grass,/area/hydroponics) "bjz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/hydroponics) -"bjA" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/hydroponics) +"bjA" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/seed_extractor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bjB" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hydroponics) "bjC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access_txt = "35"},/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bjD" = (/obj/machinery/bookbinder{pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/wood,/area/library) @@ -3211,8 +3211,8 @@ "bjM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bjN" = (/obj/machinery/computer/arcade,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bjO" = (/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bjP" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/machinery/light{dir = 1; on = 1},/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bjQ" = (/obj/structure/closet/emcloset,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/effect/decal/warning_stripes/northeast,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bjP" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bjQ" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bjR" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bjS" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape) "bjT" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/escape) @@ -3235,7 +3235,7 @@ "bkk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/junction{tag = "icon-pipe-j1 (EAST)"; icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bkl" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bkm" = (/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2 (EAST)"; icon_state = "pipe-j2"; dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/port) -"bkn" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bkn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bko" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bkp" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/camera{c_tag = "Port Hallway"; dir = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bkq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3243,9 +3243,9 @@ "bks" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bkt" = (/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel,/area/hallway/primary/port) "bku" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/port) -"bkv" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/port) +"bkv" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "bkw" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) -"bkx" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) +"bkx" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "bky" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bkz" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=QM"; location = "CHW"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/nw) "bkA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/nw) @@ -3270,12 +3270,12 @@ "bkT" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/freezer{req_access_txt = "28"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bkU" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "hydrofloor"},/area/hydroponics) "bkV" = (/turf/simulated/floor/grass,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/hydroponics) -"bkW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/flora/ausbushes/fullgrass,/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) -"bkX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/portable_atmospherics/hydroponics/soil,/mob/living/simple_animal/chicken{name = "Commander Clucky"},/turf/simulated/floor/grass,/area/hydroponics) -"bkY" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/grass,/area/hydroponics) -"bkZ" = (/obj/machinery/botany/editor,/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) -"bla" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/requests_console{department = "Hydroponics"; departmentType = 2; name = "Hydroponics Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/botany/extractor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) -"blb" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/seed_extractor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bkW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/flora/ausbushes/fullgrass,/obj/machinery/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics) +"bkX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/hydroponics/soil,/mob/living/simple_animal/chicken{name = "Commander Clucky"},/turf/simulated/floor/grass,/area/hydroponics) +"bkY" = (/obj/machinery/hydroponics/soil,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/grass,/area/hydroponics) +"bkZ" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bla" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment,/obj/machinery/requests_console{department = "Hydroponics"; departmentType = 2; name = "Hydroponics Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/plantgenes,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"blb" = (/obj/structure/reagent_dispensers/watertank/high,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "blc" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bld" = (/obj/machinery/camera{c_tag = "Hydroponics North"; network = list("SS13")},/obj/machinery/vending/hydroseeds,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "ble" = (/obj/machinery/biogenerator,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) @@ -3298,7 +3298,7 @@ "blv" = (/obj/machinery/light{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "blw" = (/obj/structure/sign/poster/legit{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "blx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bly" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bly" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "neutralcorner"; dir = 4},/area/hallway/secondary/entry) "blz" = (/obj/effect/decal/warning_stripes/east,/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "blA" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) "blB" = (/obj/machinery/status_display{pixel_y = 30},/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape) @@ -3313,8 +3313,8 @@ "blK" = (/turf/simulated/wall,/area/hallway/primary/port) "blL" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/port) "blM" = (/turf/simulated/wall,/area/crew_quarters/locker) -"blN" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) -"blO" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) +"blN" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"blO" = (/obj/effect/decal/warning_stripes/northeastcorner,/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "blP" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/port) "blQ" = (/turf/simulated/wall,/area/maintenance/port) "blR" = (/turf/simulated/wall,/area/storage/emergency2) @@ -3354,7 +3354,7 @@ "bmz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "bmA" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bmB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "green"},/area/hydroponics) -"bmC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/hydroponics) +"bmC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/reagent_dispensers/watertank/high,/turf/simulated/floor/plasteel,/area/atmos) "bmD" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/hydroponics) "bmE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 5; icon_state = "green"},/area/hydroponics) "bmF" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/floodlight,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) @@ -3377,11 +3377,11 @@ "bmW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bmX" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor4,/area/shuttle/escape) "bmY" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor4,/area/shuttle/escape) -"bmZ" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bmZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bna" = (/obj/machinery/status_display{pixel_y = 30},/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor4,/area/shuttle/escape) "bnb" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "8"},/turf/simulated/floor/plating,/area/shuttle/escape) "bnc" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) -"bnd" = (/obj/machinery/door/firedoor{dir = 2},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"bnd" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bne" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry) "bnf" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry) "bng" = (/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry) @@ -3392,7 +3392,7 @@ "bnl" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry) "bnm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry) "bnn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"bno" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "neutralcorner"; dir = 4},/area/hallway/secondary/entry) +"bno" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{pixel_x = 32},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "bnp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/secondary/entry) "bnq" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/secondary/entry) "bnr" = (/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/secondary/entry) @@ -3453,13 +3453,13 @@ "bou" = (/obj/structure/table,/obj/machinery/kitchen_machine/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bov" = (/obj/machinery/cooker/deepfryer,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bow" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/kitchen_machine/oven,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"box" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"box" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/window/eastleft{name = "Hydroponics Desk"; req_access_txt = "35"},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Kitchen Desk"; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/hydroponics) "boy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) -"boz" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/hydroponics) -"boA" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel,/area/hydroponics) +"boz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"boA" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel,/area/hydroponics) "boB" = (/turf/simulated/floor/plasteel,/area/hydroponics) "boC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) -"boD" = (/obj/machinery/newscaster{pixel_x = 27; pixel_y = 1},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"boD" = (/obj/machinery/newscaster{pixel_x = 27; pixel_y = 1},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "boE" = (/obj/structure/bookcase{name = "bookcase (Fiction)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/wood,/area/library) "boF" = (/obj/structure/bookcase{name = "bookcase (Fiction)"},/turf/simulated/floor/wood,/area/library) "boG" = (/obj/structure/bookcase{name = "bookcase (Non-Fiction)"},/turf/simulated/floor/wood,/area/library) @@ -3475,7 +3475,7 @@ "boQ" = (/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "arrival"},/area/hallway/secondary/entry) "boR" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/hallway/secondary/entry) "boS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"boT" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) +"boT" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "boU" = (/obj/structure/sign/poster/legit{pixel_y = -32},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "boV" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) "boW" = (/obj/machinery/firealarm{dir = 2; pixel_y = -24},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) @@ -3534,7 +3534,7 @@ "bpX" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/hydroponics) "bpY" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) "bpZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) -"bqa" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bqa" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bqb" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 8; icon_state = "right"; name = "Library Desk Door"; req_access_txt = "37"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/library) "bqc" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/wood,/area/library) "bqd" = (/obj/structure/table/woodentable,/obj/machinery/computer/library/checkout{pixel_y = 0},/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/wood,/area/library) @@ -3549,8 +3549,8 @@ "bqm" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bqn" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bqo" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "15"},/turf/simulated/floor/plating,/area/shuttle/escape) -"bqp" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) -"bqq" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{pixel_x = 32},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) +"bqp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bqq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bqr" = (/turf/simulated/wall,/area/security/vacantoffice) "bqs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/vacantoffice) "bqt" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/port) @@ -3602,11 +3602,11 @@ "brn" = (/obj/structure/table,/obj/item/weapon/kitchen/rollingpin,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bro" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "brp" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"brq" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/window/eastleft{name = "Hydroponics Desk"; req_access_txt = "35"},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Kitchen Desk"; req_access_txt = "28"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/hydroponics) +"brq" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "brr" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) "brs" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/hydroponics) "brt" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/hydroponics) -"bru" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bru" = (/obj/machinery/hydroponics/constructable,/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "brv" = (/obj/structure/bookcase{name = "bookcase (Adult)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/wood,/area/library) "brw" = (/obj/structure/bookcase{name = "bookcase (Adult)"},/turf/simulated/floor/wood,/area/library) "brx" = (/obj/machinery/computer/library/public,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/library) @@ -3689,10 +3689,10 @@ "bsW" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "bsX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bsY" = (/obj/machinery/processor,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"bsZ" = (/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) -"bta" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "green"; dir = 8},/area/hydroponics) -"btb" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor/plasteel,/area/hydroponics) -"btc" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bsZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bta" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"btb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/exit) +"btc" = (/obj/machinery/hydroponics/constructable,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "btd" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bte" = (/turf/simulated/wall,/area/hallway/primary/starboard/east) "btf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/library) @@ -3711,7 +3711,7 @@ "bts" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/stool,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{icon_state = "chapel"},/area/chapel/main) "btt" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/camera{c_tag = "Chapel South"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "btu" = (/obj/item/device/radio/intercom{pixel_x = -25},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera{c_tag = "Departure Lounge West"; dir = 4; network = list("SS13")},/obj/machinery/vending/cola,/turf/simulated/floor/plasteel{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) -"btv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"btv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "btw" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "btx" = (/obj/item/flag/nt,/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bty" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) @@ -3783,8 +3783,8 @@ "buM" = (/obj/structure/table/woodentable,/obj/item/weapon/kitchen/utensil/fork,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/wood,/area/crew_quarters/bar) "buN" = (/obj/effect/landmark/start{name = "Chef"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "buO" = (/obj/structure/table,/obj/machinery/reagentgrinder,/obj/machinery/requests_console{department = "Kitchen"; name = "Kitchen Requests Console"; departmentType = 2; pixel_x = 30; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"buP" = (/obj/machinery/light{dir = 8},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) -"buQ" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"buP" = (/obj/machinery/light{dir = 8},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"buQ" = (/obj/machinery/hydroponics/constructable,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "buR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j2s"; sortType = 16},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "buS" = (/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/hallway/primary/starboard/east) "buT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/sign/poster/legit{pixel_y = 32},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) @@ -3865,7 +3865,7 @@ "bwq" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bwr" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bws" = (/obj/machinery/disposal,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"bwt" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bwt" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) "bwu" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/camera{c_tag = "Starboard Primary Hallway 4"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bwv" = (/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bww" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) @@ -3934,7 +3934,7 @@ "bxH" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/fancy/donut_box,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "kitchenhall"; name = "Kitchen Shutters"; opacity = 0},/obj/machinery/door/window/westleft{dir = 1; name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bxI" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "kitchenhall"; name = "Kitchen Shutters"; opacity = 0},/obj/machinery/door/window/westright{dir = 1; name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) "bxJ" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "kitchenhall"; name = "Kitchen Shutters"; opacity = 0},/obj/machinery/door/window/westleft{dir = 1; name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) -"bxK" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) +"bxK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bxL" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Botanist"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/hydroponics) "bxM" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "green"},/area/hydroponics) "bxN" = (/obj/machinery/camera{c_tag = "Hydroponics South"; dir = 8; network = list("SS13")},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hydroponics) @@ -4015,7 +4015,7 @@ "bzk" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access_txt = "35"},/turf/simulated/floor/plasteel,/area/hydroponics) "bzl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bzm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) -"bzn" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bzn" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bzo" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/extinguisher,/obj/item/weapon/crowbar,/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) "bzp" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bzq" = (/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel,/area/hallway/secondary/entry) @@ -4087,10 +4087,10 @@ "bAE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bAF" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/machinery/camera{c_tag = "Starboard Primary Hallway 6"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bAG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) -"bAH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/exit) +"bAH" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bAI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/hallway/secondary/exit) "bAJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bAK" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bAK" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/hallway/secondary/exit) "bAL" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bAM" = (/obj/effect/decal/warning_stripes/northeastsouth,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bAN" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/hallway/secondary/exit) @@ -4146,7 +4146,7 @@ "bBL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bBM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bBN" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=HOP2"; location = "Stbd"},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) -"bBO" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bBO" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bBP" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bBQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "bBR" = (/obj/structure/grille,/obj/structure/window/full/shuttle{icon_state = "14"},/turf/simulated/floor/plating,/area/shuttle/escape) @@ -4224,17 +4224,17 @@ "bDl" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/camera{c_tag = "Starboard Primary Hallway 5"; dir = 1; network = list("SS13")},/obj/item/device/radio/intercom{pixel_y = -28},/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "bDm" = (/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "purple"},/area/hallway/primary/starboard/east) "bDn" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "purple"},/area/hallway/primary/starboard/east) -"bDo" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/hallway/secondary/exit) +"bDo" = (/obj/machinery/door/firedoor,/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Mailing Room"; req_access_txt = "50"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office) "bDp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bDq" = (/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bDr" = (/obj/machinery/newscaster{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bDs" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) -"bDt" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/machinery/light,/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bDu" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bDt" = (/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/research{name = "Mech Bay"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/assembly/chargebay) +"bDu" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "mechbay"; name = "Mech Bay"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/chargebay) "bDv" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = "s_docking_airlock"; name = "Shuttle Hatch"},/turf/simulated/shuttle/floor4,/area/shuttle/escape) "bDw" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) "bDx" = (/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Escape Shuttle Infirmary"; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) -"bDy" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bDy" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) "bDz" = (/turf/simulated/shuttle/floor4,/area/shuttle/escape) "bDA" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops) "bDB" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "109"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 11; id = "specops"; name = "ert shuttle"; roundstart_move = "specops_away"; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "specops_home"; name = "port bay 2"; width = 5},/turf/simulated/shuttle/plating,/area/shuttle/specops) @@ -4295,8 +4295,8 @@ "bEE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bEF" = (/turf/simulated/wall,/area/hallway/secondary/exit) "bEG" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/exit) -"bEH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) -"bEI" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) +"bEH" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/white,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) +"bEI" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) "bEJ" = (/turf/simulated/shuttle/wall{tag = "icon-swall7"; icon_state = "swall7"; dir = 2},/area/shuttle/escape) "bEK" = (/obj/machinery/computer/communications,/obj/item/device/radio/intercom/specops{pixel_y = -28},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops) "bEL" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops) @@ -4332,7 +4332,7 @@ "bFp" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bFq" = (/obj/structure/stool/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Cargo Technician"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bFr" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 4},/area/quartermaster/office) -"bFs" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Mailing Room"; req_access_txt = "50"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office) +"bFs" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) "bFt" = (/obj/machinery/camera{c_tag = "Central Hallway West"; dir = 8; network = list("SS13")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/central/west) "bFu" = (/obj/machinery/door/window/eastright{dir = 1; name = "Bridge Delivery"; req_access_txt = "19"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/bridge/meeting_room) "bFv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/bridge/meeting_room) @@ -4384,16 +4384,16 @@ "bGp" = (/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) "bGq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/assembly/chargebay) "bGr" = (/turf/simulated/wall/r_wall,/area/assembly/chargebay) -"bGs" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Mech Bay"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/assembly/chargebay) -"bGt" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "mechbay"; name = "Mech Bay"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/assembly/chargebay) +"bGs" = (/obj/machinery/door/window/eastright{dir = 8; name = "Chemistry Desk"; req_access_txt = "33"},/obj/machinery/door/firedoor,/obj/structure/table/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) +"bGt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Examination Room"; req_access_txt = "5"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/exam_room) "bGu" = (/obj/machinery/computer/rdconsole/robotics,/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bGv" = (/obj/structure/table,/obj/item/weapon/book/manual/robotics_cyborgs{pixel_x = 2; pixel_y = 5},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/machinery/requests_console{department = "Robotics"; departmentType = 2; name = "Robotics Requests Console"; pixel_y = 30},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bGw" = (/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) -"bGx" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) -"bGy" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/white,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "robotics"; name = "Robotics Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/assembly/robotics) +"bGx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"},/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 = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) +"bGy" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access_txt = "50"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bGz" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 10; icon_state = "purple"},/area/hallway/primary/starboard/east) -"bGA" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) -"bGB" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab"; name = "Research and Development Lab Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/lab) +"bGA" = (/obj/machinery/conveyor{dir = 4; id = "packageExternal"},/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/office) +"bGB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bGC" = (/obj/machinery/autolathe,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) "bGD" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/obj/item/weapon/storage/belt/utility,/obj/item/clothing/gloves/color/latex,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) "bGE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -4451,7 +4451,7 @@ "bHE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bHF" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bHG" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) -"bHH" = (/obj/machinery/door/window/eastright{dir = 8; name = "Chemistry Desk"; req_access_txt = "33"},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/structure/table/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard_medi"; name = "Quarantine Lockdown"; opacity = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) +"bHH" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry) "bHI" = (/turf/simulated/floor/plasteel{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/reception) "bHJ" = (/obj/structure/stool,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) "bHK" = (/obj/structure/sign/examroom,/turf/simulated/wall,/area/medical/exam_room) @@ -4555,7 +4555,7 @@ "bJE" = (/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry) "bJF" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/reception) "bJG" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) -"bJH" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/medical{name = "Examination Room"; req_access_txt = "5"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/exam_room) +"bJH" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bJI" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "bJJ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "bJK" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/stool/bed,/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) @@ -4570,7 +4570,7 @@ "bJT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/bluegrid,/area/assembly/chargebay) "bJU" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/assembly/chargebay) "bJV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/assembly/chargebay) -"bJW" = (/obj/machinery/door/firedoor{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"},/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 = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) +"bJW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/gravitygenerator) "bJX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bJY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bJZ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) @@ -4604,14 +4604,14 @@ "bKB" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/quartermaster/storage) "bKC" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/quartermaster/office) "bKD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/quartermaster/office) -"bKE" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access_txt = "50"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bKE" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/simulated/floor/plating,/area/quartermaster/storage) "bKF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 0; pixel_y = -32; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "loadingarea"},/area/quartermaster/office) "bKK" = (/obj/machinery/conveyor{dir = 4; id = "packageExternal"},/obj/structure/plasticflaps{opacity = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/office) -"bKL" = (/obj/machinery/conveyor{dir = 4; id = "packageExternal"},/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/office) +"bKL" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/window/westleft{name = "Cargo Desk"; req_access_txt = "50"},/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bKM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) "bKN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/central/west) "bKO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/west) @@ -4690,19 +4690,19 @@ "bMj" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/supply) "bMk" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/supply) "bMl" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/supply) -"bMm" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) +"bMm" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) "bMn" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/status_display/supply_display{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/quartermaster/storage) "bMo" = (/obj/structure/closet/emcloset,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bMp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bMq" = (/obj/machinery/light{dir = 1},/obj/machinery/firealarm{pixel_y = 27},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bMr" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bMs" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/quartermaster/storage) -"bMt" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel,/area/quartermaster/storage) +"bMt" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bMu" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bMv" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bMw" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bMx" = (/obj/machinery/status_display/supply_display,/turf/simulated/wall,/area/quartermaster/office) -"bMy" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/office) +"bMy" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id_tag = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/turf/simulated/floor/plating,/area/assembly/robotics) "bMz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access_txt = "50"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bMA" = (/obj/machinery/mineral/ore_redemption,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bMB" = (/obj/machinery/light{dir = 8},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw) @@ -4779,9 +4779,9 @@ "bNU" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/research) "bNV" = (/obj/structure/grille,/obj/structure/window/full/shuttle,/turf/simulated/shuttle/plating,/area/shuttle/research) "bNW" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/research) -"bNX" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) -"bNY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) -"bNZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"bNX" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab2"; name = "Research and Development Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 1; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) +"bNY" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/glass_research{name = "Research and Development"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) +"bNZ" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/external{id_tag = "supply_home"; name = "Cargo Docking Hatch"; req_access_txt = "31"},/turf/simulated/floor/plating,/area/quartermaster/storage) "bOa" = (/obj/machinery/door/poddoor{id_tag = "trash"; name = "disposal bay door"; protected = 0},/obj/structure/fans/tiny,/turf/simulated/floor/plating,/area/maintenance/disposal) "bOb" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/shuttle/supply) "bOc" = (/turf/simulated/shuttle/floor,/area/shuttle/supply) @@ -4792,7 +4792,7 @@ "bOh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bOi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bOj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) -"bOk" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/storage) +"bOk" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bOl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bOm" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bOn" = (/obj/structure/disposalpipe/segment{name = "Sorting Office"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/quartermaster/office) @@ -4811,7 +4811,7 @@ "bOA" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bOB" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = -32; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/engine/gravitygenerator) "bOC" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/engine/gravitygenerator) -"bOD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/gravitygenerator) +"bOD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/research_shuttle_dock) "bOE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/effect/spawner/window/reinforced,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/engine/gravitygenerator) "bOF" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/engine/gravitygenerator) "bOG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/space,/area/space) @@ -4872,7 +4872,7 @@ "bPJ" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "106"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "bPK" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "106"},/obj/docking_port/mobile{dir = 2; dwidth = 8; height = 15; id = "admin"; name = "administration shuttle"; roundstart_move = "admin_away"; width = 18},/obj/docking_port/stationary{dir = 2; dwidth = 8; height = 15; id = "admin_home"; name = "port bay 1"; width = 18},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "bPL" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/administration) -"bPM" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) +"bPM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access_txt = "50"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bPN" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/quartermaster/storage) "bPO" = (/obj/machinery/conveyor_switch/oneway{id = "QMLoad2"},/turf/simulated/floor/plasteel,/area/quartermaster/storage) "bPP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/storage) @@ -4882,11 +4882,11 @@ "bPT" = (/obj/structure/disposalpipe/junction{dir = 1; icon_state = "pipe-j2"; tag = "icon-pipe-j2"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bPU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bPV" = (/obj/effect/landmark/start{name = "Cargo Technician"},/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) -"bPW" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/window/westleft{name = "Cargo Desk"; req_access_txt = "50"},/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bPW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/gravitygenerator) "bPX" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/office) "bPY" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bPZ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/hallway/primary/central/sw) -"bQa" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) +"bQa" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Teleport Access"; req_access_txt = "17"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/teleporter) "bQb" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/hallway/primary/central/sw) "bQc" = (/obj/structure/table/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/flasher{id = "hopflash"; pixel_y = 28},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hop"; name = "Privacy Shutters"; opacity = 0},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Head of Personnel's Desk"; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bQd" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/crew_quarters/heads) @@ -4981,7 +4981,7 @@ "bRO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office) "bRP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bRQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) -"bRR" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bRR" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bRS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw) "bRT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) "bRU" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/hallway/primary/central/sw) @@ -5039,15 +5039,15 @@ "bSU" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 4; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/assembly/robotics) "bSV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bSW" = (/obj/machinery/door_control{id = "robotics2"; name = "Robotics Lab Shutters Control"; pixel_x = 24; pixel_y = -24; req_access_txt = "29"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) -"bSX" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id_tag = "robotics2"; name = "Robotics Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/turf/simulated/floor/plating,/area/assembly/robotics) +"bSX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access_txt = "30"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) "bSY" = (/obj/machinery/light{dir = 8},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) "bSZ" = (/obj/effect/landmark{name = "lightsout"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "whitehall"; dir = 2},/area/medical/research{name = "Research Division"}) "bTa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitecorner"},/area/medical/research{name = "Research Division"}) "bTb" = (/turf/simulated/wall,/area/toxins/lab) -"bTc" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "rdlab2"; name = "Research and Development Lab Shutters"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 1; icon_state = "left"; name = "Research and Development Desk"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) +"bTc" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) "bTd" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/toxins/lab) "bTe" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/toxins/lab) -"bTf" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/glass_research{name = "Research and Development"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/lab) +"bTf" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/mining{name = "Mining Dock"; req_access_txt = "48"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) "bTg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "bTh" = (/turf/simulated/wall/r_wall,/area/medical/research_shuttle_dock) "bTi" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating/airless,/area/medical/research_shuttle_dock) @@ -5057,7 +5057,7 @@ "bTm" = (/obj/item/stack/sheet/metal,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "bTn" = (/obj/item/stack/sheet/glass,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "bTo" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Hatch"; req_access_txt = "31"},/turf/simulated/shuttle/floor,/area/shuttle/supply) -"bTp" = (/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) +"bTp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/engine/gravitygenerator) "bTq" = (/turf/simulated/floor/plating,/area/quartermaster/storage) "bTr" = (/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/quartermaster/storage) "bTs" = (/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/quartermaster/storage) @@ -5065,7 +5065,7 @@ "bTu" = (/obj/structure/table,/obj/machinery/requests_console{department = "Cargo Bay"; name = "Cargo Requests Console"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/camera{c_tag = "Cargo Office"; dir = 4; network = list("SS13")},/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/device/multitool,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bTv" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bTw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office) -"bTx" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bTx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Server Room"; req_access = null; req_access_txt = "30"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) "bTy" = (/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) "bTz" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) "bTA" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hop"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/crew_quarters/heads) @@ -5146,7 +5146,7 @@ "bUX" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "bUY" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "bUZ" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) -"bVa" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/medical/research_shuttle_dock) +"bVa" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/turf/simulated/floor/plasteel,/area/toxins/storage) "bVb" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/research) "bVc" = (/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"; rebuildable = 1; 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) "bVd" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/research) @@ -5164,7 +5164,7 @@ "bVp" = (/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/folder/yellow,/obj/item/device/eftpos,/obj/item/weapon/book/manual/sop_supply,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bVq" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plasteel,/area/quartermaster/office) "bVr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/office) -"bVs" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access_txt = "50"},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"bVs" = (/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) "bVt" = (/obj/machinery/vending/cart,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bVu" = (/obj/structure/closet/secure_closet/hop2,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bVv" = (/turf/simulated/floor/plasteel,/area/crew_quarters/heads) @@ -5175,7 +5175,7 @@ "bVA" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/server) "bVB" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) "bVC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/server) -"bVD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/gravitygenerator) +"bVD" = (/obj/machinery/door/firedoor,/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Server Exterior Door"; req_access = null; req_access_txt = "0"},/obj/machinery/door/window/brigdoor{dir = 8; name = "Server Interior Door"; req_access = null; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) "bVE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) "bVF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/space,/area/space) "bVG" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/turf/simulated/floor/plasteel,/area/teleporter) @@ -5184,7 +5184,7 @@ "bVJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/bluespace_beacon,/turf/simulated/floor/plasteel,/area/teleporter) "bVK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/teleporter) "bVL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/teleporter) -"bVM" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Teleport Access"; req_access_txt = "17"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/teleporter) +"bVM" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bVN" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/hallway/primary/central/se) "bVO" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR: EMERGENCY ENTRANCE'."; name = "KEEP CLEAR: EMERGENCY ENTRANCE"; pixel_x = 32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "bVP" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/backpack/medic,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/weapon/storage/toolbox/emergency,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay2) @@ -5210,7 +5210,7 @@ "bWj" = (/turf/simulated/wall,/area/assembly/chargebay) "bWk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/assembly/chargebay) "bWl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/assembly/robotics) -"bWm" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) +"bWm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "Blueshield's Office"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "bWn" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bWo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bWp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) @@ -5255,7 +5255,7 @@ "bXc" = (/obj/machinery/computer/message_monitor,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) "bXd" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) "bXe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) -"bXf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access_txt = "30"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/server) +"bXf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "NT Representative's Office"; req_access_txt = "73"},/turf/simulated/floor/wood,/area/ntrep) "bXg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel,/area/engine/gravitygenerator) "bXh" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/gravitygenerator) "bXi" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/item/device/radio/intercom{dir = 4; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel,/area/engine/gravitygenerator) @@ -5343,7 +5343,7 @@ "bYM" = (/turf/simulated/wall,/area/quartermaster/qm) "bYN" = (/obj/machinery/camera{c_tag = "Cargo Bay Entrance"; dir = 4; network = list("SS13")},/obj/machinery/atm{pixel_x = -24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/sw) "bYO" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 4},/area/hallway/primary/central/sw) -"bYP" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) +"bYP" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sign/poster/legit{pixel_x = -32},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bYQ" = (/obj/structure/filingcabinet/chestdrawer,/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/crew_quarters/heads) "bYR" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel Requests Console"; pixel_y = -30},/obj/machinery/camera{c_tag = "Head of Personnel's Office"; dir = 1; network = list("SS13")},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bYS" = (/obj/structure/table,/obj/machinery/photocopier/faxmachine{department = "Head of Personnel's Office"},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) @@ -5419,16 +5419,16 @@ "cak" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "cal" = (/obj/machinery/door/poddoor/shutters{density = 0; dir = 4; icon_state = "shutter0"; id_tag = "adminshuttleshutters"; name = "Blast Shutters"; opacity = 0},/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (WEST)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 8},/turf/simulated/floor/plating,/area/shuttle/administration) "cam" = (/turf/simulated/wall,/area/quartermaster/miningdock) -"can" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/mining{name = "Mining Dock"; req_access_txt = "48"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) +"can" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "cao" = (/obj/structure/filingcabinet,/turf/simulated/floor/plasteel,/area/quartermaster/qm) "cap" = (/obj/machinery/computer/supplycomp,/turf/simulated/floor/plasteel,/area/quartermaster/qm) "caq" = (/obj/machinery/computer/security/mining,/turf/simulated/floor/plasteel,/area/quartermaster/qm) "car" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel,/area/quartermaster/qm) "cas" = (/obj/structure/disposalpipe/segment,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "bluecorner"},/area/hallway/primary/central/sw) -"cat" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = null; req_access_txt = "57"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) +"cat" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cau" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/server) "cav" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/engine/gravitygenerator) -"caw" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/engine/gravitygenerator) +"caw" = (/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/research{name = "Research Division Access"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/mixing) "cax" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "cay" = (/obj/machinery/camera{c_tag = "Central Hallway South-East"; dir = 8; network = list("SS13")},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) "caz" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/medical/sleeper) @@ -5464,9 +5464,9 @@ "cbd" = (/turf/simulated/wall/r_wall,/area/toxins/server_coldroom) "cbe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/toxins/server_coldroom) "cbf" = (/turf/simulated/wall/r_wall,/area/toxins/server) -"cbg" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/airlock/command{name = "Server Room"; req_access = null; req_access_txt = "30"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) +"cbg" = (/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/research{name = "Toxins Mixing Room"; req_access_txt = "7"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/toxins/mixing) "cbh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/toxins/storage) -"cbi" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/turf/simulated/floor/plasteel,/area/toxins/storage) +"cbi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Toxins Launch Room"; req_access_txt = "7"},/turf/simulated/floor/plasteel,/area/toxins/mixing) "cbj" = (/turf/simulated/wall/r_wall,/area/toxins/storage) "cbk" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cbl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) @@ -5478,7 +5478,7 @@ "cbr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/rack,/obj/item/device/aicard,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) "cbs" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor) "cbt" = (/obj/structure/lamarr,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/crew_quarters/hor) -"cbu" = (/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research_shuttle_dock) +"cbu" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/toxins/storage) "cbv" = (/obj/machinery/computer/shuttle/science,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research_shuttle_dock) "cbw" = (/obj/machinery/door/airlock/centcom{id_tag = "adminshuttle"; name = "Bridge"; opacity = 1; req_access_txt = "106"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) "cbx" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration) @@ -5640,7 +5640,7 @@ "cex" = (/obj/machinery/alarm/server{dir = 4; pixel_x = -22; pixel_y = 0},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 250; oxygen = 0; temperature = 0},/area/toxins/server_coldroom) "cey" = (/obj/effect/landmark{name = "blobstart"},/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 250; oxygen = 0; temperature = 0},/area/toxins/server_coldroom) "cez" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 10},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 250; oxygen = 0; temperature = 0},/area/toxins/server_coldroom) -"ceA" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Server Exterior Door"; req_access = null; req_access_txt = "0"},/obj/machinery/door/window/brigdoor{dir = 8; name = "Server Interior Door"; req_access = null; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) +"ceA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Engineering"},/obj/machinery/door/firedoor,/obj/machinery/door/window/westright{name = "Engineering Monitoring Station"; req_access = null; req_access_txt = "0"; req_one_access_txt = "11;24;34"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/engine/controlroom) "ceB" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) "ceC" = (/obj/structure/stool/bed/chair/office/light,/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) "ceD" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/toxins/server) @@ -5748,7 +5748,7 @@ "cgB" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/shuttle/mining) "cgC" = (/obj/machinery/computer/shuttle/mining,/turf/simulated/shuttle/floor,/area/shuttle/mining) "cgD" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/mining) -"cgE" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) +"cgE" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "E.X.P.E.R.I-MENTOR Lab"; req_access_txt = "47"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "cgF" = (/obj/machinery/computer/shuttle/mining,/turf/simulated/floor/plasteel{dir = 9; icon_state = "brown"},/area/quartermaster/miningdock) "cgG" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "brown"},/area/quartermaster/miningdock) "cgH" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/quartermaster/miningdock) @@ -5764,11 +5764,11 @@ "cgR" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cgS" = (/turf/simulated/wall,/area/blueshield) "cgT" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "blueshield"; name = "Privacy Shutters"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/blueshield) -"cgU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/command{name = "Blueshield's Office"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) +"cgU" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor,/obj/machinery/door/window/northleft{dir = 4; icon_state = "left"; name = "Engineering Desk"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/engine/controlroom) "cgV" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "blueshield"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/blueshield) "cgW" = (/turf/simulated/wall,/area/ntrep) "cgX" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "representative"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/ntrep) -"cgY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/command{name = "NT Representative's Office"; req_access_txt = "73"},/turf/simulated/floor/wood,/area/ntrep) +"cgY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Tech Storage"; req_access_txt = "23"},/turf/simulated/floor/plating,/area/storage/tech) "cgZ" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "representative"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/ntrep) "cha" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/south) "chb" = (/obj/structure/sign/directions/engineering,/obj/structure/sign/directions/science{dir = 4; pixel_x = 0; pixel_y = -7},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/turf/simulated/wall,/area/janitor) @@ -5816,9 +5816,9 @@ "chR" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/camera{c_tag = "Research Toxins Storage Room"; dir = 4; network = list("Research","SS13"); pixel_y = -22},/turf/simulated/floor/plasteel,/area/toxins/storage) "chS" = (/mob/living/simple_animal/mouse/white,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) "chT" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) -"chU" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/sign/poster/legit{pixel_x = -32},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"chV" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) -"chW" = (/obj/machinery/door/firedoor{dir = 1; name = "hazard door north"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) +"chU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) +"chV" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) +"chW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) "chX" = (/obj/machinery/atmospherics/pipe/simple/insulated,/obj/machinery/camera{c_tag = "Research Toxins Mixing North"; dir = 2; network = list("Research","SS13"); pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "chY" = (/obj/machinery/atmospherics/pipe/simple/insulated{dir = 6},/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "chZ" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{dir = 4},/turf/simulated/wall/r_wall/coated,/area/toxins/mixing) @@ -5903,7 +5903,7 @@ "cjA" = (/obj/machinery/light,/obj/machinery/camera{c_tag = "Research Genetics South"; dir = 1; network = list("Research","SS13")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/genetics) "cjB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/genetics) "cjC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/genetics) -"cjD" = (/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/stokcubes,/obj/item/weapon/storage/box/neaeracubes,/obj/structure/table/glass,/obj/item/weapon/storage/box/wolpincubes,/obj/item/weapon/storage/box/farwacubes,/turf/simulated/floor/plasteel{tag = "icon-whitepurple (SOUTHEAST)"; icon_state = "whitepurple"; dir = 6},/area/medical/genetics) +"cjD" = (/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes/stokcubes,/obj/item/weapon/storage/box/monkeycubes/neaeracubes,/obj/structure/table/glass,/obj/item/weapon/storage/box/monkeycubes/wolpincubes,/obj/item/weapon/storage/box/monkeycubes/farwacubes,/turf/simulated/floor/plasteel{tag = "icon-whitepurple (SOUTHEAST)"; icon_state = "whitepurple"; dir = 6},/area/medical/genetics) "cjE" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24; shock_proof = 0},/turf/simulated/floor/engine,/area/toxins/explab_chamber) "cjF" = (/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/engine,/area/toxins/explab_chamber) "cjG" = (/turf/simulated/floor/engine,/area/toxins/explab_chamber) @@ -6144,11 +6144,11 @@ "coh" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) "coi" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) "coj" = (/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"cok" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/mixing) +"cok" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel,/area/engine/controlroom) "col" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/mixing) "com" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/mixing) "con" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/mixing) -"coo" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Toxins Mixing Room"; req_access_txt = "7"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/toxins/mixing) +"coo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/atmos{name = "Incinerator Access"; req_access_txt = "24"},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cop" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/toxins/mixing) "coq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cor" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/window/eastright{name = "Toxins Mixing Room"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/toxins/mixing) @@ -6257,7 +6257,7 @@ "cqq" = (/obj/machinery/atmospherics/binary/valve,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cqr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) "cqs" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/mixing) -"cqt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{name = "Toxins Launch Room"; req_access_txt = "7"},/turf/simulated/floor/plasteel,/area/toxins/mixing) +"cqt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel,/area/construction) "cqu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel,/area/toxins/mixing) "cqv" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/toxins/mixing) "cqw" = (/obj/machinery/doppler_array{dir = 4},/turf/simulated/floor/plasteel,/area/toxins/mixing) @@ -6332,7 +6332,7 @@ "crN" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_y = 30},/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "crO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "crP" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) -"crQ" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/toxins/storage) +"crQ" = (/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/airlock/research{name = "Test Lab"; req_access_txt = "7"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "crR" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "crS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "crT" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -6441,7 +6441,7 @@ "ctS" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/obj/structure/disposalpipe/junction{tag = "icon-pipe-j2"; icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "ctT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "ctU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"ctV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/navbeacon{codes_txt = "delivery"; dir = 4; location = "Engineering"},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window/westright{name = "Engineering Monitoring Station"; req_access = null; req_access_txt = "0"; req_one_access_txt = "11;24;34"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/engine/controlroom) +"ctV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor/plasteel,/area/engine/controlroom) "ctW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/window/northleft{dir = 4; icon_state = "left"; name = "Engineering Monitoring Station"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/engine/controlroom) "ctX" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/engine/controlroom) "ctY" = (/turf/simulated/floor/plasteel,/area/engine/controlroom) @@ -6479,7 +6479,7 @@ "cuE" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "cuF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "cuG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) -"cuH" = (/obj/machinery/door/firedoor{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/research{name = "E.X.P.E.R.I-MENTOR Lab"; req_access_txt = "47"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) +"cuH" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access_txt = "55"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "cuI" = (/obj/machinery/light,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cuJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cuK" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) @@ -6519,7 +6519,7 @@ "cvs" = (/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor/plating,/area/storage/tech) "cvt" = (/obj/machinery/camera{c_tag = "Tech Storage"; dir = 2; network = list("SS13")},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/cyborgrecharger{pixel_x = -4; pixel_y = -2},/obj/item/weapon/circuitboard/mech_bay_power_console{pixel_x = 2; pixel_y = 2},/obj/item/weapon/circuitboard/mech_recharger,/obj/item/weapon/circuitboard/mechfab{pixel_y = 3},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/storage/tech) "cvu" = (/obj/structure/table,/obj/item/device/analyzer,/obj/item/device/healthanalyzer,/turf/simulated/floor/plating,/area/storage/tech) -"cvv" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) +"cvv" = (/obj/structure/table,/obj/item/device/plant_analyzer,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) "cvw" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plating,/area/storage/tech) "cvx" = (/turf/simulated/wall,/area/storage/tech) "cvy" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) @@ -6599,7 +6599,7 @@ "cwU" = (/obj/structure/disposalpipe/segment,/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 1},/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "cwV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cwW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cwX" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window/northleft{dir = 4; icon_state = "left"; name = "Engineering Desk"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/engine/controlroom) +"cwX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{on = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "cwY" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/engine/controlroom) "cwZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/engine/controlroom) "cxa" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/controlroom) @@ -6753,7 +6753,7 @@ "czS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/storage/tech) "czT" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating,/area/storage/tech) "czU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/effect/landmark{name = "blobstart"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plating,/area/storage/tech) -"czV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Tech Storage"; req_access_txt = "23"},/turf/simulated/floor/plating,/area/storage/tech) +"czV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Mechanic Workshop"; req_access_txt = "70"; req_one_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "czW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "czX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "czY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) @@ -6796,9 +6796,9 @@ "cAJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/maintenance/asmaint) "cAK" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cAL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/toxins/xenobiology) -"cAM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor{dir = 2; name = "hazard door south"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) -"cAN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor{dir = 2; name = "hazard door south"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) -"cAO" = (/obj/machinery/door/firedoor{dir = 2; name = "hazard door south"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/toxins/xenobiology) +"cAM" = (/obj/machinery/door/firedoor,/obj/structure/table/reinforced,/obj/machinery/door/window/westright{name = "Mechanic's Desk"; req_access = null; req_access_txt = "70"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/cell_charger,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) +"cAN" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "32"; req_one_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/break_room) +"cAO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -28; pixel_y = 8; req_access_txt = "55"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_interior"; locked = 1; name = "Xenobiology Internal Airlock"; req_access_txt = "55"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "cAP" = (/turf/simulated/wall/r_wall,/area/toxins/misc_lab) "cAQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall/r_wall,/area/toxins/misc_lab) "cAR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall/r_wall,/area/toxins/misc_lab) @@ -6827,7 +6827,7 @@ "cBo" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/powermonitor{pixel_x = -2; pixel_y = 2},/obj/item/weapon/circuitboard/stationalert_all{pixel_x = 1; pixel_y = -1},/obj/item/weapon/circuitboard/atmos_alert{pixel_x = 3; pixel_y = -3},/obj/item/weapon/circuitboard/thermomachine,/obj/item/weapon/circuitboard/smes{pixel_x = 4},/turf/simulated/floor/plating,/area/storage/tech) "cBp" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plating,/area/storage/tech) "cBq" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{icon_state = "caution"; dir = 4},/area/hallway/primary/aft) -"cBr" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel,/area/engine/controlroom) +"cBr" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/atmos/control) "cBs" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/construction) "cBt" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction) "cBu" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction) @@ -6885,7 +6885,7 @@ "cCu" = (/obj/effect/decal/remains/human{desc = "This guy seemed to have died in terrible way! Half his remains are dust."; icon_state = "remains"; name = "Human remains"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) "cCv" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/hologram/holopad,/mob/living/simple_animal/mouse,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) "cCw" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/incinerator) -"cCx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/atmos{name = "Incinerator Access"; req_access_txt = "24"},/turf/simulated/floor/plating,/area/maintenance/incinerator) +"cCx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/turf/simulated/floor/plasteel,/area/atmos/control) "cCy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cCz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Alternate Construction Area"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/apmaint) "cCA" = (/obj/item/stack/sheet/glass{amount = 10},/turf/simulated/floor/plating,/area/maintenance/consarea) @@ -6971,7 +6971,7 @@ "cEc" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plasteel,/area/engine/controlroom) "cEd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/engine/controlroom) "cEe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/engine/controlroom) -"cEf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plasteel,/area/construction) +"cEf" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cEg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction) "cEh" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction) "cEi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction) @@ -7002,7 +7002,7 @@ "cEH" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "cEI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "cEJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) -"cEK" = (/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{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{name = "Test Lab"; req_access_txt = "7"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) +"cEK" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cEL" = (/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 = 8; icon_state = "whitepurple"},/area/toxins/misc_lab) "cEM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "cEN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) @@ -7097,7 +7097,7 @@ "cGy" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cGz" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/scrubber,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "escape"},/area/hallway/primary/aft) "cGA" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/wall,/area/engine/controlroom) -"cGB" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor/plasteel,/area/engine/controlroom) +"cGB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access_txt = "56"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cGC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/engine/controlroom) "cGD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/engine/controlroom) "cGE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/engine/break_room) @@ -7127,7 +7127,7 @@ "cHc" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{dir = 5; icon_state = "blue"},/area/medical/patients_rooms) "cHd" = (/turf/simulated/wall,/area/medical/patients_rooms) "cHe" = (/obj/effect/spawner/lootdrop/maintenance,/obj/effect/decal/cleanable/vomit,/turf/simulated/floor/plating,/area/maintenance/asmaint) -"cHf" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access_txt = "55"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) +"cHf" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_atmos{name = "Distribution Loop"; req_access_txt = "24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plasteel,/area/atmos/distribution) "cHg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/toxins/xenobiology) "cHh" = (/obj/structure/rack,/obj/item/clothing/mask/gas{pixel_x = 2; pixel_y = 2},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -2; pixel_y = -2},/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) "cHi" = (/obj/structure/closet/l3closet/scientist,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/misc_lab) @@ -7148,8 +7148,8 @@ "cHx" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/engine/mechanic_workshop) "cHy" = (/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/engine/mechanic_workshop) "cHz" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) -"cHA" = (/obj/machinery/atmospherics/unary/vent_pump{on = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) -"cHB" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_engineering{name = "Mechanic Workshop"; req_access_txt = "70"; req_one_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) +"cHA" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = null},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/engineering) +"cHB" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/door/airlock/glass_engineering{name = "Engine Room"; req_access_txt = "10"; req_one_access_txt = null},/turf/simulated/floor/plasteel,/area/engine/engineering) "cHC" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cHD" = (/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cHE" = (/obj/machinery/atmospherics/unary/vent_pump{on = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) @@ -7219,7 +7219,7 @@ "cIQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "cIR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "cIS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/stool/bed/chair/office/light{dir = 4},/obj/effect/landmark/start{name = "Mechanic"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) -"cIT" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/table/reinforced,/obj/machinery/door/window/westright{name = "Mechanic's Desk"; req_access = null; req_access_txt = "70"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/cell_charger,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) +"cIT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/storage/secure) "cIU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cIV" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cIW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) @@ -7269,8 +7269,8 @@ "cJO" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "RnDChem"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/grille,/obj/structure/window/plasmareinforced,/obj/structure/window/plasmareinforced{dir = 4},/obj/structure/window/plasmareinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/insulated,/turf/simulated/floor/engine,/area/toxins/misc_lab) "cJP" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/toxins/misc_lab) "cJQ" = (/obj/structure/closet,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint2) -"cJR" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/engine/mechanic_workshop) -"cJS" = (/obj/structure/grille,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/engine/mechanic_workshop) +"cJR" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating/airless,/area/engine/mechanic_workshop) +"cJS" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/engine/mechanic_workshop) "cJT" = (/obj/machinery/door/airlock/maintenance{name = "Mechanic Workshop Maintenance"; req_access = null; req_access_txt = "70"},/turf/simulated/floor/plating,/area/maintenance/aft) "cJU" = (/obj/structure/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/toolbox/electrical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/radio{pixel_y = 6},/turf/simulated/floor/plasteel,/area/engine/mechanic_workshop) "cJV" = (/turf/simulated/floor/plasteel,/area/engine/mechanic_workshop) @@ -7290,7 +7290,7 @@ "cKj" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cKk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "cKl" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "yellow"},/area/hallway/primary/aft) -"cKm" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "32"; req_one_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/break_room) +"cKm" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/maintenance/turbine) "cKn" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/break_room) "cKo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/break_room) "cKp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/break_room) @@ -7391,7 +7391,7 @@ "cMg" = (/obj/effect/landmark{name = "revenantspawn"},/mob/living/carbon/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cMh" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/toxins/xenobiology) "cMi" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/toxins/xenobiology) -"cMj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -28; pixel_y = 8; req_access_txt = "55"},/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_interior"; locked = 1; name = "Xenobiology Internal Airlock"; req_access_txt = "55"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) +"cMj" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{dir = 8; id_tag = "teledoor"; name = "AI Satellite Teleport Access"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "cMk" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/engine,/area/toxins/xenobiology) "cMl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/engine,/area/toxins/test_chamber) "cMm" = (/mob/living/carbon/human/monkey,/turf/simulated/floor/engine,/area/toxins/test_chamber) @@ -7420,7 +7420,7 @@ "cMJ" = (/obj/structure/table,/obj/item/weapon/book/manual/supermatter_engine,/turf/simulated/floor/plasteel,/area/engine/break_room) "cMK" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/effect/landmark/start{name = "Life Support Specialist"},/turf/simulated/floor/plasteel,/area/engine/break_room) "cML" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/engine/break_room) -"cMM" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/atmos/control) +"cMM" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"}) "cMN" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plasteel,/area/atmos/control) "cMO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{level = 2},/turf/simulated/floor/plasteel,/area/atmos/control) "cMP" = (/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) @@ -7528,7 +7528,6 @@ "cON" = (/obj/effect/landmark/start{name = "Station Engineer"},/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/plasteel,/area/engine/break_room) "cOO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/engine/break_room) "cOP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/atmos/control) -"cOQ" = (/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/atmos/control) "cOR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/atmos/control) "cOS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/wall/r_wall,/area/atmos) "cOT" = (/turf/simulated/wall/r_wall,/area/atmos/distribution) @@ -7622,10 +7621,8 @@ "cQD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft) "cQE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/hallway/primary/aft) "cQF" = (/obj/structure/sign/securearea,/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/equipmentstorage) -"cQG" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cQH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/equipmentstorage) "cQI" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/equipmentstorage) -"cQJ" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cQK" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "Engineering"; name = "Engineering Security Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/equipmentstorage) "cQL" = (/obj/machinery/light{dir = 8},/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/blue/hollow,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) "cQM" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/blue/hollow,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/atmos) @@ -7654,7 +7651,7 @@ "cRj" = (/obj/structure/closet/emcloset,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/camera{c_tag = "Virology Airlock"; network = list("SS13")},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/medical/virology) "cRk" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology) "cRl" = (/obj/structure/table/glass,/obj/item/weapon/paper_bin{pixel_x = -5; pixel_y = 5},/obj/item/weapon/pen,/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"},/area/medical/virology) -"cRm" = (/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/stokcubes,/obj/item/weapon/storage/box/neaeracubes,/obj/structure/table/glass,/obj/item/weapon/storage/box/wolpincubes,/obj/item/weapon/storage/box/farwacubes,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"},/area/medical/virology) +"cRm" = (/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes/stokcubes,/obj/item/weapon/storage/box/monkeycubes/neaeracubes,/obj/structure/table/glass,/obj/item/weapon/storage/box/monkeycubes/wolpincubes,/obj/item/weapon/storage/box/monkeycubes/farwacubes,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"},/area/medical/virology) "cRn" = (/obj/structure/table/glass,/obj/item/weapon/storage/box/syringes,/obj/machinery/camera{c_tag = "Virology Monkey Pen"; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"},/area/medical/virology) "cRo" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHEAST)"; icon_state = "whitegreen"; dir = 5},/area/medical/virology) "cRp" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/toxins/xenobiology) @@ -7748,7 +7745,6 @@ "cSZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/engine/chiefs_office) "cTa" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cTb" = (/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) -"cTc" = (/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access_txt = "56"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "cTd" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cTe" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) "cTf" = (/obj/machinery/camera{c_tag = "Engineering Equipment East"; dir = 8; network = list("SS13")},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/engineeringcart,/obj/item/device/radio/intercom{pixel_x = 28},/turf/simulated/floor/plasteel,/area/engine/equipmentstorage) @@ -7825,7 +7821,6 @@ "cUy" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel,/area/atmos) "cUz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/atmos) "cUA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plasteel,/area/atmos) -"cUB" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_atmos{name = "Distribution Loop"; req_access_txt = "24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plasteel,/area/atmos/distribution) "cUC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plasteel,/area/atmos/distribution) "cUD" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6; level = 2},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/atmos/distribution) "cUE" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9; tag = "icon-intact-y (NORTHWEST)"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/atmos/distribution) @@ -8042,7 +8037,6 @@ "cYH" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/engine/chiefs_office) "cYI" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/engine/chiefs_office) "cYJ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/engine/engineering) -"cYK" = (/obj/machinery/door/firedoor{layer = 2.6; name = "\improper Firelock South"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering"; req_access_txt = "10"; req_one_access_txt = null},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel,/area/engine/engineering) "cYL" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/engine/engineering) "cYM" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable,/turf/simulated/floor/plating,/area/engine/engineering) "cYN" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall/r_wall,/area/engine/engineering) @@ -8139,7 +8133,6 @@ "daA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/warning_stripes/south,/turf/simulated/floor/plasteel,/area/engine/engineering) "daB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/warning_stripes/southwestcorner,/turf/simulated/floor/plasteel,/area/engine/engineering) "daC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 0; pixel_y = -32; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engine/engineering) -"daD" = (/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/door/airlock/glass_engineering{name = "Engine Room"; req_access_txt = "10"; req_one_access_txt = null},/turf/simulated/floor/plasteel,/area/engine/engineering) "daE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/engineering) "daF" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/smes/engineering,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/engine/engineering) "daG" = (/turf/simulated/floor/plating,/area/engine/engineering) @@ -8193,7 +8186,6 @@ "dbC" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/wall/r_wall,/area/engine/engineering) "dbD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering) "dbE" = (/obj/machinery/camera{c_tag = "Atmospherics West"; dir = 4; network = list("SS13")},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel,/area/atmos) -"dbF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plasteel,/area/atmos) "dbG" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4; initialize_directions = 11; level = 2},/turf/simulated/floor/plasteel,/area/atmos) "dbH" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "tox_in"; name = "Toxin Supply Control"; output_tag = "tox_out"; sensors = list("tox_sensor" = "Tank")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/atmos) "dbI" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/space,/area/space) @@ -8780,7 +8772,7 @@ "dmR" = (/obj/machinery/camera{c_tag = "Mini Satellite Access"; dir = 4; network = list("SS13","MiniSat")},/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/engine/engineering) "dmS" = (/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/engine/engineering) "dmT" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/transit_tube{dir = 4; icon_state = "Block"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/engineering) -"dmU" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/transit_tube/station,/obj/structure/transit_tube_pod{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/engine/engineering) +"dmU" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/transit_tube/station,/obj/structure/transit_tube_pod{dir = 8},/turf/simulated/floor/plasteel{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/engine/engineering) "dmV" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube,/turf/simulated/floor/plating,/area/engine/engineering) "dmW" = (/obj/structure/transit_tube,/turf/space,/area/space) "dmX" = (/obj/structure/transit_tube{icon_state = "E-W-Pass"},/obj/structure/lattice,/turf/space,/area/space) @@ -8841,8 +8833,8 @@ "doa" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/hatch{name = "MiniSat Foyer"; req_access_txt = "75"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "dob" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/turret_protected/aisat_interior) "doc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/turret_protected/aisat_interior) -"dod" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/turret_protected/aisat_interior) -"doe" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 8; frequency = 1441; id = "co2_in"; pixel_y = 1},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/turret_protected/aisat_interior) +"dod" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating/airless,/area/turret_protected/aisat_interior) +"doe" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 8; frequency = 1441; id = "co2_in"; pixel_y = 1},/turf/simulated/floor/plating/airless,/area/turret_protected/aisat_interior) "dof" = (/obj/machinery/door/airlock/external{frequency = 1450; icon_state = "door_locked"; id_tag = "sci_outer"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/asmaint2) "dog" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk4"; icon_state = "catwalk4"},/area/solar/starboard) "doh" = (/turf/simulated/floor/plating/airless,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk12"; icon_state = "catwalk12"},/area/solar/starboard) @@ -8869,7 +8861,6 @@ "doC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/turret_protected/aisat_interior) "doD" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/turret_protected/aisat_interior) "doE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) -"doF" = (/obj/machinery/door/firedoor,/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "teledoor"; name = "AI Satellite Teleport Access"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "doG" = (/obj/effect/decal/warning_stripes/east,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/door_control{desc = "A remote control-switch for the engineering security doors."; id = "teledoor"; name = "AI Satellite Teleport Shutters Control"; pixel_x = 0; pixel_y = 25; req_access_txt = "17;75"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/turret_protected/aisat_interior) "doH" = (/obj/machinery/teleport/hub,/turf/simulated/floor/plating,/area/turret_protected/aisat_interior) "doI" = (/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_sw"; name = "southwest of station"; width = 18},/turf/space,/area/space) @@ -8961,6 +8952,7 @@ "dqq" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/hatch{name = "MiniSat Chamber Hallway"; req_access_txt = "75"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{dir = 5; icon_state = "dark"; tag = "icon-vault (NORTHEAST)"},/area/aisat{name = "\improper AI Satellite Hallway"}) "dqr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/aisat{name = "\improper AI Satellite Hallway"}) "dqs" = (/obj/machinery/door/airlock/maintenance_hatch{name = "MiniSat Maintenance"; req_access_txt = "75"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) +"dqt" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/cryopod/right,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "dqu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) "dqv" = (/turf/simulated/floor/bluegrid,/area/aisat{name = "\improper AI Satellite Hallway"}) "dqw" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) @@ -9051,7 +9043,6 @@ "dsh" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = null; name = "Shuttle Cargo Hatch"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) "dsi" = (/obj/structure/noticeboard,/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape) "dsj" = (/obj/machinery/door/airlock/shuttle{aiControlDisabled = 1; hackProof = 1; id_tag = "s_docking_airlock"; name = "Shuttle Hatch"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape) -"dsk" = (/obj/structure/closet/emcloset,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/effect/decal/warning_stripes/southeast,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit) "dsl" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape) "dsn" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape) "dso" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) @@ -9072,7 +9063,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9105,14 +9096,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaabBaaiaaiaaiaaiaaiaaiaaiabCabjaaQaaqablabmabDabEaasaataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabFaaiabGaaiaaiaaiaaiaaiaawaafaaqablaaaaaaabmabDaasaataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabHabIabJabKabKabKabLabIabMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNabOabPabQabNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabmaaeaafaauaaiabRabSaaQaaqaalablaaaaaaaaaaaaabmaafaaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTabUabVabWabXabYabZabZabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNabNacaacbaccabNabNaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabmaalaaeaaeaaeaalablaaaaaaaaaaaaaaaaaaaaaabmablaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTabUabVabWabXabYabZabZabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNabNacaaacaccabNabNaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabmaalaaeaaeaaeaalablaaaaaaaaaaaaaaaaaaaaaabmablaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTacdabVabVaceabVabVacfabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNacgachaciachacjabNaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTackaclabVabVacmabVacnabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacoacpachaciachacpacoaaaaaaaaaaabaabaabaaaaaaaabaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqabIabIabIacrabIabIabIacsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactacuacvacwacvacxacyaaaaaaaaaabNabNabNabNabNaabaabaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTaczabVacAabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaababNacBacCacDachacEabNaaaaaaaababNacFacGacHabNabNabNaaaaaaaabaabaabaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTacIabVacJabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaabNacKacLacDacMacNabNaaaaabaababNacOacPacQacRacSabNaaaaabaabaacaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTabIabIabIabIabTacIabVacJacUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacabNacoabNacVacWacXacYacWabNacZadaabQabNadbadcaddacWacWabNabNabNabNabNabNabNabNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTadeabVabVadfabTacIabVacJabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaababNadgadhacKadhacDadiadjadkaciadlachadmadnadoadpadqadradsacWadtaduadvadwadxabNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTaczabVacAabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaababNacBacCacDachacEabNaaaaaaaababNacFacGacHabNabNabNaaaaaaaabaabaabafOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTacIabVacJabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaabNacKacLacDacMacNabNaaaaabaababNacOacPacQacRacSabNaaaaabaabafOaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTabIabIabIabIabTacIabVacJacUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOabNacoabNacVacWacXacYacWabNacZadaabQabNadbadcaddacWacWabNabNabNabNabNabNabNabNaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTadeabVabVadfabTacIabVacJabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabaababNadgadhacKadhacDadiadjadkaciadlachadmadnadoadpadqadradsacWadtaduadvadwadxabNaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTadeabVadyadzabTacIabVacJabTabIadAadBadCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNadDadEadFadoacDadGachachadHadIadladJadKadLadMadladNadOacWadPadPadQadRadRacoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTadSabVabVadTabTadUabVacfadVadWadWadWabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNadXacvadYacvadZaeaaebaecaedaeeaefaegaehaeiaejaefaekaekaelaemaenaeoaepaeqaeraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTadeabVabVabVaesabVabVaetaeuaevaevaewabTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaexaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabNadlaeyaezaeAaeBaeCaeDaeAaeAaeEaeFaeGaeHaeAaeIaeJaeAaeAaeKaeLaeMaeNaeMadRaeOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9132,147 +9123,147 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaababNajJajKaivajLajMajNajOajPajQajRaivaaaaaaaaaaaaaaaaaaaihajSajTajUajVaiYajWaihajXajwajwajwajwajxajyaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwajYajYagZagZagZagwajZahaahaahaakaagwagZagZagZajYajYagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaababNahRaigaivakbakcakdajOakeakfakgaivaaaaaaaaaaaaaaaakhaihakiakjakkaklaiYakmaihaknajwakoajwajwajxajyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsakpakpahnaaaaaaagwakqahaahaahaakragwaaaaaaahsakpakpahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaaaabaaaaaaaaaaababNaksaigaivaktakcakdajOakeakfakuaivaaaaaaaaaaaaaaaaaaaihakvajTakwajVaiYakxaihakyajwajwajwajwakzajyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakAahaahaahaakragwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakBakBakBakBakBakBakBakBaabaaaaaaaaaaabaabaabaabaabaababNajJaigaivaivakCakDakEakFakGaivaivaaaaaaaaaaaaaaaaaaaihakHakIakJaiYakKakLaihakMakNakOakOakPajbafXakQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakRakSahZakRakSagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakBakBakBakBakBakBakBakBaabaaaaaaaaaaabaabaabaabaabaababNajJaigaivaivakCakDakEakFakGaivaivaaaaaaaaaaaaaaaaaaaihakHakIakJaiYakKakLaihakMacbakOakOakPajbafXakQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwakRakSahZakRakSagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBakTakUakVakWakXakUakYakBaabaaaaaaaabakZakZakZakZakZakZabNalaalbalcaivaldalealfalgalhaivalialialjalkallalialiaihalmalnaloalpalqaihaihalralsaltaltaluajbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvalvalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwalxalyahaalzalAagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalBalCalDakWalBalCalDakBaaaaaaaaaaabakZalEalFalGalHalIalJalKalLalMaivaivalNalOalPaivaivalialQalRalSalTalUalValWalXalYalZalTalTamaambamcamdameamfamgajbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaalvaaaaabaaaamhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwamiamjahaamkamlagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalBalCalDakWalBalCalDakBaaaaaaaaaaabakZalEalFalGalHalIalJalKalLalMaivaivalNalOalPaivaivalialQalRalSalTalUalVakNalXalYalZalTalTamaambamcamdameamfamgajbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaalvaaaaabaaaamhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwamiamjahaamkamlagwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBammalDamnakWamoalDampakBaabaaaaaaaaaakZamqamramsamtamuamvamwafeamxamyamzamAamBamCamDamEamFamGamHamIamHamHamJamKamLamMamNamHamHamOamPamQamRamSamTamUamVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabamXaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZamYamZanaagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalDalBalDakWalDalBalDakBaaaaaaaabaabakZanbamrancandaneanfanganhaniamyanjankanlanmannanoamyanpanqanransansantanuanvanwanxanyanzanAanBanCanDanEanFanGajbanHanHanHanHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWamWalvaaaanIaaaalvamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahsagZagZagZahnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalBalDalBakWalBalDalBakBaaaaabaaaaaaakZalEanJanKanLanManNanOanPanQanRanSanTanUanVanWanXanYanZaoaaobaocaodanAaoeaofaogaohaoiaoiaojaokanHajbajbajbajbajbaolaolaolanHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabaabaabanIaabaabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalBalBalDakWalBalBalDakBaabaabaaaaaaakZakZaomaonaooaooaopacWaoqaoramyaosaotanlaouaovaowaoxaoyaozaoAaoBaoCaoDaoEaoFaoGaoHaoHaoIaoJaoKanHaolaolaolaolaolaolaolaolanHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaaaaaaaaaaoLaaaaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBalDalBaoMakWalDalBaoNakBaoOaabaabaabaabakZaoPaomaoQaoRaoSacWaoTaoUamyaoVaoWaoXaoYaoZapaapbapcapdapeapfaoCapgaphapiapjapkaplapmaoJapnanHaolaolaolaolaolaolaolaolanHamWamWapoaabamWamWamWamWamWamWamWamWamWamWamWamWamWamWaabaabappapqapraabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsaptapuapvapwaptaptapxaptaptapyaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabapzaabalvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaakBapAapBapCapDapAapBapCapEapFapFapFapFapFapFapGapGapHapIapJapKapLapMapNapNapOapPapQapRapNapSapTapUapVapWapXapYapZapiapjaqaaqbapmaqcaqdaqeaolaolaolaolaolaolaolaolanHaabaabaabaabaabaabaaaaabaaaaabaabaabaabaabaabaabaabaaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsaptapuapvapwaptaptapxaptaptapyaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabapzaabalvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaakBapAapBapCapDapAapBapCapEapFapFapFapFapFapFapGapGapHalWapJapKapLapMapNapNapOapPapQapRapNapSapTapUapVapWapXapYapZapiapjaqaaqbapmaqcaqdaqeaolaolaolaolaolaolaolaolanHaabaabaabaabaabaabaaaaabaaaaabaabaabaabaabaabaabaabaaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqgaqhaqiaqjaqkaqlaqlaqlaqmaqnaqoaaaaaaaaaalwalwalwalvalvaabaabaaaaqpaaaaabaabalvalvalwalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBaqqaqraqsalBaqtaquaqvaqwapGaqxaqyaqzaqAaqBaqCapGaqDaqEaqFaqGaqHaqIaqJaqKaqLaqMaqNaqOapRapSaqPaqQapSaqRapSanAaqSaqTaqUaqVaqWaqXaqYaoJaqZaolaolaolaolaolaolaolaolanHaabaraarbarbarbarcarbarbarbarbarcarbarbarbarbardaabaaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaareaqharfargaqlarharharharharhariaaaaaaaaaalwaaaaaaaabaaaaabaaaaaaaqpaaaaaaaabaaaaabaaaaaaalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBarjalBarkarlarmarnaroarpapGarqarrarsarsartaruapGarvarwarxaryarzaqIarAarBarCarDarEarFarGarHarIarJarKarLarMarNarOarParQarRarSarTaoJarUaqeaolaolaolaolaolaolaolaolanHaabarVaabaabaabarVaabaaaaaaaabarVaabaabaaaaaaarVaabaaaaabaabappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaareaqharfargaqlarharharharharhariaaaaaaaaaalwaaaaaaaabaaaaabaaaaaaaqpaaaaaaaabaaaaabaaaaaaalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBarjalBarkarlarmarnaroarpapGarqarrarsarsartaruapGarvarwarxaryarzaqIapIarBarCarDarEarFarAarHarIarJarKarLarMarNarOarParQarRarSarTaoJarUaqeaolaolaolaolaolaolaolaolanHaabarVaabaabaabarVaabaaaaaaaabarVaabaabaaaaaaarVaabaaaaabaabappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarWaqharXarYarharharharharZasaaqoaaaaaaaaaalwaabasbasbasbasbasbaaaascaaaasbasbasbasbasbaabalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaakBasdasearkalBasfarnasgashapGasiasjaskaslasmasnapGasoaspasqasrassastaqJasuasvaqMaswasxapRasyaozaszaszasAasBasCasDasEasFasGasHasGasIasJanHanHanHanHanHanHanHanHanHanHaabarVaabaaaappapqapraaaaaaappapqapraaaaaaappapqapraabaabaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasKaptaptaptapwaptaptapxaptaptasLaaaaaaaaaalwaaaasMasNasNasNasNasOasPasQasRasRasRasRasSaaaalwaaaaaaaaaasTasUasVasWasXaaaaaaaaaaoOakBakWakWakWakWasYasZataakWapGatbatcatdateatfatgapGathatiatjatkatlatmapNatnatoatpatqatrapNatsattatuatvatwatxatyatzatAatBaoJatCatDatEatFanHatGatGatGatGatGaaaaaaaaaaaaaabarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasKaptaptaptapwaptaptapxaptaptasLaaaaaaaaaalwaaaasMasNasNasNasNasOasPasQasRasRasRasRasSaaaalwaaaaaaaaaasTasUasVasWasXaaaaaaaaaaoOakBakWakWakWakWarGasZasYakWapGatbatcatdateatfatgapGathatiatjatkatlatmapNatnatoatpatqatrapNatsattatuatvatwatxatyatzatAatBaoJatCatDatEatFanHatGatGatGatGatGaaaaaaaaaaaaaabarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaabatHatHatHatHatHaaaatIaaaatHatHatHatHatHaabalwaaaaaaaaaatJatKatLatMatJatNatOatOatPatQatRatSatTatUatVatWatXatYapGapGatZauaapGapGaubapGaucaucaudaucaueaufapNaqJaugauhapQapRapNauiaujaukapSapSapSanAanAaulaumaunauoanAanHaupanHauqaurausausautaaaaaaaaaaaaaaaarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaaaaaaaabaaaaaaaaaauuaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaauvauwauxauyauzauAauBauCauAauDauDauEauFauGauHauIauJauKauLauMauNauOauPauQauRauSauTauUauVauWauXauYauZavaavbavcavdaveavfavgavhaviauSauWauSavjavkavlavmavnavoavpavqavravsavqavtavuavvavwaaaaaaaaaaaaaaaarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaaaaaaappaqfapraaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaabasbasbasbasbasbaaaatIaaaasbasbasbasbasbaabalwaaaaaaaaaatJavxavyavzatJatNatOatOatOavAavBavCavDavEavFavFavGavHavIavJavKavLavMavNavOavPavQavRavPavSavTavMavUavVavWavXavMavYavZavMavYawaawbawcawdavOaweawfawgawhawiawjawkavrawlavqawmausausawnaaaaacawoaacaaaarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaabaabappaqfapraabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaabasbasbasbasbasbaaaatIaaaasbasbasbasbasbaabalwaaaaaaaaaatJavxavyavzatJatNatOatOatOavAavBavCavDavEavFavFavGavHavIavJavKavLavMavNavOavPavQavRavPavSavTavMavUavVavWavXavMavYavZavMavYawaawbawcawdavOaweawfawgawhawiawjawkavrawlavqawmausausawnaaaafOawoafOaaaarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaabaabappaqfapraabaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawpawqawrawsawtaaaawuawvawwawxawyapoaaaasMasNasNasNasNasOasPasQasRasRasRasRasSaaaalwaaaaaaaaaatJawzawzawAatJaaaaaaaaaawBawCawDawEawFawGawDawDawHawHawHawHawIawJawKawKawKawLawMawNawLawKawKawKawOawPawPawQawRawSawTawUawVawWawXawYawWawVawZaxaaxbaxcaxdaxeaxfavrawlaxgaxgatGaxhaxhaxhatGaxiatGaabarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraabaabaaaaabaoLaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaxkaxkaxkaxjaaaaxlaxmaxmaxmaxlalwaxnatHatHatHatHatHaaaatIaaaatHatHatHatHatHaabalwaaaaaaaaaauvaxoawzaxpatJatNatOatOatOaxqawDaxraxsaxtaxuaxvawHaxwaxxaxyaxzaxAaxBaxCaxDaxEaxFaxGaxHaxIaxJaxBaxKaxLaxLaxMaxNaxOaxPaxQawVaxRaxSaxTaxUawVaxVaxWaxXaxYaxZayaaxfavraybaycaydayeayfayfaygatGayhatGaabarVaabaaaappaqfapraaaaaaappaqfapraaaaaaappaqfapraaaaaaaaaaabarVaabaaaaaaayiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjayjayjayjaxjaaaaxlaykaylaykaxlalwaaaaaaaaaaabaaaaaaaaaauuaaaaaaaaaaabaaaaaaaaaalwaaaaaaaaaatJaymawzawzaynauAayoauCauAaypawDayqayraysaytayuawHayvaywayxayyayzayAayBayCayDayEayFayGayCayHayIayJaxLaxLaxMayKayLayMayNayOayPayQayRaySawVayTayUayVayWayVayXaxfavravqavqavqavqayYavqayZazaazbatGaraazcardaaaaaaaoLaabaabaabaabaoLaabaabaabaabaoLaabaabaabaabazdazeardaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjazfazgazhaxjaaaaxlaziazjazkaxlalwaabasbasbasbasbasbaaaatIaaaasbasbasbasbasbaabalwaaaaaaaaaatJazlazlazlatJatNatOazmazmaznazoazpazqazrazsaztawHazuazvazwazxazyazzazAazBazCazDazEazFazGazHazzazIaxLaxLaxMazJawUazKazLazMazNazOazPazQawVazRazSazTayWayVazUaxfazVazWazXazYazXazZaAaatGatGawlatGarVaAbaAcarbarbazcarbarbarbarbazcarbarbarbarbazcarbarbarbaAdaAeaAbarVaabaaaamWaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaaAfaAfaAgaAgaAgaAgaAgaAgaAfaAfaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjayjayjayjaxjaaaaxlaykaylaykaxlalwaaaaaaaaaaabaaaaaaaaaauuaaaaaaaaaaabaaaaaaaaaalwaaaaaaaaaatJaymawzawzaynauAayoauCauAataawDayqayraysaytayuawHayvaywayxayyayzayAayBayCayDayEayFayGayCayHayIayJaxLaxLaxMayKayLayMayNayOayPayQayRaySawVayTayUayVayWayVayXaxfavravqavqavqavqayYavqayZazaazbatGaraazcardaaaaaaaoLaabaabaabaabaoLaabaabaabaabaoLaabaabaabaabazdazeardaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjazfazgazhaxjaaaaxlaziazjazkaxlalwaabasbasbasbasbasbaaaatIaaaasbasbasbasbasbaabalwaaaaaaaaaatJazlazlazlatJatNatOazmazmaznazoazpazqazrazsaztawHazuazvazwazxazyazzazAazBazCazDazEazFazGazHazzazIaxLaxLaxMazJawUaypazLazMazNazOazPazQawVazRazSazTayWayVazUaxfazVazWazXazYazXazZaAaatGatGawlatGarVaAbaAcarbarbazcarbarbarbarbazcarbarbarbarbazcarbarbarbaAdaAeaAbarVaabaaaamWaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaaaaAfaAfaAgaAgaAgaAgaAgaAgaAfaAfaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaAhazgazhaxjaaaaxlaAiaykaykaxlalwaaaasMasNasNasNasNasOasPasQasRasRasRasRasSaaaalwaaaaaaaaaaAjaAkaAkaAkaAlaaaaaaaAmaAnaAoaAnaApaApaApaApaAqawHawHaArawHaAsaAtawKawKaAuawKaAvaAwawKaAuawKaAxaAyaAzaxLaAAaABaACaADaAEawVaAFaAGaAHaAIaAJaAKaALaAMaANayVaAOaxfaAPaAQaARaASaATaAUaAVaAWaAXaAYatGaAZazcaBaaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaBbaBcaBaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaAfaAfaBdaBeaBfaBgaBhaBiaBjaBfaAfaAfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaAhazgazhaxjaaaaxlaBkaykaBlaxlaabaBmatHatHatHatHatHaaaatIaaaatHatHatHatHatHaabalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBnaAnaAnaAnaBoaApaBpaBqaBrawHaBsaBtaBuaBvaBwaxBaBxaByaBzaBAaBBaBCaBDaBEaxBaBFaBGaxLaxLaxLaBHaBIaBJawVaBKaAFaBLaBMawVaBNaBOayVayWayVaBPaxfaAPayYaAQaAQaAQaBQavqaBRaBSaBTatGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaabaabaabaabaBUaabaabaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaAfaAfaAfaAfaBVaBgaBWaBgaBWaBXaBgaBgaBgaBYaAfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjazgazgazgaBZaaaaxlaBkaykaBlaxlalwaaaaaaaabaaaaabaaaaaaaCaaaaaaaaabaaaaabaaaaaaalwaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaBnaCbaAnaAnaCcaApaApaCdaCeawHayvaCfaCgaChaCiaCjaCkaClaCmaCnaCoaCpaCqaCraCsaCtaCuaCuaCuaCuaCuaCvaCwawVaCxaBLaAFaCyaCzaCAaCBaCzaCCaCDaCEaxfaAPaCFaCGaCGaCGaCHaCIaCJaCKaCLatGaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaabaabaabaCMaabaabaaaaaaaabaaaaabaabaaaaaaaaaaaaaaaaaaaaaaAfaCNaCOaCPaCQaCRaCSaCTaBgaBgaCUaCVaBgaCWaAfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaCXazgazgaCYaaaaxlaCZaykaykaDaalwalwalwaabaabaabaabaDbaDcaDbaabaabaabaabalwalwalwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAmaDdaDeaDfaDgaDhaDiaDjaDkawHaDlaDmaDnaDoazyazzaDpaDqazzaDraDsazzaDtaDuazzaDvaDwaDxaDyaxLaDzaxLaDAawVaDBaDCaDDaBLaDEaDFaDGaDHaDIaDJaDJaDKaDLaDMaDNaDNaDNaDOaDPaDQaDRaDRaDRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaabaabaDSaDTaDSaabaabaaaaabaaaaaaaabaabaaaaaaaaaaaaaaaaaaaAfaDUaDVaDWaDXaDYaDZaBgaBgaBgaEaaEbaBgaEcaAfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaEdazgaEeaxjaaaaxlaEfaykaykaxlaabaaaaabaaaaaaaabaaaaDbaEgaEhaaaaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEiaEiaEjaEjaEjaEkaElaEmaEnaEoaEpaEpaEpaEqaEraEsaEtaEtaEuaEtaEvaEwaEtaExaAxaAxaEyaEzaEAaEBaECaEBaECaEAawVawVawVawVawVaCzaEDaEEaEFaEGaEHaEIaEJaEKaDNaELaEMaENaDOaEOaEPaEQaERaDPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaaaDSaESaDSaaaaabaaaaabaaaaaaaaaaabaabaaaaaaaaaaaaaaaaAfaETaEUaCPaEVaEWaEXaEYaBgaEZaFaaFbaFcaAfaFdaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxjaEdazgaEeaxjaaaaxlaEfaykaykaxlaabaaaaabaaaaaaaabaaaaDbaEgaEhaaaaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEiaEiaEjaEjaEjaEkaElaEmaEnaEoaEpaEpaEpaEqaEraEsaEtaEtaEuaEtaEvaEwaEtaExaAxaAxaEyaEzaEBaEBaECaEBaECaEBawVawVawVawVawVaCzaEDaEEaEFaEGaEHaEIaEJaEKaDNaELaEMaENaDOaEOaEPaEQaERaDPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaabaaaaDSaESaDSaaaaabaaaaabaaaaaaaaaaabaabaaaaaaaaaaaaaaaaAfaETaEUaCPaEVaEWaEXaEYaBgaEZaFaaFbaFcaAfaFdaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFeaFfaFgaFfaFhaaaaFiaFjaykaFkaFiaabaaaaabaaaaaaaabaDbaDbaFlaFmaDbaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEiaFnaFoaFpaFqaFraFsaFtaFuaFvaFwaFxaFxaFyaFzaFzaFzaFzaFzaFAaFBaFCaFzaFzaFzaFzaFDaFEaFzaFzaFFaFGaFFaFHaFHaFIaFHaFJaFKaFLaFMaFNaFOaFPaFQaFRaFSavraDNaFTaFUaFVaDOaFWaFXaFYaFZaDPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaabaDSaDSaGaaDSaDSaabaaaaabaaaaaaaaaaaaaabaabaaaaaaaaaaaaaAfaGbaGcaCPaAfaCPaCPaGdaGeaAfaAfaAfaAfaAfaAfaabaabaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaFeaGfaFhaaaaaaaGgaFiaGhaFiaGiaabaaaaabaaaaaaaabaGjaGkaGlaGmaGjaGnaGnaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGoaGpaFFaGqaGraGsaGraGtaGuaGvaGwaGraGraGxaGraGraGraGraGraGyaGraGraGraGraGraGraGzaGAaGraGraGraGBaGraGCaFFaGDaFFaGEaGFaFLaGGaGHaFLaGIaGJaGKaFSaGLaDNaGMaGNaGOaGPaGQaGRaGSaERaDPaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabaGTaGUaGVaGWaGTaabaaaaabaaaaaaaabaaaaaaaabaabaaaaaaaGXaAfaCPaAfaCPaGYaGZaGYaHaaGYaGYaGYaHbaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaGnaGnaGnaGnaGnaGnaGnaGnaabaabaGjaHcaHdaHeaGjaHfaGnaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGoaHgaHhaHiaHjaHkaHlaHmaHnaHoaHpaHpaHqaHraHsaHtaHpaHpaHpaHuaHpaHpaHpaHpaHpaHpaHvaHwaHmaHmaHmaHxaHyaHzaHyaHAaHBaHCaHDaFLaFLaFLaFLaHEaHEaHEaFSavraDNaHFaFUaHGaDOaHHaHIaFYaHJaDPaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaabaGTaHKaHLaHMaGTaabaaaaabaaaaaaaabaaaaaaaGXaHNaGXaHNaGXaHbaGYaGYaGYaGYaGYaGYaGYaGYaGYaHOaHPaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaHQaHRaHQaaaaaaaaaaGnaHSaHTaHSaHUaHVaHWaGnaaaaaaaGjaHXaHYaHZaIaaHSaGnaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaEiaEiaEiaIbaIcaIdaIeaIeaIfaIgaIhaIhaIiaIjaIkaIlaImaImaIlaInaIlaIoaIoaIoaIoaIoaIoaIpaIoaIoaIqaIraIsaItaEjaIuaEjaIvaEjaEjayeaIwavqavqavqavqaIxavraDNaIyaFUaIzaDOaIAaGRaGSaERaDPaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaHQaIBaHQaaaaabaGTaICaIDaIEaGTaIFaIFaIFaIFaIFaHNaHNaHNaGXaIGaGYaHOaHPaHaaGYaHaaHaaHaaGXaIHaGXaGXaGXaGXaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaIIaIJaIIaaaaaaaabaGnaIKaILaHSaHSaIMaHSaGnaIIaIIaGjaGjaINaIOaIaaHSaGnaGnaIIaIIaIIaGnaGnaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaIbaIPaIQaIRaISaITaIgaIUaIVaIWaIjaIXaIlaIYaIZaJaaJbaJcaJdaJeaJfaJgaJhaJiaJjaJkaJlaJmaFFaFHaJnaJoaJpaJqaJraJqaJqaJqaJsaJqaJqaJqaJqaJtaJuaJvaJwaJxaJyaJzaJAaJBaJCaJDaDPaabaJEaJFaJFaJFaJFaJFaJGaabaabaaaaaaaaaaaaaHNaJHaHNaaaaIFaGTaGTaJIaJJaGTaJKaGYaGYaGYaHaaJLaGYaJMaGXaGYaGYaGYaJNaHaaGYaGXaJOaJPaGXaGYaJQaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJRaJSaJTaaaaJUaJVaJWaabaabaIIaHSaIIaaaaaaaabaGnaJXaJYaJZaKaaKbaKcaGnaKdaHSaKeaKfaKgaKhaKhaKhaKhaKhaKhaKhaKhaKiaGnaaaaKjaaaaaaaaaaaaaaaaaaaaaaaaaIbaKkaKlaKmaKnaKoaKpaKqaKraKsaIjaIXaIlaKtaKuaKvaJbaJcaKwaKxaKxaKxaKxaKxaJjaKyaJlaFzaFFaFHaEjaKzaKAaKBaKCaKBaKBaKDaKEaKFaKFaKFaKFaKFaKFaKGaKHaKIaKJaKKaKLaKMaKNaDPaDPaKOaKPaKQaKQaKQaKQaKQaKPaKOaabaaaaaaaaaaaaaHNaKRaKSaaaaIFaKTaKUaKVaKWaGYaGYaGYaHaaGYaHaaKXaGYaGYaGXaGYaKYaKZaKXaIHaGYaGXaLaaLbaGXaGYaLcaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLdaLeaLfaLeaLdaLgaLhaLgaLdaabaIIaLiaLjaaaaaaaGnaGnaGnaGnaGnaLkaLlaLmaLnaLoaLpaLpaLqaLraLraLsaLtaGnaHSaGnaGnaGnaLuaGnaaaaabaaaaaaaaaaaaaaaaaaaabaabaIbaLvaLwaLxaLyaLzaLAaLBaLCaKsaIjaIXaIlaLDaLEaLFaJbaLGaLHaKxaLIaKxaLJaLJaJjaKxaJlaFzaFFaLKaEjaLLaKAaLMaLNaLOaLPaLQaLRaLSaLTaLUaLVaLWaLXaLYaLZaMaaMbaMcaMdaMeaMfaMgaMhaKOaKPaKQaKQaKQaKQaKQaKPaKOaabaabaabaabaHNaHNaMiaMjaHNaIFaMkaGYaMlaGYaHbaGYaGXaGXaMmaGXaGXaMnaHaaHaaKXaMoaMpaGYaGXaGYaMqaMqaMqaMqaMqaMqaMqaMqaMqaMraMraMraMraacaMraMraabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaLeaMtaLeaMsaLgaMuaLgaMsaGnaIIaMvaMwaIIaIIaGnaHSaHSaHSaHSaHSaHSaHSaLkaLuaGnaGnaGnaGnaGnaMxaGnaGnaHSaMyaGnaMzaLuaGnaGnaGnaaaaaaaaaaaaaaaaMAaMAaMAaMAaMAaMAaMAaMAaMAaLAaMBaMCaMDaMEaMFaMGaMHaMIaMJaMKaJcaMLaKxaMMaMNaMOaMPaMQaMRaJlaFzaFFaFHaEjaAPaMSaMTaLNaLOaLPaMUaMVaMVaMVaMVaMVaMVaMVaMVaMVaMVaMWaMXaMYaMZaNaaNbaNcaNdaKPaKQaKQaKQaKQaKQaKPaKOaKOaKOaaaaaaaHNaGYaNeaNfaJKaHaaMoaKXaMlaGYaNgaGZaNhaIHaGYaGYaGYaGYaNiaGYaGYaMoaNjaGYaMnaGYaMqaNkaNlaNmaMqaNnaNoaNpaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaNqaNraNsaMsaNtaNuaNvaNwaNxaHSaNyaNzaNAaMyaNBaHSaGnaGnaGnaGnaGnaGnaGnaLuaGnaNCafOaNDaGnaNEaNFaNGaHSaNBaGnaNAaNHaKhaKiaNIaaaaaaaaaaaaaaaaNJaNKaNLaNMaNNaNOaNPaMAaiWaLAaNRaNSaNTaLAaNUaIlaNVaNWaNXaNYaJcaNZaKxaOaaObaOcaOdaOeaOfaOgaOhaOiaOjaOkaOlaOmaOnaLNaLOaLPaOoaMVaOpaOpaOpaMVaMVaOqaOraOraOsaMWaOtaOuaOvaOvaOwaOxaOyaOzaKQaKQaKQaKQaKQaOAaOBaOCaODaaaaaaaHNaGYaGYaOEaGYaHaaOFaGYaOGaOHaOHaOHaOHaOIaOHaOJaGYaGYaGYaGYaGYaGYaGYaGYaHaaGZaMqaOKaOLaOLaMqaOMaONaOOaMqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaOPaOQaORaMsaOPaOQaORaNwaKcaHSaOSaHSaHSaHSaHSaHSaGnaOTaOUaOVaOWaOXaGnaLuaGnafOaOYaNCaOZaPaaPbaGnaPcaGnaGnaGnaGnaPcaLuaNIaaaaHQaHQaHQaHQaPdaNKaPeaPfaPgaPhaPiaPjaMAaLAaPkaPlaPlaPlaPmaPnaPoaPnaPnaPnaPpaPqaPraPsaPtaPtaPtaPtaPuaPvaPwaFFaPxaEjaAPaPyaPzaLNaLOaLPaMUaOpaPAaPAaPBaOpaMVaPCaPDaPDaPEaPFaOtaPGaPHaPIaPJaMVaPKaODaKQaKQaKQaKQaKQaODaPLaPMaODaabaabaGXaGYaGYaHaaHaaHaaHPaHPaGXaGXaGXaHaaHaaHaaGXaPNaPOaGXaHaaHaaGXaHaaHaaGXaGXaPPaPQaPRaPSaPTaPUaPVaOKaPWaMqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPXaPYaLdaMsaPZaQaaLdaMsaPZaQaaLdaGnaLkaGnaGnaGnaGnaGnaHSaGnaHSaQbaQcaHSaHSaGnaLuaGnaQdaabaQdaGnaJYaPbaGnaQeaQfaGnaNAaKcaGnaLuaMAaMAaQgaQgaQgaQgaQgaQgaQgaQgaQgaPiaPiaPjaQhaQiaQjaQkaQlaQmaQnaQoaQpaQpaQpaQpaQqaQraQsaQtaQuaQpaQpaQvaQvaQwaQxaQyaQzaQAaQBaPyaQCaQDaQDaLPaMUaOpaPAaQEaQFaOpaMVaPCaPDaPDaPEaQGaOtaPGaPIaPIaPJaMVaPKaODaKQaKQaKQaKQaKQaODaQHaPMaODaaaaaaaGXaQIaGYaGYaQJaHaaQKaHOaQLaQMaHbaGXaOFaHbaGXaQNaGYaGXaQOaGYaGXaQPaQQaQRaOHaQSaOHaQTaQUaQVaQWaQXaQYaQZaMqaMraMraacaacaMraMraMraMraabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaaRbaOQaRbaRcaRcaRcaRdaRcaRcaRcaReaRfaRgaRgaRgaRgaRhaGnaHSaGnaRiaRjaRkaHSaRlaPcaLuaGnaGnaGnaGnaGnaGnaPcaGnaHSaRkaLkaHSaHSaHSaNQaRnaRoaRpaRpaRpaRpaRqaRpaRpaRraRsaRoaRtaRuaRuaRuaRuaRuaRuaRuaRvaRwaRwaRwaRwaRxaRyaRwaRzaRwaRAaRxaRwaRwaRwaRwaRBaRCaRDaREaRFaOmaRGaRHaQDaRIaMUaOpaRJaRKaRLaOpaMVaRMaRNaRNaROaMWaOtaRPaRQaRQaRRaMVaRSaRTaKQaKQaKQaKQaKQaRUaRVaRWaODaaaaaaaGXaGYaGYaGYaGYaGYaGYaQRaOHaOHaOHaOHaOHaOHaOHaKVaGYaGYaGYaGYaMnaGYaGYaMlaGYaRXaRYaRZaSaaSbaOLaOLaOLaScaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYaPYaSdaSeaSfaSgaShaSiaSjaSkaSlaSjaSmaSnaSjaSjaSoaGnaHSaGnaSpaHSaHSaSqaSraGnaNHaKiaHSaHSaHSaHSaHSaHSaPcaSsaHSaGnaNxaNxaGnaRmaMAaSuaSvaSwaSwaSwaSxaSwaSwaSwaSyaSuaSzaSAaSAaSAaSAaSAaSAaSAaPiaRwaSBaSCaSDaSEaSFaSGaSHaSIaSJaSKaSLaSCaSMaRwaSNaFFaSOaEjaSPaPyaSQaSRaSRaSSaSTaSUaSVaSWaSWaSXaSYaSZaSXaSYaSYaTaaTbaTcaMVaMVaTdaMVaTeaTfaKQaKQaKQaKQaKQaTfaKOaKOaKOaGXaGXaGXaHbaHaaHaaIHaGXaGXaMlaHaaGXaTgaHaaGXaIHaGXaMlaQIaHaaGXaIHaGXaGYaQIaMlaGYaThaMqaTiaQUaTjaTkaTlaQUaTmaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaSdaTnaSdaToaSfaSfaTpaSdaTnaSdaTqaTraTsaTtaGnaHSaPcaPcaGnaGnaGnaTuaTuaTuaIkaTuaTuaTuaTuaTuaHSaGnaGnaGnaGnaGnaGnaGnaRmaKdaStaaaaabaaaaabaaaaabaaaaabaaaaSuaSzaSAaTwaTxaTyaTzaTAaSAaPiaRwaTBaTBaTCaTDaTEaTFaTGaTFaTHaTIaTJaTBaTBaRwaSNaFFaTKaEjaSPaPyaPzaLNaLOaLPaMUaTLaTMaTNaTOaTPaTPaTQaTRaTPaTRaTSaTTaTUaTVaTWaTXaTYaKOaTfaKQaKQaKQaKQaKQaTfaGXaLcaGYaTZaUaaHaaGXaHaaLcaGYaGXaLcaMlaGXaUbaGYaGXaUcaGYaHaaUdaUeaGXaUfaGYaHaaIHaIHaMlaIHaUgaMqaUhaQUaUiaUjaUiaQUaUkaMqaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaUlaLdaUmaOQaSdaUnaUoaUpaUqaSdaOQaUraPYaLdaUsaUtaGnaHSaHSaHSaHSaHSaHSaTuaUuaUvaUwaUxaUyaUzaUuaTuaTvaUBaUAaUAaUAaUAaUAaUAaUCaNxaStaabaUEaUEaUEaUEaUEaUEaUEaabaSuaSzaSAaUFaUGaUHaUIaUFaSAaPiaRwaUJaUJaUJaUKaULaSCaUMaSCaULaUNaUJaUJaUJaRwaSNaFFaUOaEjaSPaPyaOnaLNaLOaLPaOoaUPaUQaUQaUQaUQaUQaUQaUQaURaUQaUSaUSaUSaUSaUSaUTaGXaKOaTfaKQaKQaKQaKQaKQaTfaGXaGXaGYaUUaUaaHaaUVaGXaGYaGYaGXaGYaMlaHaaGYaGYaGXaGYaGYaHaaMlaGZaGXaGYaGYaHaaUWaGYaMlaGYaUXaUYaUYaMqaMqaMqaMqaMqaMqaMqaMraMraMraMraMraabaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYaTnaSdaSdaSdaSdaSdaSdaTnaPYaUZaLdaVaaVbaVcaVcaVcaVcaVcaVcaVdaTuaUuaVeaUwaVfaVeaVeaUuaTuaVgaUDaViaViaViaViaViaViaViaViaVjaaaaUEaVkaVlaVmaVnaVoaUEaaaaSuaSzaSAaVpaVqaVraVsaUFaSAaPiaRwaVtaVtaTCaVuaVvaTFaTGaTFaVvaVwaVxaTBaTBaRwaSNaFFaSOaEjaVyaKAaVzaLNaLOaLPaMUaUPaUQaVAaVBaVCaVCaUQaVDaVEaVFaUSaVGaVHaVIaUSaVJaGXaaaaVKaVLaVLaVLaVLaVLaVMaaaaGXaGYaVNaVOaHaaHaaGXaGXaHaaHaaVPaVQaHaaGXaHPaGXaGXaHaaHaaVRaVSaGXaGXaGXaQLaUWaGYaMlaGYaUXaHOaHbaOFaYPbcDaVhbcDaYPaYPaYPaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaVWaVXaVWaVWaVYaVZaVWaVWaVXaWaaWbaLdaToaWcaVcaWdaWeaWfaWgaWhaWiaTuaUuaVeaUwaWjaVeaVeaUuaTuaWkaWlaWmaWnaWoaWpaWqaWraWsaWtaVjaabaUEaWuaWvaWwaWxaWyaUEaabaSuaSzaSAaWzaWAaWBaWCaWDaSAaPiaRwaSBaSCaWEaWFaULaSCaWGaSCaULaWHaWIaSCaSMaRwaSNaFFaWJaEjaSPaMSaMTaLNaLOaLPaWKaWLaUQaWMaVEaVEaVEaWNaWOaWPaWQaUSaWRaWSaWTaWUaWVaHPaaaaaaaaaaaaaaaaaaaaaaaaaaaaGXaWWaWXaWYaWZaXaaGXaNgaGYaQIaMlaGYaGXaaaaGXaGYaGYaGYaGYaMlaXbaXcaXdaXdaXdaXdaXeaXfaXgaXhaXiaXjaXiaXkaVTaVTaVUaXmaXlaXnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLdaLeaLfaLeaLdaLgaLhaLgaLdaabaIIaLiaLjaaaaaaaGnaGnaGnaGnaGnaLkaLlaLmaLnaLoaLpaLpaLqaLraLraLsaLtaGnaHSaGnaGnaGnaLuaGnaaaaabaaaaaaaaaaaaaaaaaaaabaabaIbaLvaLwaLxaLyaLzaLAaLBaLCaKsaIjaIXaIlaLDaLEaLFaJbaLGaLHaKxaLIaKxaLJaLJaJjaKxaJlaFzaFFaLKaEjaLLaKAaLMaPzaLNaLPaLQaLRaLSaLTaLUaLVaLWaLXaLYaLZaMaaMbaMcaMdaMeaMfaMgaMhaKOaKPaKQaKQaKQaKQaKQaKPaKOaabaabaabaabaHNaHNaMiazKaHNaIFaMkaGYaMlaGYaHbaGYaGXaGXaMmaGXaGXaMnaHaaHaaKXaMoaMpaGYaGXaGYaMqaMqaMqaMqaMqaMqaMqaMqaMqaMraMraMraMrafOaMraMraabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaLeaMtaLeaMsaLgaMuaLgaMsaGnaIIaMvaEAaIIaIIaGnaHSaHSaHSaHSaHSaHSaHSaLkaLuaGnaGnaGnaGnaGnaMxaGnaGnaHSaMyaGnaMzaLuaGnaGnaGnaaaaaaaaaaaaaaaaMAaMAaMAaMAaMAaMAaMAaMAaMAaLAaMBaMCaMDaMEaMFaMGaMHaMIaMJaMKaJcaMLaKxaMMaMNaMOaMPaMQaMRaJlaFzaFFaFHaEjaAPaMSaLOaPzaLNaLPaMUaMVaMVaMVaMVaMVaMVaMVaMVaMVaMVaMWaMXaMYaMZaNaaNbaNcaNdaKPaKQaKQaKQaKQaKQaKPaKOaKOaKOaaaaaaaHNaGYaNeaNfaJKaHaaMoaKXaMlaGYaNgaGZaNhaIHaGYaGYaGYaGYaNiaGYaGYaMoaNjaGYaMnaGYaMqaNkaNlaNmaMqaNnaNoaNpaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaNqaNraNsaMsaNtaNuaNvaNwaNxaHSaNyaNzaNAaMyaNBaHSaGnaGnaGnaGnaGnaGnaGnaLuaGnaNCafOaNDaGnaNEaNFaNGaHSaNBaGnaNAaNHaKhaKiaIIaaaaaaaaaaaaaaaaNJaNKaNLaNMaNNaNOaNPaMAaiWaLAaNRaNSaNTaLAaNUaIlaNVaNWaNXaNYaJcaNZaKxaOaaObaOcaOdaOeaOfaOgaOhaOiaOjaOkaOlaOmaMTaPzaLNaLPaOoaMVaOpaOpaOpaMVaMVaOqaOraOraOsaMWaOtaOuaOvaOvaOwaOxaOyaMjaKQaKQaKQaKQaKQaMwaOBaOCaODaaaaaaaHNaGYaGYaOEaGYaHaaOFaGYaOGaOHaOHaOHaOHaOIaOHaOJaGYaGYaGYaGYaGYaGYaGYaGYaHaaGZaMqaOKaOLaOLaMqaOMaONaOOaMqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaMsaOPaOQaORaMsaOPaOQaORaNwaKcaHSaOSaHSaHSaHSaHSaHSaGnaOTaOUaOVaOWaOXaGnaLuaGnafOaOYaNCaOZaPaaPbaGnaPcaGnaGnaGnaGnaPcaLuaIIaaaaHQaHQaHQaHQaPdaNKaPeaPfaPgaPhaPiaPjaMAaLAaPkaPlaPlaPlaPmaPnaPoaPnaPnaPnaPpaPqaPraPsaPtaPtaPtaPtaPuaPvaPwaFFaPxaEjaAPaPyaOnaPzaLNaLPaMUaOpaPAaPAaPBaOpaMVaPCaPDaPDaPEaPFaOtaPGaPHaPIaPJaMVaPKaODaKQaKQaKQaKQaKQaODaPLaPMaODaabaabaGXaGYaGYaHaaHaaHaaHPaHPaGXaGXaGXaHaaHaaHaaGXaPNaPOaGXaHaaHaaGXaHaaHaaGXaGXaPPaPQaPRaPSaPTaPUaPVaOKaPWaMqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNIaSdaSdaLdaMsaPZaQaaLdaMsaPZaQaaLdaGnaLkaGnaGnaGnaGnaGnaHSaGnaHSaQbaQcaHSaHSaGnaLuaGnaQdaabaQdaGnaJYaPbaGnaQeaQfaGnaNAaKcaGnaLuaMAaMAaQgaQgaQgaQgaQgaQgaQgaQgaQgaPiaPiaPjaQhaQiaQjaQkaQlaQmaQnaQoaQpaQpaQpaQpaQqaQraQsaQtaQuaQpaQpaQvaQvaQwaQxaQyaQzaQAaQBaPyaQCaPzaLNaLPaMUaOpaPAaQEaQFaOpaMVaPCaPDaPDaPEaQGaOtaPGaPIaPIaPJaMVaPKaODaKQaKQaKQaKQaKQaODaQHaPMaODaaaaaaaGXaQIaGYaGYaQJaHaaQKaHOaQLaQMaHbaGXaOFaHbaGXaQNaGYaGXaQOaGYaGXaQPaQQaQRaOHaQSaOHaQTaQUaQVaQWaQXaQYaQZaMqaMraMrafOafOaMraMraMraMraabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaRaaRbaOQaRbaRcaRcaRcaRdaRcaRcaRcaReaRfaRgaRgaRgaRgaRhaGnaHSaGnaRiaRjaRkaHSaRlaPcaLuaGnaGnaGnaGnaGnaGnaPcaGnaHSaRkaLkaHSaHSaHSaNQaRnaRoaRpaRpaRpaRpaRqaRpaRpaRraRsaRoaRtaRuaRuaRuaRuaRuaRuaRuaRvaRwaRwaRwaRwaRxaRyaRwaRzaRwaRAaRxaRwaRwaRwaRwaRBaRCaRDaREaRFaOmaRGaRHaQDaRIaMUaOpaRJaRKaRLaOpaMVaRMaRNaRNaROaMWaOtaRPaRQaRQaRRaMVaRSaOzaKQaKQaKQaKQaKQaOAaRVaRWaODaaaaaaaGXaGYaGYaGYaGYaGYaGYaQRaOHaOHaOHaOHaOHaOHaOHaKVaGYaGYaGYaGYaMnaGYaGYaMlaGYaRXaRYaRZaSaaSbaOLaOLaOLaScaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPXaSdaSdaPYaSfaSgaShaSiaSjaSkaSlaSjaRTaSnaSjaSjaSoaGnaHSaGnaSpaHSaHSaSqaSraGnaNHaKiaHSaHSaHSaHSaHSaHSaPcaSsaHSaGnaNxaNxaGnaRmaMAaSuaSvaSwaSwaSwaSxaSwaSwaSwaSyaSuaSzaSAaSAaSAaSAaSAaSAaSAaPiaRwaSBaSCaSDaSEaSFaSGaSHaSIaSJaSKaSLaSCaSMaRwaSNaFFaSOaEjaSPaPyaSRaSQaVzaSSaSTaSUaSVaSWaSWaSXaSYaSZaSXaSYaSYaTaaTbaTcaMVaMVaTdaMVaTeaTfaKQaKQaKQaKQaKQaTfaKOaKOaKOaGXaGXaGXaHbaHaaHaaIHaGXaGXaMlaHaaGXaTgaHaaGXaIHaGXaMlaQIaHaaGXaIHaGXaGYaQIaMlaGYaThaMqaTiaQUaTjaTkaTlaQUaTmaMqaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaSdaRUaSdaToaSfaSfaTpaSdaRUaSdaTqaTraTsaTtaGnaHSaPcaPcaGnaGnaGnaTuaTuaTuaIkaTuaTuaTuaTuaTuaHSaGnaGnaGnaGnaGnaGnaGnaRmaKdaStaaaaabaaaaabaaaaabaaaaabaaaaSuaSzaSAaTwaTxaTyaTzaTAaSAaPiaRwaTBaTBaTCaTDaTEaTFaTGaTFaTHaTIaTJaTBaTBaRwaSNaFFaTKaEjaSPaPyaOnaPzaLNaLPaMUaTLaTMaTNaTOaTPaTPaTQaTRaTPaTRaTSaTTaTUaTVaTWaTXaTYaKOaTfaKQaKQaKQaKQaKQaTfaGXaLcaGYaTZaUaaHaaGXaHaaLcaGYaGXaLcaMlaGXaUbaGYaGXaUcaGYaHaaUdaUeaGXaUfaGYaHaaIHaIHaMlaIHaUgaMqaUhaQUaUiaUjaUiaQUaUkaMqaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaLdaLdaSdaOQaSdaUnaUoaUpaUqaSdaOQaSdaSdaLdaSmaTnaGnaHSaHSaHSaHSaHSaHSaTuaUuaUvaUwaUxaUyaUzaUuaTuaTvaUBaUAaUAaUAaUAaUAaUAaUCaNxaStaabaUEaUEaUEaUEaUEaUEaUEaabaSuaSzaSAaUFaUGaUHaUIaUFaSAaPiaRwaUJaUJaUJaUKaULaSCaUMaSCaULaUNaUJaUJaUJaRwaSNaFFaUOaEjaSPaPyaMTaPzaLNaLPaOoaUPaUQaUQaUQaUQaUQaUQaUQaURaUQaUSaUSaUSaUSaUSaUTaGXaKOaTfaKQaKQaKQaKQaKQaTfaGXaGXaGYaUUaUaaHaaUVaGXaGYaGYaGXaGYaMlaHaaGYaGYaGXaGYaGYaHaaMlaGZaGXaGYaGYaHaaUWaGYaMlaGYaUXaUYaUYaMqaMqaMqaMqaMqaMqaMqaMraMraMraMraMraabaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdaRUaSdaSdaSdaSdaSdaSdaRUaSdaUZaLdaVaaVbaVcaVcaVcaVcaVcaVcaVdaTuaUuaVeaUwaVfaVeaVeaUuaTuaVgaUDaViaViaViaViaViaViaViaViaVjaaaaUEaVkaVlaVmaVnaVoaUEaaaaSuaSzaSAaVpaVqaVraVsaUFaSAaPiaRwaVtaVtaTCaVuaVvaTFaTGaTFaVvaVwaVxaTBaTBaRwaSNaFFaSOaEjaVyaKAdqtaPzaLNaLPaMUaUPaUQaVAaVBaVCaVCaUQaVDaVEaVFaUSaVGaVHaVIaUSaVJaGXaaaaVKaVLaVLaVLaVLaVLaVMaaaaGXaGYaVNaVOaHaaHaaGXaGXaHaaHaaVPaVQaHaaGXaHPaGXaGXaHaaHaaVRaVSaGXaGXaGXaQLaUWaGYaMlaGYaUXaHOaHbaOFaYPbcDaVhbcDaYPaYPaYPaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaVWaVXaVWaVWaVYaVZaVWaVWaVXaWaaWbaLdaToaWcaVcaWdaWeaWfaWgaWhaWiaTuaUuaVeaUwaWjaVeaVeaUuaTuaWkaWlaWmaWnaWoaWpaWqaWraWsaWtaVjaabaUEaWuaWvaWwaWxaWyaUEaabaSuaSzaSAaWzaWAaWBaWCaWDaSAaPiaRwaSBaSCaWEaWFaULaSCaWGaSCaULaWHaWIaSCaSMaRwaSNaFFaWJaEjaSPaMSaLOaPzaLNaLPaWKaWLaUQaWMaVEaVEaVEaWNaWOaWPaWQaUSaWRaWSaWTaWUaWVaHPaaaaaaaaaaaaaaaaaaaaaaaaaaaaGXaWWaWXaWYaWZaXaaGXaNgaGYaQIaMlaGYaGXaaaaGXaGYaGYaGYaGYaMlaXbaXcaXdaXdaXdaXdaXeaXfaXgaXhaXiaXjaXiaXkaVTaVTaVUaXmaXlaXnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaWaaVWaXqaXraXsaXtaXuaXvaXwaXxaXyaXzaXAaXBaSdaToaXCaVcaXDaXEaXFaXGaXFaXHaTuaXIaVeaXJaXKaXLaXKaXMaXNaXOaXPaXQaXQaXQaXQaXQaXQaXRaXSaVjaaaaUEaXTaWvaXUaWxaXVaUEaaaaSuaSzaSAaXWaXXaXYaXZaYaaSAaPiaRwaYbaYbaTCaYcaVvaTFaYdaTFaVvaYeaTJaYfaYfaRwaYgaIraYhaEjaSPaMSaYiaYiaYiaYiaYjaYkaYlaYmaYnaYoaYoaYoaYpaYoaYqaYraYsaYtaYuaYraYvaYwaHPaGXaGXaGXaGXaGXaGXaGXaGXaGXaGXaGXaGXaYxaGXaGXaGXaGXaGYaMlaWWaHNaabaHNaGYaYyaYzaYAaYBaYCaYDaYEaYEaYEaYEaYFaYGaYHaYIaYJaYKaYJaYLaYJaYJaYMaXoaYOaYPaYQaYRaYSaYSaYSaYSaYSaYSaYSaYSaYSafXajcaaaaaaaaaaaaaaaaaaaaaaYTaYUaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXAaYWaYXaYYaXzaYZaXsaYZaXsaYZaXsaYZaXzaZaaZbaSdaToaZcaVcaZdaZeaZfaZgaZhaZiaTuaZjaVeaZkaZlaZmaZnaZoaTuaZpaZqaXQaXQaXQaXQaXQaXQaXRaZraVjaabaUEaZsaZtaZuaZvaZwaUEaabaSuaSzaSAaZxaZyaZzaZAaZBaSAaPiaRwaUJaUJaUJaZCaULaSCaUMaSCaULaZDaUJaUJaUJaRwaZEaZFaZGaEjaVyaZHaZIaZIaZIaZJaZKaZLaZMaZNaZOaZMaZPaZQaZRaZMaZSaZTaZUaZVaZWaUSaZXaZYaZZbaabaaaZYbabbacbacbacbacbacbadbaebacbafbagbahbaibajbakbalbambanbaobanbapbaqaGYaGXbarbasbatbaubavbawbaxbaybazbaAbazbaBbaCbaDbaEbaFbaGbaHbaIbaJbaKbaLaYPbaMbaNbaObaPbaQbaRbaSbaTbaUbaVaaaaaaaaaaaaaaaaaaaaaaYTbaWbaXbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaZaXsaXsaVXaXzaYZaXsaYZbbaaYZaXsaYZaXzaZaaZbaSdaTobbbaVcaVcbbcbbdbbebbdaVcaTuaTuaTuaTubbfbbgbbhbbiaTubbjbbkbblaXQaXQbbmaXQbbnbbobbpaVjaaaaUEaUEbbqbbrbbqaUEaUEaaaaSuaSzaSAbbsbbtbbuaZAbbvaSAaPiaRwaSBaSCbbwaWFaULaSCaUMaSCaULaWHbbxaRwaRwaRwbbybbzbbAbbBbbCbbDatGatGbbEbbFbbGbbHaUQbbIaVEaUQbbJaUQbbKaUQbbLbbMbbNbbObbPbbQbbRbbSbbTbbUbbVbbWbbXbbVbbVbbYbbVbbSbbZbbSaXjbcabbSbcbbccbcdbcebcfbcgbchbcibcjbckbclaXibcmbcnbcobcpbcqbcrbcsbctbaybcubcvbazbcwbcxbcybczbaFbcAbcBbcCbcDbcEbcFaYPbcGbcHbcHbcIbaTbaTbaTbaTbaUbaVaaaaaaaaaaaaaaaaaaaYTbaWbcJbcKbcLbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXAbcMbcNaYYaXzaYZaXsaYZaXsaYZaXsaYZaXzaZaaZbaSdaTobcObcPbcQbcRbcSbcSaSfbcTbcUbcVbcWbcXbcYbcZaVebdaaTubdbbdcbddbdebdfbdgbdhbdibdjbdkaVjaaaaabaaabdlbdmbdlaaaaabaaaaSuaSzaSAbdnbdobdpbdqbdraSAaPiaRwbdsbdtaTCbdubdvaTFbdwaTFbdxbdybdzaRwbdAbdBbdCbdDbdEbdFbdGbdHaaaaaabbEbdIbdJbdKaUQbdLbdMaVEaVEbdNaVEaVEaVEbdOaUSbdPaUSbdQbdRaUSbdSaUSbdTbdUbdVbdWbdXbdYbdTbdZbeabebbecbebbebbebbebbedbeebebbefbegbehbeibebbejaGYbaubekbcpbelbembenbeobepbeqberbesbazbetbeubevbewbexbcAbcBbcCbcDbaKbeyaYPbezbcHbcHbcIbaTbaTbaTbaTbaUbaVaaaaaaaaaaaaaaaaaaaYUbeAbeBbeCbeBbeDaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeEbeFaVWaXqaXzaXsbeGbeHaXsaXsbeIbeGaXzaXAbeJaSdaTobeKbeLbeMbeNbeMbeMbeMbeMbeMbeOaSfaTubePbeQbePaTuaTubeRbeSbeRaViaViaViaVibeRbeTbeUaVjbeVbeWbeWbeXbeYbeXbeWbeWbeZaSubfaaSAbfbaSAbfcbfdbfeaSAbffaRwaRwaRwaRwbfgbfhbfibfjbfibfhbfgaRwaRwbfkbdDbdDbdDbdDbflbfmbfnbfobfpbbEbfqbdJbfraUQaUQaUQaUQaUQaUQaUQaUSaUSbdObfsbftbfubfvbfwbfxbfybfzbdTbfAbfBbfCbfDbfEbdTbfFbfGbfHbfIbfHbfJbfKbfLbfMbfNbfObfPbfQbfRbfSbebbfTbfUbfVbfWbfXbelbfYbfZbeobgabazbgbbgcbgdbgebgfbczbczbazbazbcBbcCbcDbcEbggaYPbghbgibgjbgkbglbgmbaTbaTbgnbaVaaaaaaaaaaaaaaaaYTbaWbgobeCbeCbeCbgpbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeEaVWaVXaVWaVWaVYaVZaVWaVWaVXbeFbgqaLdbgrbeKaPYbgsbgsbgtbgsbguaMsbgvbgwaSfbgxbgybgzbgzbgAbgBbgzbgCbgzbgzbgzbgDbgzbgzbgEbgFbgGbgHbgIbgJbgHbgKbgHbgHbgHbgHbgLbgMbgNbgzbgzbgObgPbgQbgRbgSbgTbgUbgVbgWbgXbgXbgXbgXbgXbgXbgXbgYbgZbhabhbbhcbhdbhebhfbhgbhhbdDbdDbhibhjbhkbhjbhkbhlbhmbhnbhobhpbhqaUSbhrbhsbhtbhubhvbhvbhwbhxbhybhzbdTbhAbhBbhCbhCbhDbdTbhEbhFbhGbhHbhIbhIbhJbhKbhLbhMbhNbhObhPbhQbhRbebbejaTgbaubhSbhTbhTbhUbhVbhTbhWbazbhXbhYbazbhZbiabczbibbazbicbidbiebcDaYPaYPaYPbifbigbihbiibigbigbigbigaYSafXajcaaaaaaaaaaaabijbikbilbeCbeCbimbinbeCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYbioaSdaSdaSdaSdaSdaSdbioaPYaUZaLdbipbiqaPYbirbisbitbitbiuaMsbivbgwbiwbixbgybiybizbiAbiBbiBbiCbiDbiDbiDbiEbiFbiFbiGbiHbiIbiBbiBbiJbiFbiKbiLbiMbiMbiNbiObiPbiQbiQbiQbiRbgPbgQbgRbgSbgSbgSbgSbiSbgSbgSbgSbgSbgSbgSbiTbiUbiVbiWbiXbiYbiZbjabjbbjcbiVbiVbiVbjdbjebjebjebjfbhqbhqbhqbjgbjhbhqaUSbjibjjbhvbhvbjkbhvbjlbjmbhybjnbdTbjobjpbjqbjrbjsbdTbjtbjubjvbjwbjxbjybebbebbjzbjAbebbebbjBbjCbjBbebbejaGYbaubjDbcpbcpbcpbjEbcpbjFbazbazbazbazbazbazbazbjGbazbcDbcDbcCbcDbjHbjIaYPbjJbjNbjLblwbjKbjObjPbjQbjRaaaaaaaaaaaaaYTbjSbjTbjSbjSbjSbjUbjSbjVbjSbjTbjSaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaUlaLdaPYaOQaSdbjWbjXbjYbjZaSdaOQaPYaPYaLdbkabeKaPYbkbbkcbitbitbiuaMsbkdbgwaSfbixbgybgzbkebkfbkgbkgbkhbkibkjbkgbkkbkgbklbkgbkmbknbkgbkgbkgbkgbkgbkobkpbkgbkqbkrbksbktbgzbgzbkubkvbkwbkxbkybkzbkybkAbkBbkAbkAbkAbkAbkAbkAbkCbkDbkEbkEbkEbkEbkFbkEbkGbkHbkEbkEbkIbkJbkKbkKbkKbkKbkKbkKbkKbkLbhqbhqaUSbkMbkNbkObkPbkPbkQbkRbjmbhybkSbdTbdTbdTbdTbdTbkTbdTbkUbkVbkWbkXbfHbkYbebbkZblablbblcbldbleblfblgbebbejaQLbaublhblibcpbljblkbcpbllbllbaublmblnbloaYPblpblqblrbcDbcDblsbltaYPbluaYPblvbjKbjLblxblybjKbjKblzbjRaaaaaaaaaaaabijbmXbnabmYbmYblDbeCblCblDblAblBblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaPYbioaSdaToaSfaSfaTpaSdbioaSdblEblFblGblHaPYblIblIbgtblIbguaMsblJbgwaSfaMsblKblKblLblMblMblMblMblMblMblNblOblMblMblMblMblMblMblPblQblRblRblSblRblTblUblVblTblTblWblXblYblKblZblZbmabmabmabmbbmbbmbbmbbmbbmbbmbbmbbmcbmdbmdbmebmdbmfbmfbmfbmfbmgbmhbmfbmcbmibmibmibmibmibmibmibmibmjbmjbmjaUSbmkbmlbmmbmmbmmbmmbmnbmobmpbmqbmrbmsbmtbmubmvbmwbdTbdTbmxbmybmzbmybmybebbmAbmBbmCbmDbmDbmDbmEbmFbebbmGbmHbaubmIbcpbljbljblkbljbcpbmJbaubmKbmLbmMaYPbcDbmNbmObmPbmPbmQbmRbmSbmTbmUbmVbmWboObzpbjMbjKbjKblzbjRbjRbjRbjRbjRbijbBTbDzbDzbDzbBVbeCblCbnbblAbeCbncbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabndbneaSfbnfbngbnhbnibnjbnkbnibnlbnmbnibnibnnbnobnpbnqbnrbnrbnrbnsbnrbntbnuaMsbnvbnwbnxblMbnybnzbnAbnBbnCbnDbnEbnFbnGbnHbnIbnJblMbnKbnLblRbnMbnNbnOblTbnPbnQbnRblTbnSbnTbnUbnSbnSbnSbnVbgSbnWbmbaaaaaaaaaaaaaaaaaaaaabmcbnXbnYbnZboabobbocbodboebofbogbohbmcaaaaaaaaaaaaaaaaaaaaabmiboibhqbojaUSbokbmlbmqbmqbmqbmqbmqbolbombmqbmqbmqbonbooboobopboqborbosbotboubovbowbebboxboybozboAboAboBboCboDbebbejaGYbauboEboFbcpbljblkbcpboGboGbaubauboHbauaYPboIblqbltboJboJboKbltaYPaYPaYPboLbjKbEFbDubjMbjKbjKbmZbAMbrKbrMbrMbrKbDvbDzbDzbGJbGJbnbbeCblCbnbblAbeCblCaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabndboPboQboPboPboPboPboPboPboQboPboPboRaSfboSboTboUaSfboVaSfboWboXboYboZbpaaMsbnwbnwbpbblMbpcbnDbnDbnDbnDbnDbnEbpdbnDbnDbnDbpeblMbnKbpfblRbpgbphbpiblTbpjbpkbplblTbpmbpnbpobppbpqbnTbnVbgSbnWbmbaaaaaaaaaaaabmcbmcbmcbmcbprbpsbptbpubpvbpwbpxbpybpzbpAbpBbmcbmcbmcbmcaaaaaaaaaaaabmiboibhqbpCbpDbpEbpFbpGbpHbpEbpIbpJbpKbpLbpMbpNbmqbpObpPboobpQbpRboobpSbpTbpUbpVboobpWbpXbpYbozboAboAboBbpZbqabebbejaTgbaubmIbcpbljbljblkbljbcpbcpbqbbqcbcpbqdaYPbqebqfbqgboJboJbqhbqgbqiaYPbqjbqkbjKbDybDybEHbEIbDybDybjRbqnbjRbjRbjRbEJbjSbjSbjSbjSbqobeCblCbqoblAbeCblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLdaLdaPYaPYaPYaPYaPYaPYaPYaPYaPYaLdaMsbqpbqqbqrbqrbqrbqrbqrbqrbqsbqrbqrbqraMsbnwbnKbqtblMbqubnDbnDbqvbqwbqxbqybqvbnDbnDbnDbqzblMbnKbnLblRbqAbqBbqCblTbqDbqEbqFblTbqGbqHbqIbqJbqKbnTbqLbqMbnWbmbbmbbqNbmcbmcbmcbqObqPbqQbqRbqSbqSbqTbqUbqSbqVbqSbqWbqXbqYbqZbrabrbbmcbmcbmcbqNbmibmiboibhqbhqaUSbrcbrdbpMbrebmqbrfbrgbmqbrhbribpNbmqbonbooboobrjbrkbrlbrmbrnbrobrpboobrqbpXbrrbozboAboAbrsbrtbrubebbejaGYbaubrvbrwbrxbljblkbrybcpbcpbrzbcpbrAbrBaYPbrCbrDbrEboJboJbrFbrEbrGaYPbrHbqkbjKbjObGIbjMbjKbjKbrIbrJbrKbrLbrMbrKbrNbeCbeCbeCbeCbeCbeCbeCbeCbeCbeCblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrObrPbrPbrQbrPbrPbrPbrRbrPbrPbrSaabaPYaUnaShbrTbqrbrUbrVbrWbrXbrYbrZbsabsbbqrbscbsdbsebsfblMbsgbnDbnDbqvbqxbshbsibqvbnDbnDbsjbskblMbnKbnLblRblRbslblRblTbsmbsnbsoblTbspbqJbsqbqJbsrbnTbnVbssbnWbgXbgXbstbsubsvbmcbswbptbsxbqSbqSbsybszbsAbsBbsAbsCbsDbsEbsFbsGbsHbsIbmcbsJbsubsKbsLbsMboibhqbhqbsNbmqbsObmqbmqbmqbsPbsQbmqbrhbsRbpNbmqbpObooboobsSbsTbsUbsVbsWbsXbrpbsYbebbsZbtabtbboAboAboBbrtbtcbebbtdbtebaubtfbaubaubtgblkbthbtibcpbtjbtkbtlbtmbmUbtnbtobtpbtqbtqbtrbtsbttbmUbtubtvbjKbtwbjKbjMdsfbjKbtxbjRbjRbjRbjRbqnbijbtybeCblCblDblAbeCblCblDblAbeCbtzbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrObtAbtBbtCbtDbtDbtEbtDbtDbtDbtEbrQaPXaPYaSdaToboSbqrbrUbtFbtGbrUbtHbtIbtJbtKbqrbtLbtMbtNblQblMbtObtPbtQbtRbtSbtTbtUbtVbtVbtVbtWbtXblMbnKbsdbtYbtZbuabubblTblTblTblTblTbucbudbuebufbugbnTbnVbssbgSbgSbgSbuhbuibujbukbulbumbqSbunbuobupbuqburbusbutbuubuvbuwbuxbulbuybuzbuAbuBbuCbuDbuEbuEbuFbhqbuGaUSbmqbuHbuIbpNbmqbuJbuKbmqbuLbuMbpNbmqbonboobooboobopboobuNboobsXbrpbuObebbuPbrrboBboAboAboBbrtbuQbebbuRbuSbuTbuUbuVbuWbuXbuYbuZbuZbuZbuZbuZbuZbvabvbbvcboJboJboJboJboJboJbvdbvebvfbqkbjKbjKbjKbjMbjKbjKbvgbqnbvhbvhbvhbjRblDblAbeCblCbnbblAbeCblCbnbblAbeCblCblDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvibvjbvjbvjbvjbvjbvjbvjbvjbvjbvjbvkbvlaOQbvlaSfboSbqrbvmbrUbvnbvnbvnbvobrUbvpbqrbvqbvrbtNbvsbvsbvsbvsbvtbvsbvubnDbvvbvwbvxbvxbvybvzblMbvAbvBbvCbvDbvEbvFbvGbvHbvIbvHbvJbvJbvJbvJbvJbvKbvLbnVbvMbvNbvObvPbvQbvRbvSbvTbvUbusbvVbvWbvXbvXbvXbvXbvYbvXbvZbwabwbbwcbvVbwdbwebmcbwfbwgbwhbwibwjbwkbhqbhqbsNbmqbwlbmqbmqbmqaZVbmqbmqbwmbwmbmqbmqbwnbooboobwobwpboobooboobwqbwrbwsbebbqabrrboBboBboBboBbrtbwtbebbwubwvbwvbwwbwvbwxbljbljbljbljbwybljbljbljbwzbveboJboJboJboJboJboJboJbvdbvebvfbqkbjKboMboMboNboMbjKbwAbjRbwBbwCbwDbjRbnbblAbeCblCbnbblAbeCblCbnbblAbeCblCbnbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwEbwFbwGbwHbwIbwIbwJbwIbwIbwIbwJbrQaPYaPYaSdbwKblHbwLbrUbwMbvnbvnbvnbvobwMbrUbqrbwNbwObtNbvsbwPbwQbwRbwSbvsbwTbwUbwVblMbwWbwXbwYbwZblMbnKbxabxbbxbbxcbxbbxbbxbbxbbxdbxebxebxebxfbxebxgbxhbxibxjbxkbxlbxlbxlbxlbxlbxmbxmbxnbxmbvXbvXbxobxpbxqbxrbxsbxtbxobxubvXbxvbxwbxvbxvbxvbxvbxvbxvbxvbwkbhqbhqaUSbxxbmqbxybxzbmqbxAbmqbxBbxCbxDbmqbxEbdTbxFbxGbdTbdTbxHbxIbxJbxIbdTbdTbebbxKbxLbxMbxMbxMbxMbxLbxNbebbxObwvbwvbwwbxPbaubxQbxRbxSbxTbxUbxVbxWbxXbxYaYPbxZbcDbyaboJboJbyabcDbybaYPbycbqkbjKbqlbqlbqmbqlbjKbvgbqnbvhbvhbvhbjRbqoblAbeCblCbqoblAbeCblCbqoblAbeCblCbqoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwEbrPbrPbrQbrPbrPbrPbrRbrPbrPbydaabaPYbyebngbyfbqrbtFbtFbtFbrUbygbyhbyibyjbqrbykbylbtNbvsbymbvsbynbyobvsbypbyqbyrblMbwWbwXbwYbskblMbnKbxabxbbysbytbyubyvbywbxbbyxbyybyzbyAbyBbyBbyBbyCbyDbyEbyFbxlbyGbyHbyIbyJbyKbyLbyMbyNbvXbyObxqbxqbyPbyQbyPbxqbxqbyRbvXbySbyTbyUbyVbyWbyXbyYbyZbxvbzabzbbzbbzcaUSaUSaUSaUSbzdbsNbzdbzeaUSbdRaUSaUSbdTbdTbdTbdTbzfbzgbzgbzgbzgbzhbzibebbjBbzjbjBbzkbzkbjBbzjbjBbebbxObwvbwvbzlbxPbaubaubaubaubaubtfbaubaubaubauaYPaYOaYQaYQaYQaYQaYQaYQaYPaYPbzmbznbjKbjKbjKbjMbjKbjKdsgbjRbjRbjRbjRbqnbijbzobeCbeCbeCbeCbeCbeCbeCbeCbeCbeCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUlaLdaSdaSdaSdaMsaMsaMsaMsaMsaMsbzqbzrbqrbqrbqrbqrbqrbqrbzsbqrbqrbqrbnKbnKbztbvsbzubzvbynbzwbvsbzxbzybzzblMbwWbwXbwYbnDblMbnKbxabxbbzAbzBbzCbyvbzCbxbbyxbzDbzEbzFbzGbzHbzIbzJbzKbzLbyFbzMbzNbzObzPbzQbzQbzPbzRbzSbvXbzTbxqbxqbyPbzUbyPbxqbxqbzVbwbbzWbzXbzYbzZbAabAbbzYbAcbxvbAdbAebAfbAgbAhbAibAjbAkbAkbAkbAkbAkbAkbAlbAmbAnbAkbAkbAobAkbAkbAkbAkbAkbAkbAkbAkbApbAqbArbArbArbArbArbArbAsbAibAtbAubAubAvbAwbAxbAwbAybAwbAzbAAbABbAwbACbADbAEbAFbAGbAGbAGbAGbAGbAGbAGbAHbAIbAJbAJbAJbAJbAKbAJbALbrIbAMbrKbANbrMbrKbAObeCbeCbeCbeCbAPbeCbAPbeCbeCbeCbeCaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabAQbARbARbARbARbASbASbARbARbATaaaaabaPYaUnaShbAUbAVbAWbAXbAXbAXbAXbAYbAZbBablQbnwbBbbBcbvsbvsbvsbBdbyobvsblMblMblMblMbwWbBebBfbBgblMbBhbBibxbbBjbBkbyvbzCbBlbxbbyxbBmbzEbzFbBnbBobBpbzJbBqbzLbyFbzMbBrbBsbBtbBubBvbBwbzRbBxbvXbBybyPbxqbBzbBAbBzbxqbyPbBBbxubBCbzYbzYbzZbBDbAbbzYbBEbxvbBFbAfbAfbAgbAhbAibAkbAkbAkbAkbAkbAkbAkbBGbAkbAkbAkbAkbAkbAkbBHbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBJbBKbBLbAGbAGbBMbwvbwvbwvbwvbwvbwwbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbBNbwvbBObBPbjKbjKbjKbjKbjKbjKbjKbBQbjRbqnbjRbjRbjRbEJbjSdsidshbjSbBUaYUbBUaYUbDxbBRbBSbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBWbBXbBYbBZbCabCbbCbbCcbCdbARbATaPXaPYaPYaTobCebCfbCgbCfbCfbCfbCfbChbCibCjblQblQbCkbClbvsbwPbCmbCnbzwbvsbCobCpbCoblMblMblMblMbCqblMbCrbCsbxbbCtbCubzCbCvbCwbxbbyxbzJbCxbzFbBnbBnbCybzJbCzbzLbyFbzMbCAbBsbBtbCBbCCbBwbzRbCDbvXbCEbCFbxqbCGbCHbCIbxqbCJbCKbCLbCMbCNbCObCPbCQbCRbzYbCSbxvbCTbCUbAfbAgbAhbAibAkbCVbAkbAkbAkbAkbCWbCXbCXbCXbCXbCYbAkbAkbAkbAkbCZbAkbCVbDabAkbDbbDcbDdbAkbDebDfbDfbDgbDhbDibDjbwvbwvbwvbwvbwvbwvbwvbDkbDlbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbDmbDnbDnbDobDpbDqbDrbDsbDsbDsbDsbDtdskbAMbrKbrMbrMbrKdsjdsldsldsldsnbijaaabijdsobDwbDwdspbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXAaYWaYXaYYaXzaYZaXsaYZaXsaYZaXsaYZaXzaZaaZbaSdaToaZcaVcaZdaZeaZfaZgaZhaZiaTuaZjcMMaZkaZlaZmaZnaZoaTuaZpaZqaXQaXQaXQaXQaXQaXQaXRaZraVjaabaUEaZsaZtaZuaZvaZwaUEaabaSuaSzaSAaZxaZyaZzaZAaZBaSAaPiaRwaUJaUJaUJaZCaULaSCaUMaSCaULaZDaUJaUJaUJaRwaZEaZFaZGaEjaVyaZHaZIaZIaZIaZJaZKaZLaZMaZNaZOaZMaZPaZQaZRaZMaZSaZTaZUaZVaZWaUSaZXaZYaZZbaabaaaZYbabbacbacbacbacbacbadbaebacbafbagbahbaibajbakbalbambanbaobanbapbaqaGYaGXbarbasbatbaubavbawbaxbaybazbaAbazbaBbaCbaDbaEbaFbaGbaHbaIbaJbaKbaLaYPbaMbaNbaObaPbaQbaRbaSbaTbaUbaVaaaaaaaaaaaaaaaaaaaaaaYTbaWbaXbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaZaXsaXsaVXaXzaYZaXsaYZbbaaYZaXsaYZaXzaZaaZbaSdaTobbbaVcaVcbbcaUraUmaUraVcaTuaTuaTuaTubbfbbgbbhbbiaTubbjbbkbblaXQaXQbbmaXQbbnbbobbpaVjaaaaUEaUEbbqbbrbbqaUEaUEaaaaSuaSzaSAbbsbbtbbuaZAbbvaSAaPiaRwaSBaSCbbwaWFaULaSCaUMaSCaULaWHbbxaRwaRwaRwbbybbzbbAbbBbbCbbDatGatGbbEbbFbbGbbHaUQbbIaVEaUQbbJaUQbbKaUQbbLbbMbbNbbObbPbbQbbRbbSbbTbbUbbVbbWbbXbbVbbVbbYbbVbbSbbZbbSaXjbcabbSbcbbccbcdbcebcfbcgbchbcibcjbckbclaXibcmbcnbcobcpbcqbcrbcsbctbaybcubcvbazbcwbcxbcybczbaFbcAbcBbcCbcDbcEbcFaYPbcGbcHbcHbcIbaTbaTbaTbaTbaUbaVaaaaaaaaaaaaaaaaaaaYTbaWbcJbcKbcLbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXAbcMbcNaYYaXzaYZaXsaYZaXsaYZaXsaYZaXzaZaaZbaSdaTobcOaUsbcQbcRbcSbcSaSfbcTbcUbcVbcWbcXbcYbcZaVebdaaTubdbbdcbddbdebdfbdgbdhbdibdjbdkaVjaaaaabaaaaUtbdmaUtaaaaabaaaaSuaSzaSAbdnbdobdpbdqbdraSAaPiaRwbdsbdtaTCbdubdvaTFbdwaTFbdxbdybdzaRwbdAbdBbdCbdDbdEbdFbdGbdHaaaaaabbEbdIbdJbdKaUQbdLbdMaVEaVEbdNaVEaVEaVEbdOaUSbdPaUSbdQbdRaUSbdSaUSbdTbdUbdVbdWbdXbdYbdTbdZbeabebbecbebbebbebbebbedbeebebbefbegbehbeibebbejaGYbaubekbcpbelbembenbeobepbeqberbesbazbetbeubevbewbexbcAbcBbcCbcDbaKbeyaYPbezbcHbcHbcIbaTbaTbaTbaTbaUbaVaaaaaaaaaaaaaaaaaaaYUbeAbeBbeCbeBbeDaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeEbeFaVWaXqaXzaXsbeGbeHaXsaXsbeIbeGaXzaXAbeJaSdaTobeKbbdbeMbeNbeMbeMbeMbeMbeMbeOaSfaTubePbeQbePaTuaTubeRbeSbeRaViaViaViaVibeRbeTbeUaVjbcPbbebbebdlbeYbdlbbebbebeLaSubfaaSAbeVaSAbeXbeWbfeaSAbffaRwaRwaRwaRwbfgbfhbfibfjbfibfhbfgaRwaRwbfkbdDbdDbdDbdDbflbfmbfnbfobfpbbEbfqbdJbfraUQaUQaUQaUQaUQaUQaUQaUSaUSbdObfsbftbfubfvbfwbfxbfybfzbdTbfAbfBbfCbfDbfEbdTbfFbfGbfHbfIbfHbfJbfKbfMbfLbfNbfObfPbfQbfRbfSbebbfTbfUbfVbfWbfXbelbfYbfZbeobgabazbgbbgcbgdbgebgfbczbczbazbazbcBbcCbcDbcEbggaYPbghbgibgjbgkbglbgmbaTbaTbgnbaVaaaaaaaaaaaaaaaaYTbaWbgobeCbeCbeCbgpbaYaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeEaVWaVXaVWaVWaVYaVZaVWaVWaVXbeFbgqaLdbgrbeKaSdbgsbgsbgtbgsbguaMsbgvbgwaSfbeZbfbbgzbgzbgAbgBbgzbgCbgzbgzbgzbgDbgzbgzbgEbgFbfcbgHbgIbgJbgHbgKbgHbgHbgHbgHbgLbgMbgNbgzbgzbgObfbbgQbfdbgSbgTbgUbgVbgWbgXbgXbgXbgXbgXbgXbgXbgYbgZbhabhbbhcbhdbhebhfbhgbhhbdDbdDbhibhjbhkbhjbhkbhlbhmbhnbhobhpbhqaUSbhrbhsbhtbhubhvbhvbhwbhxbhybhzbdTbhAbhBbhCbhCbhDbdTbhEbhFbhGbhHbhIbhIbhJbhKbhLbfMbhNbhObhPbhQbhRbebbejaTgbaubhSbhTbhTbhUbhVbhTbhWbazbhXbhYbazbhZbiabczbibbazbicbidbiebcDaYPaYPaYPbifbigbihbiibigbigbigbigaYSafXajcaaaaaaaaaaaabijbikbilbeCbeCbimbinbeCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbgxaSdaSdaSdaSdaSdaSdbgxaSdaUZaLdbipbiqaSdbirbisbitbitbiuaMsbivbgwbiwbgybfbbiybizbiAbiBbiBbiCbiDbiDbiDbiEbiFbiFbiGbiHbgGbiBbiBbiJbiFbiKbiLbiMbiMbiNbiObiPbiQbiQbiQbiRbfbbgQbfdbgSbgSbgSbgSbiSbgSbgSbgSbgSbgSbgSbiTbiUbiVbiWbiXbiYbiZbjabjbbjcbiVbiVbiVbjdbjebjebjebjfbhqbhqbhqbjgbjhbhqaUSbjibjjbhvbhvbjkbhvbjlbjmbhybjnbdTbjobjpbjqbjrbjsbdTbjtbjubjvbjwbjxbjybebbebbjzbebbebbebbjBbjCbjBbebbejaGYbaubjDbcpbcpbcpbjEbcpbjFbazbazbazbazbazbazbazbjGbazbcDbcDbcCbcDbjHbjIaYPbjJbjNbjLblwbgPbiobgRbixbjRaaaaaaaaaaaaaYTbjSbjTbjSbjSbjSbjUbjSbjVbjSbjTbjSaYVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaUlaLdaSdaOQaSdbjWbjXbjYbjZaSdaOQaSdaSdaLdbkabeKaSdbkbbkcbitbitbiuaMsbkdbgwaSfbgybfbbgzbkebkfbkgbkgbkhbkibkjbkgbkkbkgbklbkgbkmbiIbkgbkgbkgbkgbkgbkobkpbkgbkqbkrbksbktbgzbgzbkubjPbkwbjQbkybkzbkybkAbkBbkAbkAbkAbkAbkAbkAbkCbkDbkEbkEbkEbkEbkFbkEbkGbkHbkEbkEbkIbkJbkKbkKbkKbkKbkKbkKbkKbkLbhqbhqaUSbkMbkNbkObkPbkPbkQbkRbjmbhybkSbdTbdTbdTbdTbdTbkTbdTbkUbkVbkWbkXbfHbkYbebbhMblabjAblcbldbleblfblgbebbejaQLbaublhblibcpbljblkbcpbllbllbaublmblnbloaYPblpblqblrbcDbcDblsbltaYPbluaYPblvbjKbjLblxbknbALbjKblzbjRaaaaaaaaaaaabijbmXbnabmYbmYblDbeCblCblDblAblBblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaSdbgxaSdaToaSfaSfaTpaSdbgxaSdblEblFblGblHaSdblIblIbgtblIbguaMsblJbgwaSfaMsblKblKblLblMblMblMblMblMblMbkvbkxblMblMblMblMblMblMblPblQblRblRblSblRblTblUblVblTblTblWblXblYblKblZblZbmabmabmabmbbmbbmbbmbbmbbmbbmbbmbbmcbmdbmdbmebmdbmfbmfbmfbmfbmgbmhbmfbmcbmibmibmibmibmibmibmibmibmjbmjbmjaUSbmkbmlbmmbmmbmmbmmbmnbmobmpbmqbmrbmsbmtbmubmvbmwbdTbdTbmxbmybmzbmybmybebbmAbmBbmDbmDbmDbmDbmEbmFbebbmGbmHbaubmIbcpbljbljblkbljbcpbmJbaubmKbmLbmMaYPbcDbmNbmObmPbmPbmQbmRbmSbmTbmUbmVbmWboObzpbjMbjKbjKblzbjRbjRbjRbjRbjRbijbBTbDzbDzbDzbBVbeCblCbnbblAbeCbncbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbneaSfbnfbngbnhbnibnjbnkbnibnlbnmbnibnibnnblybnpbnqbnrbnrbnrbnsbnrbntbnuaMsbnvbnwbnxblMbnybnzbnAbnBbnCbnDbnEbnFbnGbnHbnIbnJblMbnKbnLblRbnMbnNbnOblTbnPbnQbnRblTbnSbnTbnUbnSbnSbnSbnVbgSbnWbmbaaaaaaaaaaaaaaaaaaaaabmcbnXbnYbnZboabobbocbodboebofbogbohbmcaaaaaaaaaaaaaaaaaaaaabmiboibhqbojaUSbokbmlbmqbmqbmqbmqbmqbolbombmqbmqbmqbonbooboobopboqborbosbotboubovbowbebbkZboyboBboAboAboBboCboDbebbejaGYbauboEboFbcpbljblkbcpboGboGbaubauboHbauaYPboIblqbltboJboJboKbltaYPaYPaYPboLbjKbEFblNbjMbjKbjKblObAMbrKbrMbrMbrKbDvbDzbDzbGJbGJbnbbeCblCbnbblAbeCblCaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdboPboQboPboPboPboPboPboPboQboPboPboRaSfboSbgyboUaSfboVaSfboWboXboYboZbpaaMsbnwbnwbpbblMbpcbnDbnDbnDbnDbnDbnEbpdbnDbnDbnDbpeblMbnKbpfblRbpgbphbpiblTbpjbpkbplblTbpmbpnbpobppbpqbnTbnVbgSbnWbmbaaaaaaaaaaaabmcbmcbmcbmcbprbpsbptbpubpvbpwbpxbpybpzbpAbpBbmcbmcbmcbmcaaaaaaaaaaaabmiboibhqbpCbpDbpEbpFbpGbpHbpEbpIbpJbpKbpLbpMbpNbmqbpObpPboobpQbpRboobpSbpTbpUbpVboobpWbpXbpYboBboAboAboBbpZbqabebbejaTgbaubmIbcpbljbljblkbljbcpbcpbqbbqcbcpbqdaYPbqebqfbqgboJboJbqhbqgbqiaYPbqjbqkbjKbjRbjRbmZbndbjRbjRbjRbqnbjRbjRbjRbEJbjSbjSbjSbjSbqobeCblCbqoblAbeCblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLdaLdaSdaSdaSdaSdaSdaSdaSdaSdaSdaLdaMsbgybnobqrbqrbqrbqrbqrbqrbqsbqrbqrbqraMsbnwbnKbqtblMbqubnDbnDbqvbqwbqxbqybqvbnDbnDbnDbqzblMbnKbnLblRbqAbqBbqCblTbqDbqEbqFblTbqGbqHbqIbqJbqKbnTbqLbqMbnWbmbbmbbqNbmcbmcbmcbqObqPbqQbqRbqSbqSbqTbqUbqSbqVbqSbqWbqXbqYbqZbrabrbbmcbmcbmcbqNbmibmiboibhqbhqaUSbrcbrdbpMbrebmqbrfbrgbmqbrhbribpNbmqbonbooboobrjbrkbrlbrmbrnbrobrpbooboxbpXbrrboBboAboAbrsbrtbrubebbejaGYbaubrvbrwbrxbljblkbrybcpbcpbrzbcpbrAbrBaYPbrCbrDbrEboJboJbrFbrEbrGaYPbrHbqkbjKbjObGIbjMbjKbjKbrIbrJbrKbrLbrMbrKbrNbeCbeCbeCbeCbeCbeCbeCbeCbeCbeCblCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrObrPbrPbrQbrPbrPbrPbrRbrPbrPbrSaabaSdaUnaShbrTbqrbrUbrVbrWbrXbrYbrZbsabsbbqrbscbsdbsebsfblMbsgbnDbnDbqvbqxbshbsibqvbnDbnDbsjbskblMbnKbnLblRblRbslblRblTbsmbsnbsoblTbspbqJbsqbqJbsrbnTbnVbssbnWbgXbgXbstbsubsvbmcbswbptbsxbqSbqSbsybszbsAbsBbsAbsCbsDbsEbsFbsGbsHbsIbmcbsJbsubsKbsLbsMboibhqbhqbsNbmqbsObmqbmqbmqbsPbsQbmqbrhbsRbpNbmqbpObooboobsSbsTbsUbsVbsWbsXbrpbsYbebbqabrrboBboAboAboBbrtbtcbebbtdbtebaubtfbaubaubtgblkbthbtibcpbtjbtkbtlbtmbmUbtnbtobtpbtqbtqbtrbtsbttbmUbtubozboTbtwbjKbjMdsfbjKbtxbjRbjRbjRbjRbqnbijbtybeCblCblDblAbeCblCblDblAbeCbtzbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrObtAbtBbtCbtDbtDbtEbtDbtDbtDbtEbrQaSdaSdaSdaToboSbqrbrUbtFbtGbrUbtHbtIbtJbtKbqrbtLbtMbtNblQblMbtObtPbtQbtRbtSbtTbtUbtVbtVbtVbtWbtXblMbnKbsdbtYbtZbuabubblTblTblTblTblTbucbudbuebufbugbnTbnVbssbgSbgSbgSbuhbuibujbukbulbumbqSbunbuobupbuqburbusbutbuubuvbuwbuxbulbuybuzbuAbuBbuCbuDbuEbuEbuFbhqbuGaUSbmqbuHbuIbpNbmqbuJbuKbmqbuLbuMbpNbmqbonboobooboobopboobuNboobsXbrpbuObebbuPbrrboBboAboAboBbrtbuQbebbuRbuSbuTbuUbuVbuWbuXbuYbuZbuZbuZbuZbuZbuZbvabvbbvcboJboJboJboJboJboJbvdbvebvfbqpbjKbjKbjKbqqbALbjKbvgbqnbvhbvhbvhbjRblDblAbeCblCbnbblAbeCblCbnbblAbeCblCblDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabvibvjbvjbvjbvjbvjbvjbvjbvjbvjbvjbvkbvlaOQbvlaSfboSbqrbvmbrUbvnbvnbvnbvobrUbvpbqrbvqbvrbtNbvsbvsbvsbvsbvtbvsbvubnDbvvbvwbvxbvxbvybvzblMbvAbvBbvCbvDbvEbvFbvGbvHbvIbvHbvJbvJbvJbvJbvJbvKbvLbnVbvMbvNbvObvPbvQbvRbvSbvTbvUbusbvVbvWbvXbvXbvXbvXbvYbvXbvZbwabwbbwcbvVbwdbwebmcbwfbwgbwhbwibwjbwkbhqbhqbsNbmqbwlbmqbmqbmqaZVbmqbmqbwmbwmbmqbmqbwnbooboobwobwpboobooboobwqbwrbwsbebbqabrrboBboBboBboBbrtbwtbebbwubwvbwvbwwbwvbwxbljbljbljbljbwybljbljbljbwzbveboJboJboJboJboJboJboJbvdbvebvfbqpbjKboMboMboNboMbjKbwAbjRbwBbwCbwDbjRbnbblAbeCblCbnbblAbeCblCbnbblAbeCblCbnbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwEbwFbwGbwHbwIbwIbwJbwIbwIbwIbwJbrQaSdaSdaSdbwKblHbwLbrUbwMbvnbvnbvnbvobwMbrUbqrbwNbwObtNbvsbwPbwQbwRbwSbvsbwTbwUbwVblMbwWbwXbwYbwZblMbnKbxabxbbxbbxcbxbbxbbxbbxbbxdbxebxebxebxfbxebxgbxhbxibxjbxkbxlbxlbxlbxlbxlbxmbxmbxnbxmbvXbvXbxobxpbxqbxrbxsbxtbxobxubvXbxvbxwbxvbxvbxvbxvbxvbxvbxvbwkbhqbhqaUSbxxbmqbxybxzbmqbxAbmqbxBbxCbxDbmqbxEbdTbxFbxGbdTbdTbxHbxIbxJbxIbdTbdTbebblbbxLbxMbxMbxMbxMbxLbxNbebbxObwvbwvbwwbxPbaubxQbxRbxSbxTbxUbxVbxWbxXbxYaYPbxZbcDbyaboJboJbyabcDbybaYPbycbqpbjKbqlbqlbqmbqlbjKbvgbqnbvhbvhbvhbjRbqoblAbeCblCbqoblAbeCblCbqoblAbeCblCbqoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwEbrPbrPbrQbrPbrPbrPbrRbrPbrPbydaabaSdbyebngbyfbqrbtFbtFbtFbrUbygbyhbyibyjbqrbykbylbtNbvsbymbvsbynbyobvsbypbyqbyrblMbwWbwXbwYbskblMbnKbxabxbbysbytbyubyvbywbxbbyxbyybyzbyAbyBbyBbyBbyCbyDbyEbyFbxlbyGbyHbyIbyJbyKbyLbyMbyNbvXbyObxqbxqbyPbyQbyPbxqbxqbyRbvXbySbyTbyUbyVbyWbyXbyYbyZbxvbzabzbbzbbzcaUSaUSaUSaUSbzdbsNbzdbzeaUSbdRaUSaUSbdTbdTbdTbdTbzfbzgbzgbzgbzgbzhbzibebbjBbzjbjBbzkbzkbjBbzjbjBbebbxObwvbwvbzlbxPbaubaubaubaubaubtfbaubaubaubauaYPaYOaYQaYQaYQaYQaYQaYQaYPaYPbzmbrqbtabsZbjKbjMbjKbjKdsgbjRbjRbjRbjRbqnbijbzobeCbeCbeCbeCbeCbeCbeCbeCbeCbeCbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUlaLdaSdaSdaSdaMsaMsaMsaMsaMsaMsbzqbzrbqrbqrbqrbqrbqrbqrbzsbqrbqrbqrbnKbnKbztbvsbzubzvbynbzwbvsbzxbzybzzblMbwWbwXbwYbnDblMbnKbxabxbbzAbzBbzCbyvbzCbxbbyxbzDbzEbzFbzGbzHbzIbzJbzKbzLbyFbzMbzNbzObzPbzQbzQbzPbzRbzSbvXbzTbxqbxqbyPbzUbyPbxqbxqbzVbwbbzWbzXbzYbzZbAabAbbzYbAcbxvbAdbAebAfbAgbAhbAibAjbAkbAkbAkbAkbAkbAkbAlbAmbAnbAkbAkbAobAkbAkbAkbAkbAkbAkbAkbAkbApbAqbArbArbArbArbArbArbAsbAibAtbAubAubAvbAwbAxbAwbAybAwbAzbAAbABbAwbACbADbAEbAFbAGbAGbAGbAGbAGbAGbAGbtbbAIbAJbAJbtvbAJbxKbjKbjKbrIbAMbrKbANbrMbrKbAObeCbeCbeCbeCbAPbeCbAPbeCbeCbeCbeCaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabAQbARbARbARbARbASbASbARbARbATaaaaabaSdaUnaShbAUbAVbAWbAXbAXbAXbAXbAYbAZbBablQbnwbBbbBcbvsbvsbvsbBdbyobvsblMblMblMblMbwWbBebBfbBgblMbBhbBibxbbBjbBkbyvbzCbBlbxbbyxbBmbzEbzFbBnbBobBpbzJbBqbzLbyFbzMbBrbBsbBtbBubBvbBwbzRbBxbvXbBybyPbxqbBzbBAbBzbxqbyPbBBbxubBCbzYbzYbzZbBDbAbbzYbBEbxvbBFbAfbAfbAgbAhbAibAkbAkbAkbAkbAkbAkbAkbBGbAkbAkbAkbAkbAkbAkbBHbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBIbBJbBKbBLbAGbAGbBMbwvbwvbwvbwvbwvbwwbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbBNbwvbznbBPbjKbjKbAHbjKbjKbjKbjKbBQbjRbqnbjRbjRbjRbEJbjSdsidshbjSbBUaYUbBUaYUbDxbBRbBSbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBWbBXbBYbBZbCabCbbCbbCcbCdbARbATaSdaSdaSdaTobCebCfbCgbCfbCfbCfbCfbChbCibCjblQblQbCkbClbvsbwPbCmbCnbzwbvsbCobCpbCoblMblMblMblMbCqblMbCrbCsbxbbCtbCubzCbCvbCwbxbbyxbzJbCxbzFbBnbBnbCybzJbCzbzLbyFbzMbCAbBsbBtbCBbCCbBwbzRbCDbvXbCEbCFbxqbCGbCHbCIbxqbCJbCKbCLbCMbCNbCObCPbCQbCRbzYbCSbxvbCTbCUbAfbAgbAhbAibAkbCVbAkbAkbAkbAkbCWbCXbCXbCXbCXbCYbAkbAkbAkbAkbCZbAkbCVbDabAkbDbbDcbDdbAkbDebDfbDfbDgbDhbDibDjbwvbwvbwvbwvbwvbwvbwvbDkbDlbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbwvbDmbDnbDnbAKbDpbDqbDrbDsbDsbBObBObDqblObAMbrKbrMbrMbrKdsjdsldsldsldsnbijaaabijdsobDwbDwdspbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBWbBXbDAbCbbCbbCbbCbbCbbCbbCbbDBbDCaOQbDCaSfbDDbCfbDEbDFbDGbDHbDIbChbDJbDKbDLbDLbDMbDNbvsbvsbvsbynbDObymblQblQblQblQbDPbnKbnKbCsbnKbCrbCsbxbbDQbDRbDSbDTbyvbxbbDUbzJbDVbzFbBnbBnbDWbDXbDYbzLbDZbxlbEabEbbzPbzPbzPbzPbzRbEcbvXbEdbEebvXbvXbvXbvXbvXbvXbvXbxubxvbEfbEgbEhbEibEjbEkbElbxvbEmbEnbEnbEobEobEobEobEobEobEobEpbEpbEqbErbEsbEsbErbEqbEpbEpbEtbEtbEtbEtbEtbEtbEubEubEvbEubEubEubEubEubEubEwbExbEybwvbwvbEzbEzbEAbEAbEAbEAbEAbEBbDnbDnbDmbDnbwvbDnbDnbDnbDnbECbEDbEDbEDbEDbEEbEFbEFbEGbEGbEGbEGbEGbEGbEGbjRbjRbjRbjRaYUdsqdsldsldsrbijaaabijdssbDwbDwdstbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBWbBXbEKbELbELbCbbELbELbELbARbEMaPYaPYaPYaTobENbCfbEObEPbEPbEPbEQbChbnKbERbESbETbEUbEVbvsbwPbEWbynbEXbymbEYbEZbFabFbbFcbFdbFdbFebFdbFfbFgbxbbFhbFibFjbFkbFlbFmbFnbyBbFobFpbBnbFqbFrbFsbDYbzLbFtbxlbFubFvbFwbFxbFybFzbFAbxmbxmbFBbFCbFDbFEbFFbFEbFGbFCaaabFHbxvbFIbFJbFKbFLbEjbzYbFMbxvbFNbFObFPbEobFQbFRbFSbFTbFUbFVbFWbFXbFYbFZbGabGabFZbGbbGcbGdbEtbGebGfbGgbGhbEtbGibGjbGkbGlbGmbGnbGnbGobEubGpbGqbGrbGsbGrbGtbGtbEAbGubGvbGwbEAbGxbGybGxbEAbGzbDnbECbEDbGAbGBbGAbEDbGCbGDbEDbGEbGFbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabijdsudswdsvdsvbijaaabijdsxbDwdsxbDwbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGKbARbARbARbARbARbARbARbARbEMaaaaaaaPYbGLbngbGMbCfbGNbCfbGObEPbGPbGQbChbGRbGSbGTbGUbEVbvsbvsbvsbvsbvsbvsbGVbGWbGXbGYbGZbxbbxbbxbbxbbxbbxbbxbbHabxbbxbbxbbHbbxbbHcbHdbHebBnbBnbBnbHfbDXbHgbzLbHhbxlbHibFvbxlbxlbxlbxmbHjbxmbHkbHlbHmbHnbHobHpbHqbHrbHsbHtbHubxvbHvbzYbHwbHxbEjbHybzYbxvbHzbHAbHBbEobHCbHDbHEbHFbHGbHHbHIbGabGabGabGabGabGabGabGabHJbHKbHLbHMbHNbHObEtbHPbHQbHRbHSbHTbHUbHQbHTbEubHVbGqbHWbHXbHYbHZbHZbIabIbbIcbIdbIebIfbIgbIhbEAbIibIjbIkbEDbIlbImbInbIobIpbIqbEDbIrbGGbIsbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabItbjVbIubIubIubIvaaabIwbIxbIxbIxbjVbIyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUlaLdaSdaSdaPYaPYaPYaPYaPYaPYaPYaToaSfbIzbCfbIAbIBbICbIDbIDbIEbIFbIGbIHbIHbIIbIJbDLbDLbDLbDLbDLbDLbIKbILbILbIMbINbxbbIObIPbIQbIRbISbITbIUbIVbxbbIWbIXbyBbyCbDXbHebBnbBnbIYbzJbzJbIZbJabJbbJcbJdbJebJfbJgbJhbJibJjbJkbJlbJmbHsbJnbJobJnbJobJpbHsbHtbJqbJrbJsbJtbJubJvbJwbJxbJybJrbJzbFObFObEobJAbJBbJCbJDbJEbEobHIbGabGabGabGabGabGabGabJFbJGbJHbJIbJJbHLbJKbEtbJLbJMbJNbHSbHTbHUbJObJPbEubJQbJRbJSbJTbJTbJUbJVbJWbJXbJYbJYbJYbJZbJYbKabKbbKcbKdbKebKfbKgbKhbKibKibKibKjbEDbKkbGGbKlbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabItbKmbKmbKmbIyaaabItbKmbKmbKmbIyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYbKnbKobKpaRcaRcaRcbngaSfaSfbCfbKqbCfbKrbKsbKtbKubCfblQbKvbKvbKwbKxbKwbKwbKwbKxbKwblQblQbxbbxbbxbbKybxbbKzbKzbKzbKzbKzbKzbIUbKAbKBbKCbzFbKDbKEbKFbKGbKHbKIbKJbKKbKLbKMbKNbKObKPbKQbKQbKRbKSbKTbKUbKVbKWbKXbKYbFCbKZbHqbLabHobLbbFCaaabLcbLdbLebLfbLdbLdbLdbLdbLgbxvbLhbFObLibLjbLkbLlbLmbLnbLobEobLpbLqbLrbLsbLtbLubLvbLwbGabLxbEtbLybJJbLzbLAbEtbLBbLCbHRbHSbHTbHUbHQbHTbEubHVbGqbLDbLEbLFbLGbLHbLIbLJbLKbLLbLMbLNbLObLPbEAbLQbLRbLSbEDbLTbLUbLVbIpbLWbLXbEDbKkbGGbLYbGHaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYbLZbMabKpaSeaSebMbbMcaSebMdbCfbMebIBbMfbMgbMhbMibCfaaaaabaabbMjbMkbMkbMkbMkbMkbMlaaaaaabMmbMnbMobMpbMqbKzbKzbKzbKzbKzbKzbMrbMsbMtbMubMvbMwbMxbMybzJbzJbMzbMAbzJbzJbMBbMCbMDbMEbMFbMGbMGbMHbMGbMIbMJbMGbMKbKYbFCbMLbFEbFEbFEbMMbFCaaabLcbLdbMNbMObMPbMQbMRbMSbMTbMUbMVbFObMWbEobMXbMYbMZbNabNbbNcbNdbNebNfbNgbNhbNibNjbNkbNlbNmbNnbNobJJbNpbNqbEtbNrbNsbNtbNubNvbNwbNxbGobEubNybNzbNAbNBbNBbNCbNDbNEbNFbNGbNHbNIbNJbNKbNLbEAbNMbLRbNNbEDbNObNPbNQbIpbIpbNRbEDbIrbGGbNSbGHaaaaaaaaaaaaaabbNTbNUbNVbNUbNVbNUbNWaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPYbKpbKpbNXaPYaPYaUlaLdbNYbNZbCfbOabIBbIBbIBbCfbCfbCfaaaaaaaaabObbOcbOcbOdbOcbOcbObaaaaaabMmbOebKzbOfbOgbOgbOgbOgbOgbOhbOibOgbOjbOkbOlbOmbOnbOobOpbzJbOqbBnbOrbOsbDXbOtbOubOvbMEbMEbMGbOwbOxbOybOzbOAbMGbFBbKYbFCbOBbOCbODbOEbOFbFCaaabOGbLdbOHbOIbOJbOKbOLbOKbOMbONbOObFObOPbEobOQbOQbORbOSbOTbOUbOVbOWbOXbOYbOZbOZbPabPbbPcbPdbEtbNobPebPfbEtbEtbEubPgbPhbPibEubEubEubEubPjbPkbGqbPlbLEbLFbPmbNBbNEbPnbPobPobPpbIdbPqbPrbPsbPtbIjbPubEDbPvbPwbIpbPxbPybPzbEDbKkbPAbGHbGHaaaaaaaaaaaaaabbPBbPCbPDbPEbPFbPGbPBaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbPIbPIbPIbPJbPKbPIbPIbPIbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbObbPMbMmbMmbPNbPObPPbPQbPQbPQbPObKzbIUbKAbKzbKzbKBbPRbPSbPTbPUbPVbPWbPXbBnbBnbPYbDXbOtbOubPZbQabQbbQcbQdbQebQfbQgbQhbMGbQibQjbHmbQkbQlbQmbQnbQobHsbHtbQpbLdbQqbQrbQsbOKbQtbOKbQubONbQvbFObQwbEobQxbQybQzbQAbQBbQCbQDbQEbQFbQFbQGbQHbQFbQFbQIbQJbQKbQLbQMbQNbQObQPbQQbQRbQSbQTbQUbQVbQWbQXbQYbQZbGqbRabRbbRcbRdbRebIabRfbPobPobRgbRhbPqbRibEAbRjbRjbRkbEDbRlbRmbRnbRobIpbRpbEDbKkbRqbGHaaaaaaaaaaaaaaaaabbRrbRsbPDbPFbPDbRtbNVaabaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbRubRvbRwbRxbRybRzbRAbRybRBbRCbRDbPIbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbREbRFbRGbRFbRHbRIbRJbRIbRIbRIbRIbRKbIUbKAbRLbxbbxbbRMbBnbzFbPUbRNbDXbRObRPbRPbRQbRRbRSbRTbRUbRVbRWbRXbRYbRZbSabSbbScbMGbMKbKYbFCbSdbSebSfbSgbShbFCaaabOGbSibSjbSibSibSibSibSibSkbSibSlbFObQwbEobSmbSnbSnbSobSpbOUbSqbSrbSsbStbSubSvbSwbSsbSxbSybSzbSAbSBbSCbSDbSDbSEbSFbSGbSHbSIbSJbSKbSLbSMbSNbSObSPbSPbSQbSRbSSbIabSTbIdbIdbSUbSVbPqbSWbSXbSYbSZbTabTbbTcbTdbTebTfbTebEDbEDbTgbPtbThbTibTibTibTibTibThbPBbPFbPDbPFbPFbPGbPBaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbRAbRAbRAbTjbRybTkbTkbRybTlbRAbRAbTmbTnbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbTobTpbTqbTpbTrbKzbPPbPQbPQbPQbKzbKzbIUbKAbTsbTtbxbbTubBnbzFbPUbTvbDXbTwbBnbBobBnbTxbOtbTybTzbRVbRWbTAbTBbTCbTDbTEbTFbTGbTHbTIbTJbTJbTKbTLbTMbFCbFCaaabOGbSibTNbTObTPbTQbTRbTSbTTbTUbTVbFObQwbNcbTWbTXbTYbTZbUabOUbUbbUcbUdbUebUfbUgbUhbUibUjbUkbUlbUmbUnbUobUpbUqbUrbUsbUtbUubUvbQVbUwbQXbUxbUybGrbUzbUAbUBbUCbUCbIabUDbUEbUFbIabUGbPqbUHbIabUIbUJbUKbULbUMbUNbUObUPbUQbURbUSbUTbUUbUVbUWbUWbUXbUYbUZbVabVbbNUbNVbVcbNVbNUbVdaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbVebVfbVgbVhbVibRybVjbRAbVkbRAbRAbRAbRAbRAbTjbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbVlbOcbOcbOcbVmbObbPMbMmbMmbVnbKzbPPbKzbKzbKzbKzbKzbIUbKAbTsbVobxbbVpbBnbVqbVrbBnbVsbzEbBnbBnbVtbDXbOtbTybTzbRVbRWbMGbVubVvbVwbVxbVybMHbVzbVAbVBbVCbHsbVDbVEbHsbHtbHtbVFbSibVGbVHbVIbVJbVKbVKbVLbVMbVNbFObVObEobOUbVPbOQbVQbVRbOUbUbbVSbVTbVUbVVbVWbVXbVTbUbbVYbVZbWabWbbWabWcbWabWdbWdbWebWfbWgbWgbWgbWhbWgbWgbWibWibWjbWkbWjbWjbIabIabIabIabIabWlbWmbLIbIabWnbWobWpbWqbWqbWrbWsbWtbWubWvbWwbWxbWybWzbWAbWAbWBbWCbWDbThbVabVabVabWEbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWFbWGbRAbRAbWHbWHbWHbRybRAbRAbRybWIbWJbWKbWLbWMbWNbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbWObTpbTqbTpbPNbWPbWQbKzbKzbKzbWPbKzbIUbKAbTsbWRbxbbWSbBnbzFbPUbBnbzJbWTbBnbBnbWUbDXbOtbTybWVbRVbWWbMGbWXbWYbWZbXabXbbMHbXcbXdbXebXfbXgbXhbXibFCaaaaaaaaabSibXjbXkbXlbXlbXmbXnbXobSibXpbXqbQwbXrbXsbXtbXubXvbXwbXxbXybUcbXzbXAbXBbXCbXDbXzbUbbVYbXEbXFbXGbXHbXIbXJbWdbXKbXLbXMbXNbXObXPbXQbXRbXSbXTbXUbURbXVbWqbWqbXWbXXbWqbXYbXZbYabYbbYcbWqbYdbYebYfbYgbYhbYibYjbYkbYjbYjbYjbTgbPtbThbTibTibThbYlbYmbYnbYobYpbYqbYrbVaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYsbWGbRAbRAbRAbRAbRAbYtbRAbRAbRybPIbPIbPIbPIbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbYvbYwbYxbYwbYybYzbYAbYAbYAbYAbYAbYBbYCbYDbTsbYEbxbbYFbYGbYHbYIbYJbYKbYLbYLbYLbYMbYMbYNbTybYObYPbRWbMGbYQbYRbYSbVvbYTbMHbYUbYVbYWbTJbYXbQmbYYbFCaaaaaaaaabSibYZbZabZbbZcbXmbXnbXobSibZdbZebZfbZgbZhbZibZjbZkbZlbZmbZnbZobVTbVTbZpbZqbVTbVTbUbbVYbZrbZsbZtbZubZvbZwbWdbZxbZybZzbZAbZBbZCbZDbZDbZEbZFbZGbZHbZIbUMbUMbZJbUMbZKbUMbZLbUMbZMbZNbZNbZObZPbZQbZRbZSbZTbZUbZVbZWbZXbYjbZYbZZaaaaaaaaabThcaabUYcabbYobVacaccadbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRybRAbRAbRybRAcajcakcalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbObbPMbMmbMmbxbbxbbMmbMmbMmbMmbMmbxbbxbbMmbMmbMmbxbcamcamcamcancambYMcaocapcaqcarbYMbOtbTycasbMEbMEbMGbMGbMGbMGbMGcatbMHbTJbTIcaubTJcavcawbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSicaxbFOcaycazcaAcaBcaCcaAcaAcaDcaEcaFcaGcaHcaIcaJcaKcaLbXycaMcaNcaOcaPcaQcaRcaScaTcaUcaVcaWcaXcaYcaZcbacbbcbcbWgbWicbdcbecbdcbfcbgcbfcbfcbfcbhcbicbjcbjcbkcblcbmcbnbZRcbocbpcbqcbrcbscbtbYjbZYbZZaaaaaaaaabThcbucbvbThbVabThbThbVabThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBWbBXbEKbELbELbCbbELbELbELbARbEMaSdaSdaSdaTobENbCfbEObEPbEPbEPbEQbChbnKbERbESbETbEUbEVbvsbwPbEWbynbEXbymbEYbEZbFabFbbFcbFdbFdbFebFdbFfbFgbxbbFhbFibFjbFkbFlbFmbFnbyBbFobFpbBnbFqbFrbDobDYbzLbFtbxlbFubFvbFwbFxbFybFzbFAbxmbxmbFBbFCbFDbFEbFFbFEbFGbFCaaabFHbxvbFIbFJbFKbFLbEjbzYbFMbxvbFNbFObFPbEobFQbFRbFSbFTbFUbFVbFWbFXbFYbFZbGabGabFZbGbbGcbGdbEtbGebGfbGgbGhbEtbGibGjbGkbGlbGmbGnbGnbGobEubGpbGqbGrbDtbGrbDubDubEAbGubGvbGwbEAbDybEHbDybEAbGzbDnbECbEDbEIbFsbEIbEDbGCbGDbEDbGEbGFbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabijdsudswdsvdsvbijaaabijdsxbDwdsxbDwbijaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGKbARbARbARbARbARbARbARbARbEMaaaaaaaSdbGLbngbGMbCfbGNbCfbGObEPbGPbGQbChbGRbGSbGTbGUbEVbvsbvsbvsbvsbvsbvsbGVbGWbGXbGYbGZbxbbxbbxbbxbbxbbxbbxbbHabxbbxbbxbbHbbxbbHcbHdbHebBnbBnbBnbHfbDXbHgbzLbHhbxlbHibFvbxlbxlbxlbxmbHjbxmbHkbHlbHmbHnbHobHpbHqbHrbHsbHtbHubxvbHvbzYbHwbHxbEjbHybzYbxvbHzbHAbHBbEobHCbHDbHEbHFbHGbGsbHIbGabGabGabGabGabGabGabGabHJbHKbHLbHMbHNbHObEtbHPbHQbHRbHSbHTbHUbHQbHTbEubHVbGqbHWbHXbHYbHZbHZbIabIbbIcbIdbIebIfbIgbIhbEAbIibIjbIkbEDbIlbImbInbIobIpbIqbEDbIrbGGbIsbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabItbjVbIubIubIubIvaaabIwbIxbIxbIxbjVbIyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUlaLdaSdaSdaSdaSdaSdaSdaSdaSdaSdaToaSfbIzbCfbIAbIBbICbIDbIDbIEbIFbIGbIHbIHbIIbIJbDLbDLbDLbDLbDLbDLbIKbILbILbIMbINbxbbIObIPbIQbIRbISbITbIUbIVbxbbIWbIXbyBbyCbDXbHebBnbBnbIYbzJbzJbIZbJabJbbJcbJdbJebJfbJgbJhbJibJjbJkbJlbJmbHsbJnbJobJnbJobJpbHsbHtbJqbJrbJsbJtbJubJvbJwbJxbJybJrbJzbFObFObEobJAbJBbJCbJDbJEbEobHIbGabGabGabGabGabGabGabJFbJGbGtbJIbJJbHLbJKbEtbJLbJMbJNbHSbHTbHUbJObJPbEubJQbJRbJSbJTbJTbJUbJVbGxbJXbJYbJYbJYbJZbJYbKabKbbKcbKdbKebKfbKgbKhbKibKibKibKjbEDbKkbGGbKlbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabItbKmbKmbKmbIyaaabItbKmbKmbKmbIyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbKnbKobKpaRcaRcaRcbngaSfaSfbCfbKqbCfbKrbKsbKtbKubCfblQbKvbKvbKwbKxbKwbKwbKwbKxbKwblQblQbxbbxbbxbbKybxbbKzbKzbKzbKzbKzbKzbIUbKAbKBbKCbzFbKDbGybKFbKGbKHbKIbKJbKKbGAbKMbKNbKObKPbKQbKQbKRbKSbKTbKUbKVbKWbKXbKYbFCbKZbHqbLabHobLbbFCaaabLcbLdbLebLfbLdbLdbLdbLdbLgbxvbLhbFObLibLjbLkbLlbLmbLnbLobEobLpbLqbLrbLsbLtbLubLvbLwbGabLxbEtbLybJJbLzbLAbEtbLBbLCbHRbHSbHTbHUbHQbHTbEubHVbGqbLDbLEbLFbLGbLHbLIbLJbLKbLLbLMbLNbLObLPbEAbLQbLRbLSbEDbLTbLUbLVbIpbLWbLXbEDbKkbGGbLYbGHaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbLZbMabKpaSeaSebMbbMcaSebMdbCfbMebIBbMfbMgbMhbMibCfaaaaabaabbMjbMkbMkbMkbMkbMkbMlaaaaaabKBbMnbMobMpbMqbKzbKzbKzbKzbKzbKzbMrbMsbGBbMubMvbMwbMxbDXbzJbzJbMzbMAbzJbzJbMBbMCbMDbMEbMFbMGbMGbMHbMGbMIbMJbMGbMKbKYbFCbMLbFEbFEbFEbMMbFCaaabLcbLdbMNbMObMPbMQbMRbMSbMTbMUbMVbFObMWbEobMXbMYbMZbNabNbbNcbNdbNebNfbNgbNhbNibNjbNkbNlbNmbNnbNobJJbNpbNqbEtbNrbNsbNtbNubNvbNwbNxbGobEubNybNzbNAbNBbNBbNCbNDbNEbNFbNGbNHbNIbNJbNKbNLbEAbNMbLRbNNbEDbNObNPbNQbIpbIpbNRbEDbIrbGGbNSbGHaaaaaaaaaaaaaabbNTbNUbNVbNUbNVbNUbNWaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbKpbKpbHHaSdaSdaUlaLdaSdaSdbCfbOabIBbIBbIBbCfbCfbCfaaaaaaaaabObbOcbOcbOdbOcbOcbObaaaaaabKBbOebKzbOfbOgbOgbOgbOgbOgbOhbOibOgbOjbJHbOlbOmbOnbOobOpbzJbOqbBnbOrbOsbDXbOtbOubOvbMEbMEbMGbOwbOxbOybOzbOAbMGbFBbKYbFCbOBbOCbJWbOEbOFbFCaaabOGbLdbOHbOIbOJbOKbOLbOKbOMbONbOObFObOPbEobOQbOQbORbOSbOTbOUbOVbOWbOXbOYbOZbOZbPabPbbPcbPdbEtbNobPebPfbEtbEtbEubPgbPhbPibEubEubEubEubPjbPkbGqbPlbLEbLFbPmbNBbNEbPnbPobPobPpbIdbPqbPrbPsbPtbIjbPubEDbPvbPwbIpbPxbPybPzbEDbKkbPAbGHbGHaaaaaaaaaaaaaabbPBbPCbPDbPEbPFbPGbPBaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbPIbPIbPIbPJbPKbPIbPIbPIbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbObbKEbKBbKBbPNbPObPPbPQbPQbPQbPObKzbIUbKAbKzbKzbKBbPRbPSbPTbPUbPVbKLbPXbBnbBnbPYbDXbOtbOubPZbMmbQbbQcbQdbQebQfbQgbQhbMGbQibQjbHmbQkbQlbQmbQnbQobHsbHtbQpbLdbQqbQrbQsbOKbQtbOKbQubONbQvbFObQwbEobQxbQybQzbQAbQBbQCbQDbQEbQFbQFbQGbQHbQFbQFbQIbQJbQKbQLbQMbQNbQObQPbQQbQRbQSbQTbQUbQVbQWbQXbQYbQZbGqbRabRbbRcbRdbRebIabRfbPobPobRgbRhbPqbRibEAbRjbRjbRkbEDbRlbRmbRnbRobIpbRpbEDbKkbRqbGHaaaaaaaaaaaaaaaaabbRrbRsbPDbPFbPDbRtbNVaabaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbRubRvbRwbRxbRybRzbRAbRybRBbRCbRDbPIbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbREbRFbRGbRFbRHbRIbRJbRIbRIbRIbRIbRKbIUbKAbRLbxbbxbbRMbBnbzFbPUbRNbDXbRObRPbRPbRQbMtbRSbRTbRUbRVbRWbRXbRYbRZbSabSbbScbMGbMKbKYbFCbSdbSebSfbSgbShbFCaaabOGbSibSjbSibSibSibSibSibSkbSibSlbFObQwbEobSmbSnbSnbSobSpbOUbSqbSrbSsbStbSubSvbSwbSsbSxbSybSzbSAbSBbSCbSDbSDbSEbSFbSGbSHbSIbSJbSKbSLbSMbSNbSObSPbSPbSQbSRbSSbIabSTbIdbIdbSUbSVbPqbSWbMybSYbSZbTabTbbNXbTdbTebNYbTebEDbEDbTgbPtbThbTibTibTibTibTibThbPBbPFbPDbPFbPFbPGbPBaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbRAbRAbRAbTjbRybTkbTkbRybTlbRAbRAbTmbTnbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbTobNZbTqbNZbTrbKzbPPbPQbPQbPQbKzbKzbIUbKAbTsbTtbxbbTubBnbzFbPUbTvbDXbTwbBnbBobBnbOkbOtbTybTzbRVbRWbTAbTBbTCbTDbTEbTFbTGbTHbTIbTJbTJbTKbTLbTMbFCbFCaaabOGbSibTNbTObTPbTQbTRbTSbTTbTUbTVbFObQwbNcbTWbTXbTYbTZbUabOUbUbbUcbUdbUebUfbUgbUhbUibUjbUkbUlbUmbUnbUobUpbUqbUrbUsbUtbUubUvbQVbUwbQXbUxbUybGrbUzbUAbUBbUCbUCbIabUDbUEbUFbIabUGbPqbUHbIabUIbUJbUKbULbUMbUNbUObUPbUQbURbUSbUTbUUbUVbUWbUWbUXbUYbUZbODbVbbNUbNVbVcbNVbNUbVdaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIbVebVfbVgbVhbVibRybVjbRAbVkbRAbRAbRAbRAbRAbTjbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbVlbOcbOcbOcbVmbObbKEbKBbKBbVnbKzbPPbKzbKzbKzbKzbKzbIUbKAbTsbVobxbbVpbBnbVqbVrbBnbPMbzEbBnbBnbVtbDXbOtbTybTzbRVbRWbMGbVubVvbVwbVxbVybMHbVzbVAbVBbVCbHsbPWbVEbHsbHtbHtbVFbSibVGbVHbVIbVJbVKbVKbVLbQabVNbFObVObEobOUbVPbOQbVQbVRbOUbUbbVSbVTbVUbVVbVWbVXbVTbUbbVYbVZbWabWbbWabWcbWabWdbWdbWebWfbWgbWgbWgbWhbWgbWgbWibWibWjbWkbWjbWjbIabIabIabIabIabWlbRRbLIbIabWnbWobWpbWqbWqbWrbWsbWtbWubWvbWwbWxbWybWzbWAbWAbWBbWCbWDbThbODbODbODbWEbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWFbWGbRAbRAbWHbWHbWHbRybRAbRAbRybWIbWJbWKbWLbWMbWNbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbWObNZbTqbNZbPNbWPbWQbKzbKzbKzbWPbKzbIUbKAbTsbWRbxbbWSbBnbzFbPUbBnbzJbWTbBnbBnbWUbDXbOtbTybWVbRVbWWbMGbWXbWYbWZbXabXbbMHbXcbXdbXebSXbXgbXhbXibFCaaaaaaaaabSibXjbXkbXlbXlbXmbXnbXobSibXpbXqbQwbXrbXsbXtbXubXvbXwbXxbXybUcbXzbXAbXBbXCbXDbXzbUbbVYbXEbXFbXGbXHbXIbXJbWdbXKbXLbXMbXNbXObXPbXQbXRbXSbXTbXUbURbXVbWqbWqbXWbXXbWqbXYbXZbYabYbbYcbWqbYdbYebYfbYgbYhbYibYjbYkbYjbYjbYjbTgbPtbThbTibTibThbYlbYmbYnbYobYpbYqbYrbODaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYsbWGbRAbRAbRAbRAbRAbYtbRAbRAbRybPIbPIbPIbPIbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbYvbYwbYxbYwbYybYzbYAbYAbYAbYAbYAbYBbYCbYDbTsbYEbxbbYFbYGbYHbYIbYJbYKbYLbYLbYLbYMbYMbYNbTybYObTcbRWbMGbYQbYRbYSbVvbYTbMHbYUbYVbYWbTJbYXbQmbYYbFCaaaaaaaaabSibYZbZabZbbZcbXmbXnbXobSibZdbZebZfbZgbZhbZibZjbZkbZlbZmbZnbZobVTbVTbZpbZqbVTbVTbUbbVYbZrbZsbZtbZubZvbZwbWdbZxbZybZzbZAbZBbZCbZDbZDbZEbZFbZGbZHbZIbUMbUMbZJbUMbZKbUMbZLbUMbZMbZNbZNbZObZPbZQbZRbZSbZTbZUbZVbZWbZXbYjbZYbZZaaaaaaaaabThcaabUYcabbYobODcaccadbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcafcagcahcaibRAbRybRAbRAbRybRAcajcakcalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabObbOcbOcbOcbOcbOcbObbKEbKBbKBbxbbxbbKBbKBbKBbKBbKBbxbbxbbKBbKBbKBbxbcamcamcambTfcambYMcaocapcaqcarbYMbOtbTycasbMEbMEbMGbMGbMGbMGbMGbMJbMHbTJbTIcaubTJcavbTpbFCbFCbFCbFCbFCbSibSjbSibSibSibSibSibSibSicaxbFOcaycazcaAcaBcaCcaAcaAcaDcaEcaFcaGcaHcaIcaJcaKcaLbXycaMcaNcaOcaPcaQcaRcaScaTcaUcaVcaWcaXcaYcaZcbacbbcbcbWgbWicbdcbecbdcbfbTxcbfcbfcbfcbhbVacbjcbjcbkcblcbmcbnbZRcbocbpcbqcbrcbscbtbYjbZYbZZaaaaaaaaabThbVscbvbThbODbThbThbODbThaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPIbPIbPIbPIbPIbPIbRybTlbRAcbwbRAcbxcbycbzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbAcbBbOccbCbOccbDcbEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbFaabaaaaaaaaaaaacamcbGcbHcbIcbJbYMcbKcbLcbMcbNbYMbOtbTycbOcbPcbQcbRcbScbTcbUcbVcbWcbXcbYcbZccaccbcccccdcceccfccgcchcciccjcckcclccmbEnccnbFOccoccpccqbFOccrcaAccscctccuccvccwbUbccxccycczccAccBccCccDccEccFccGccHbWaccIbZuccJccKccLccMccNccObXNccPbXQbXQbXQccQbWgcbdccRccSccTccUccVccWccXcbfccYccZcdacbjcbjcdbcbmcdccddcdecdfcdgcdhcdicdjbYjcdkbGHaaaaaaaaabThbThbThbThaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIcdlcdmcdncdlcdobRybRAbRAbRybRAcdpcdqcdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdscdtcducducducdtcdvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdwcdxcdycdzbYLcdAcdBcdCcdDbYMbOtcdEcdFbTybTycdGcdHcdIcdJcclcdKcdLcdKcdMcdNcdNcdOcdPcdQcdNcdNcdRcdNcdScdNcclccmbEncdTcdUcdVcdWcdXcdYbFOcaAcdZcctceaccucebbUbceccedceecefcegcehceicejbUbcekcelbWacemcencenceocepceqcercesbXNcetceubXQcevcewbWgcbdcexceycezceAceBceCceDcbfceEccZceFceFcbjceGceHceIceJceKceLceMceNceOcePbYjbZYbGHceQaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPHbPIcdlcdmcdncdlcdobRybRAbRAbRybRAcdpcdqcdraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdscdtcducducducdtcdvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacamcdwcdxcdycdzbYLcdAcdBcdCcdDbYMbOtcdEcdFbTybTycdGcdHcdIcdJcclcdKcdLcdKcdMcdNcdNcdOcdPcdQcdNcdNcdRcdNcdScdNcclccmbEncdTcdUcdVcdWcdXcdYbFOcaAcdZcctceaccucebbUbceccedceecefcegcehceicejbUbcekcelbWacemcencenceocepceqcercesbXNcetceubXQcevcewbWgcbdcexceycezbVDceBceCceDcbfceEccZceFceFcbjceGceHceIceJceKceLceMceNceOcePbYjbZYbGHceQaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabWFbWGceRceRceRceRceRceSbRAbRAbRybPIbPIbPIbPIbPIbPIbPLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceTceUceUceUceVaaaaaaaaaaaaaaaaaaaaaceWceXceYceXceZaaaaaaaaacamcamcamcfacfbcdycfcbYLcfdcbMcfecffbYMbOtcfgcfhcficfjcfkcflcfmcfncfocfpcfqcfrcfscftcftcfucfvcfvcfvcfvcfvcfvcfwcfxcfycfzcfAcfBcfCcfDcfEcfFcfGcfHcaAcfIcctccucfJcebbUbceccedcfKcfLcfMcfNcfOcfPbUjcfQcfRbWabWacfScfSbWacepbWdcfTcfUbWgcfVcfWcfXcfYcfZbWgcbdcgacgbcgccgdcgecgfcggcbfcghccZceFceFcbjcgicgjcgkcglcgmcgncgocgpcgqcgrbYjbZYcgscgtcgscgucgvcgucgucguaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYsbWGceRceRceRcgwcgxbRybRAbRAbRybRAbRAbRAcgybRAcgzbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgAcgBcgCcgDcgAcgEcgEcgEcamcgFcgGcgHcgIcgJcgKcgLcgMcgNcgNcgObYMcgPcgQcgRcgScgScgTcgUcgVcgScgWcgWcgXcgYcgZcgWcgWchacclcclchbchcchcchcchdchechcchcchfchgchhchhchichhchjchkchhchlchmchncaAchochpcecchqchrchschtchuchvchrbUbcekchwchxchychzchAchBchCchDchEchFchGchHchIchJchKchLbWicbdcbdchMchNchOchPchOchQcbfchRchSchTchTcbjchUchVchWbYjbYjbYjbYjbYjbYjbYjbYjbZYcgschXchYchZciaciacibcguaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcicciccicciccidcidcieciecieciecifaabaabaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcigceRceRcihciibRybRAbRAcijbRAbRAbRAcikbRAcilbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcimcincimceYcgEciocipcamciqcfbcirciscitciubYMcivciwcixciybYMcgQcgQcizcgSciAciBciCciDciEcgWciFciGciHciIciJcgWciKciLciMchcciNciOciPciQciRciSciTciUciVciWciXciYciZcjacjbcjccjdcjecjfcjgcjhcjicjjcedcjkcjlcjmcjncjocjpbUjcjqcjrcjscjtchAcjucjucjvcjwbWgcjxcjycjzcjAcjBcjCcjDbWicjEcjFcjGcjHcjGcjGcjIcjJcjKcjLcjMcjNcjOcbjcjPcjQcbnbPtbGGcjRcjScjTcjTcjScjTcjUcgscjVcjWchZciacjXcjYcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccjZckacjZcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIckdceRceRckebRybRAbRAbRyckfbRAbRAckgckhbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgAckicimcimckjckkcfbcfbcklckmcfbcfbciscknckobYMbYMbYMbYMbYMbYMckpcgQckqckrckscktcktcktckucgWckvckwckwckwckxckyckzckAckBckCckDckEckFckGckHckIchcchfckJchhckKckLckMckNckOchhcdZccuceaccuckPckQckRckSckTckUckVckWckXchrckYckZclaclbclccldcleclfclgclhbWgbWgbWgbWgbWgclicljclkbWicllcjGcjGclmclncjGcloclpcbjclqccZclrclrcbjcblclscbnbPtcgscltcgscgscgscgscgscgscgscluclvcguclwclxclycguaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacclzcjZcjZclAciecieckbckbclBckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIclCclDclEbRybRAclFbRyclGclHbRAbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcincincinceYcgEclIclJclKckmcfbcfbclLclMclNclOclPclPclPclQcgQcgQcgQcizcgSclRcktclScktclTcgWckvckwclUckwclVcgWclWclXclYchcclZcmacmbcmccmdcmecmfcmgcmhcmicmjcmkcmlcmmcmnchhcfIccuccucmockPckQcmpcmqcmrcjlcmscmtcmucmvcmwcmxcmycmzcmAcmBcmCcmDcjucmEchxcmFcmGcmHcmIcmJcmKcmLclpcllcmMcjGcjGcjGcmNcmOclpcbjcmPccZclrclrcbjcmQcmRcbnbPtcmScmTcmUcgscmVcmWcmXcmYcmZcnacnbcgucnccndcnecgucgscgscgscgscgscgscgscgsaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacnfcieclzciecieckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIbPIbPIbPIbPIbPIbPIbPIbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaccgQcngcngcgQcngcngcgQaaaaaacgAcnhcnicnjcgAcgEcgEcgEcamcnkcnlcnmcnmcnmcamcamcgQcnncnocnpcnqcgQcnrcnscgSclRcktcktcktcntcgWckvckwckwcnucnvcnwcnxcnycnzchcchcchcchcchccnAchcchccnBcnCchhchhcnDchhchkchhchhcaAcnEcnEcaAcnFcnGcnHcnIcnJcnKcnLcnMcnNcnObQVcnPcmycmzcnQcnRcnScnTcnUcnVchxcnWcnXcnYcnZcoacobcoccodcoecodcofcofcofcodcogcodcodcohcoiclrclrcbjcojclscbncokcolcomconcoocopcoqcoqcorcoscotcoucovcowcoxcoycozcoAcoBcoCcoDcoEcoFcoGcoHaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacidciecoIcoJcoJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacgQcoKcoLcgQcoKcoLcgQaaaaaacoMceXcoNceXcoOaaaaabaaacamcamcamcamcamcamcamcoPcgQcoQcoRcoScoTclPcoUcoVcgScoWcoXcoYcktcoZcpacpbcpccpdcpecpfcgWcpgcphcpicpjcpkcpkcpkcpkcplcpmcpncpocpocppcppcpqcprcpschfcaAcptcpucpvcpwcpxckQcpycnIcpzcpAcpBcpCceicpDcpEcpFcpGcpHcpHcpIcpHcpHcpHcpJchxcpKcpLcpMcpNcpOcpPcpQcpRcpScpRcpTcpUcpVcpRcpWcpXcodcpYcpZcdacbjcbjcqacqbcqccqdcqecqfcqgcqhcqicqjcqkcqlcqmcqncqocqpcqqcqrcqqcqscqrcqrcqrcqtcqucqvcqwcqxaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacieciecqyckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaccgQcqzcoLcgQcqzcoLcgQaaaaaaaabaabaabaabaabaabaabaabaabcgQcoLcqAcqBcgQcqCcqDcgQcqEcgQcgQcqFcgQcgQcqGcgScqHcqIcqJcqKcqLcqMcqNcqOcqPcqQcqRcpacqScqTcqUcqVcqWcqWcqWcqWcqXcqYcqZcracrbcracrccrdcrecrfcrgcrhcricrjcrkcrlcrmcrncrocrpcrqcrrcrscrtcrucrvcrwcrxcrybXubXucrzcrAcrBcrtcrCcrDcrDcrEcrDcrFcrGcrHcrIcpRcrJcrKcrLcrMcrLcrNcrOcrPcodcbjcrQcbjcbjcrRcrSclsbLRbPtcgscrTcgscgscrUcrVcrWcrXcrYcqrcrZcsacsbcqkcsbcqkcsccqkcqkcgscsdcsecsfcsgaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacieckbckbckbckbckbckbcshckbcsickbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjaacaabaMraMraaccgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsncgQcsocspcoLcgQcsqcgScsrcsscstclRcsucsvcswckvcsxcsycszcsvcsAcsBcsCcsDcsDcsEcsFcsGcsHcsIcsJcsKcsLcsMchfcsNcsLcsLcsOcsPcsQcsRcsScrlcsTcsUcsVcsWcsXcsYcsZctactbcsYcsYctcctdctdctdctdctdctectfctgcthcthctictjctkctlctmctncpRctoctpctqctrctqctscttcrLctuctvctwbLRctxbLRcrSclsbLRbIictyctzctAcgscgscgscgscgsctBcqkctCctDcsccqkctEcqkclucqkctFcgsctGctHctIcgsaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctKckbctLctJcsickbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaaccngcoLcoLcoLcoLctMctNcoLcoLcoQctOctOctPctOctOctOctOctOctOctOctOctOctOctOctOcoRcgQcskcqzctQcgQcsqctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWctSctTctUctVctWctXctYctYctZcuacsJcsLcsLcubcuccudcsLcsLcsLcuecufcugcrjcuhcuicujctdcukculcumcecculcuncuocuocuocupcuqcuqcuqcuqcurcusceccutcuucuvcuwcuxcuycuzcuAcpRcuBcuCcrLcuDcrLcuEcuFcuGcuHcuIcuJcuKbLRcuLcrSclscuMbIibPAcuNcuOcuPcuQbGGbGGcgscuRcuScuTcuUcuVcuWcuXcuYcuZcvacvbcgscvccvdcvecvfaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvgcjZcjZcjZcjZcjZcjZcjZcvhcvickbckbckbckbcvjckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaabaaccngcvkcvlcvmcoLcoLcvncoLcoLcsncgQcgQcgQcgQcgQcgQcqFcgQcgQcgQcgQcvocvocvocvocvocvocvocvocvocgQcsqcvpaaaaaaaaaaaacvqcvrcvscvtcvucvvcvwcvxcvycvzcvAcvBcvCcvDcvEcvEcvFcvGcvHcvIcvIcvIcvIcvJcvIcsLcsLcaAcvKcvLcvMcvNcvOcvPcuxcvQcvRcvScvTcvUcvVcvWcuqcuocvXcvYcvYcvYcvYcvZcwacwbcwccwdcwecwfcwgbQVcwhcwicpRcwjcwkcwlcwmcwncrLcwocpRcpRbIicwpbIibIibIicwqcwrcwsbIibGGcuNcwtcwucuQcuQcuQcgscgscgscgscgscgscgscgscgscgscgscgscgscgscgscgscgsaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciecoJcoJcoJcoJcoJcoJcwvckbcoIcoJcwwckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgQcwxcwxcwxcwxcwxcwxcwycwxcsncwzcgQcoLcwAcwBcwCcoLcwCcwDcwEcwBcvocwFcwFcvocwGcvocwHcwIcvocoLcqGcngaaacwJcwKcwLcwMcwNcwOcwPcwQcwRcwScwTcwUcwVcwWcwXcwYcwZcxacxbcxccxdcvHcxecxfcxfcxfcxgcvIcsLcsLcxhcxhcxhcxhcxicxhcxjcxjcxkcxhcxhcxlcxhcxmcxncxocxpcxocxqcxrcxscxtcxucxvcxwcxxcxycxzcxAcxBcxCcxDcpscpRcpRcxEcpRcxFcpRcxGcxHcxIcsMcxJcxKcxLcxMcxNcxOcxPcxQcxNbGGcuNcxRbGGbGGcxScxTcxUctybGGbGGbGGbGGbGGbGGbGGcxVcxWbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieckbckbckbckbckbckbcshckbcwwckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYsbWGceRceRceRcgwcgxbRybRAbRAbRybRAbRAbRAcgybRAcgzbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgAcgBcgCcgDcgAbVMbVMbVMcamcgFcgGcgHcgIcgJcgKcgLcgMcgNcgNcgObYMcgPcgQcgRcgScgScgTbWmcgVcgScgWcgWcgXbXfcgZcgWcgWchacclcclchbchcchcchcchdchechcchcchfchgchhchhchichhchjchkchhchlchmchncaAchochpcecchqchrchschtchuchvchrbUbcekchwchxchychzchAchBchCchDchEchFchGchHchIchJchKchLbWicbdcbdchMchNchOchPchOchQcbfchRchSchTchTcbjbYPcatcanbYjbYjbYjbYjbYjbYjbYjbYjbZYcgschXchYchZciaciacibcguaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcicciccicciccidcidcieciecieciecifaabaabaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIcigceRceRcihciibRybRAbRAcijbRAbRAbRAcikbRAcilbRyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcimcincimceYbVMciocipcamciqcfbcirciscitciubYMcivciwcixciybYMcgQcgQcizcgSciAciBciCciDciEcgWciFciGciHciIciJcgWciKciLciMchcciNciOciPciQciRciSciTciUciVciWciXciYciZcjacjbcjccjdcjecjfcjgcjhcjicjjcedcjkcjlcjmcjncjocjpbUjcjqcjrcjscjtchAcjucjucjvcjwbWgcjxcjycjzcjAcjBcjCcjDbWicjEcjFcjGcjHcjGcjGcjIcjJcjKcjLcjMcjNcjOcbjcjPcjQcbnbPtbGGcjRcjScjTcjTcjScjTcjUcgscjVcjWchZciacjXcjYcguaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccjZckacjZcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIckdceRceRckebRybRAbRAbRyckfbRAbRAckgckhbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgAckicimcimckjckkcfbcfbcklckmcfbcfbciscknckobYMbYMbYMbYMbYMbYMckpcgQckqckrckscktcktcktckucgWckvckwckwckwckxckyckzckAckBckCckDckEckFckGckHckIchcchfckJchhckKckLckMckNckOchhcdZccuceaccuckPckQckRckSckTckUckVckWckXchrckYckZclaclbclccldcleclfclgclhbWgbWgbWgbWgbWgclicljclkbWicllcjGcjGclmclncjGcloclpcbjclqccZclrclrcbjcblclscbnbPtcgscltcgscgscgscgscgscgscgscluclvcguclwclxclycguafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOafOclzcjZcjZclAciecieckbckbclBckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIclCclDclEbRybRAclFbRyclGclHbRAbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceYcincincinceYbVMclIclJclKckmcfbcfbclLclMclNclOclPclPclPclQcgQcgQcgQcizcgSclRcktclScktclTcgWckvckwclUckwclVcgWclWclXclYchcclZcmacmbcmccmdcmecmfcmgcmhcmicmjcmkcmlcmmcmnchhcfIccuccucmockPckQcmpcmqcmrcjlcmscmtcmucmvcmwcmxcmycmzcmAcmBcmCcmDcjucmEchxcmFcmGcmHcmIcmJcmKcmLclpcllcmMcjGcjGcjGcmNcmOclpcbjcmPccZclrclrcbjcmQcmRcbnbPtcmScmTcmUcgscmVcmWcmXcmYcmZcnacnbcgucnccndcnecgucgscgscgscgscgscgscgscgsaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacnfcieclzciecieckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaebPIbPIbPIbPIbPIbPIbPIbPIbPIbPIbYuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabafOcgQcngcngcgQcngcngcgQaaaaaacgAcnhcnicnjcgAbVMbVMbVMcamcnkcnlcnmcnmcnmcamcamcgQcnncnocnpcnqcgQcnrcnscgSclRcktcktcktcntcgWckvckwckwcnucnvcnwcnxcnycnzchcchcchcchcchccnAchcchccnBcnCchhchhcnDchhchkchhchhcaAcnEcnEcaAcnFcnGcnHcnIcnJcnKcnLcnMcnNcnObQVcnPcmycmzcnQcnRcnScnTcnUcnVchxcnWcnXcnYcnZcoacobcoccodcoecodcofcofcofcodcogcodcodcohcoiclrclrcbjcojclscbncawcolcomconcbgcopcoqcoqcorcoscotcoucovcowcoxcoycozcoAcoBcoCcoDcoEcoFcoGcoHaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacidciecoIcoJcoJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacgQcoKcoLcgQcoKcoLcgQaaaaaacoMceXcoNceXcoOaaaaabaaacamcamcamcamcamcamcamcoPcgQcoQcoRcoScoTclPcoUcoVcgScoWcoXcoYcktcoZcpacpbcpccpdcpecpfcgWcpgcphcpicpjcpkcpkcpkcpkcplcpmcpncpocpocppcppcpqcprcpschfcaAcptcpucpvcpwcpxckQcpycnIcpzcpAcpBcpCceicpDcpEcpFcpGcpHcpHcpIcpHcpHcpHcpJchxcpKcpLcpMcpNcpOcpPcpQcpRcpScpRcpTcpUcpVcpRcpWcpXcodcpYcpZcdacbjcbjcqacqbcqccqdcqecqfcqgcqhcqicqjcqkcqlcqmcqncqocqpcqqcqrcqqcqscqrcqrcqrcbicqucqvcqwcqxaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaacieciecqyckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafOaaaafOcgQcqzcoLcgQcqzcoLcgQaaaaaaaabaabaabaabaabaabaabaabaabcgQcoLcqAcqBcgQcqCcqDcgQcqEcgQcgQcqFcgQcgQcqGcgScqHcqIcqJcqKcqLcqMcqNcqOcqPcqQcqRcpacqScqTcqUcqVcqWcqWcqWcqWcqXcqYcqZcracrbcracrccrdcrecrfcrgcrhcricrjcrkcrlcrmcrncrocrpcrqcrrcrscrtcrucrvcrwcrxcrybXubXucrzcrAcrBcrtcrCcrDcrDcrEcrDcrFcrGcrHcrIcpRcrJcrKcrLcrMcrLcrNcrOcrPcodcbjcbucbjcbjcrRcrSclsbLRbPtcgscrTcgscgscrUcrVcrWcrXcrYcqrcrZcsacsbcqkcsbcqkcsccqkcqkcgscsdcsecsfcsgaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaacieckbckbckbckbckbckbcshckbcsickbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcsjafOaabaMraMrafOcgQcgQcqFcgQcgQcqFcgQcgQcgQcngcngcngcgQcgQcgQcgQcgQcgQcgQcoLcskcslcgQcsmcgQcgQcsncgQcsocspcoLcgQcsqcgScsrcsscstclRcsucsvcswckvcsxcsycszcsvcsAcsBcsCcsDcsDcsEcsFcsGcsHcsIcsJcsKcsLcsMchfcsNcsLcsLcsOcsPcsQcsRcsScrlcsTcsUcsVcsWcsXcsYcsZctactbcsYcsYctcctdctdctdctdctdctectfctgcthcthctictjctkctlctmctncpRctoctpctqctrctqctscttcrLctuctvctwbLRctxbLRcrSclsbLRbIictyctzctAcgscgscgscgscgsctBcqkctCctDcsccqkctEcqkclucqkctFcgsctGctHctIcgsaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciectJctJctJctJctJctJctKckbctLctJcsickbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOafOcngcoLcoLcoLcoLctMctNcoLcoLcoQctOctOctPctOctOctOctOctOctOctOctOctOctOctOctOcoRcgQcskcqzctQcgQcsqctRctRctRctRctRctRcgWcgWcgWcgWcgWcgWcgWctSctTctUceActWctXctYctYctZcuacsJcsLcsLcubcuccudcsLcsLcsLcuecufcugcrjcuhcuicujctdcukculcumcecculcuncuocuocuocupcuqcuqcuqcuqcurcusceccutcuucuvcuwcuxcuycuzcuAcpRcuBcuCcrLcuDcrLcuEcuFcuGcgEcuIcuJcuKbLRcuLcrSclscuMbIibPAcuNcuOcuPcuQbGGbGGcgscuRcuScuTcuUcuVcuWcuXcuYcuZcvacvbcgscvccvdcvecvfaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaacvgcjZcjZcjZcjZcjZcjZcjZcvhcvickbckbckbckbcvjckccieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabaabafOcngcvkcvlcvmcoLcoLcvncoLcoLcsncgQcgQcgQcgQcgQcgQcqFcgQcgQcgQcgQcvocvocvocvocvocvocvocvocvocgQcsqcvpaaaaaaaaaaaacvqcvrcvscvtcvucvvcvwcvxcvycvzcvAcvBcvCcvDcvEcvEcvFcvGcvHcvIcvIcvIcvIcvJcvIcsLcsLcaAcvKcvLcvMcvNcvOcvPcuxcvQcvRcvScvTcvUcvVcvWcuqcuocvXcvYcvYcvYcvYcvZcwacwbcwccwdcwecwfcwgbQVcwhcwicpRcwjcwkcwlcwmcwncrLcwocpRcpRbIicwpbIibIibIicwqcwrcwsbIibGGcuNcwtcwucuQcuQcuQcgscgscgscgscgscgscgscgscgscgscgscgscgscgscgscgscgsaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaciecoJcoJcoJcoJcoJcoJcwvckbcoIcoJcwwckbckbckbckbcieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcgQcwxcwxcwxcwxcwxcwxcwycwxcsncwzcgQcoLcwAcwBcwCcoLcwCcwDcwEcwBcvocwFcwFcvocwGcvocwHcwIcvocoLcqGcngaaacwJcwKcwLcwMcwNcwOcwPcwQcwRcwScwTcwUcwVcwWcgUcwYcwZcxacxbcxccxdcvHcxecxfcxfcxfcxgcvIcsLcsLcxhcxhcxhcxhcxicxhcxjcxjcxkcxhcxhcxlcxhcxmcxncxocxpcxocxqcxrcxscxtcxucxvcxwcxxcxycxzcxAcxBcxCcxDcpscpRcpRcxEcpRcxFcpRcxGcxHcxIcsMcxJcxKcxLcxMcxNcxOcxPcxQcxNbGGcuNcxRbGGbGGcxScxTcxUctybGGbGGbGGbGGbGGbGGbGGcxVcxWbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieckbckbckbckbckbckbcshckbcwwckbckbckbckbckbciecieaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacxXcxYcxYcxYcxYcxYcxYcxZcyacybcyccydcyecyfcwycsncygcgQcoLcyhcwBcoLcoLcoLcwDcqBcwBcvocwFcyicwIcwIcyjcwIcykcvocylcqGcngaaacymcyncyocypcyqcwOcyrcyscytcyucvxcyvcsBcywcvBcyxctYcyyctYcyzcyAcyBcyCcyDcyDcyDcyEcvIcsLcsLcxhcyFcyGcyHcyIcyJcyKcyKcyLcyMcyNcyOcyPcyQcyRcyScyTcyUcyVcyWcyXcyYcyZczaczbcxBczcczdczecxxczfczgczhczicziczjczkczlczmcznczoczmczmczmczpczmczmczqczrczscztczuczvczwczxczyczyczzczyczyczyczyczAczBczyczyczyczCczDbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacieciecqyckbckbckbckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczEczFczFczFczFczGczHczIczJczKczKczLcwxcsncoLcqFcoLcoLcoLcoLcoLcoLcoLcoLcoLcvocvocwIczMcwIcvocwIczMcvoczNcsqcngaaacymczOczPczQczRczSczTczUczRczRczVczWczXczYczZczZcAacAbctYcAccAdcyBcyDcyDcyDcyDcAecvIcsLcsLcxhcAfcAgcAhcAicAjcAkcAkcAlcAmcAncAocyKcApcxhcAqcuocArcvYcAscAtcAucAvcAwcAxcxBcAycAzcAAcxBcABcACcADcAEcAEcAEcAEcAEcAFcAGcAHcAIcAJcAJcAKcAKcAJcALcAMcANcAOcAPcAPcAQcARcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAScATcAUbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacnfcieciectJctJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcAWcAXcAYcAXcAZcBacBbcBccBdcBecwxcsncgQcgQcBfcngcngcngcngcngcngcngcBgcvocwIcwIcwIcwIcBhcwIcwIcvocygcqGcngaaacymcBicBjcBkcBlcwOcBmcBncBocBpcvxcyvcsBcnycBqcsDcBrcsDcvBcvBcvBcBscBtcyDcyDcBucBvcvIcsLcBwcxhcBxcBycBzcBAcBAcBBcBCcBDcBAcBAcBEcyKcBFcxhcBGcuocBHcvYcvYcBIcvYcvYcAwcBJcxBcBKcBLcBMcxBcBNcBOcBwcBPcBPcBPcBPcBPcBQcBQcBQcBPcBPaaaaaaaaaaaacBRcBScBTcBUcAPcBVcBWcBXcBYcBZcCacCbcCccCdcCecCfcCgcChcCicAPcAScCjcCkcClcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCncCocieclzcieckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcCpcCqcCrcCsczJcCtcCucCvczJcCwcCxcCycskcgQcoLcngaaaaaaaaaaaaaaacngcoLcCzcwFcCAcwIcwIcwIcwIcCBcCCcCDcCEcngaaacCFcwKcCGcwMcCHcwOcwOcCIcCJcCKcCLcCMcCNcCOcBqcsDcCPcCQcCRcCScCTcvHcCUcyDcyDcyDcCVcvIcsLcsLcCWcCWcCXcCYcCZcCZcDacDbcDccDdcDdcDecDfcDgcDfcAqcuocArcDhcDicDjcDkcDlcAwcDmcxBcDncDocDpcxBcsLcBOcBPcBPaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDqcDrcDscDtcDucDvcDwcDwcDxcDwcDwcDwcDwcDwcDycDzcDAcDBcDCbGHcDDcjUbGHbGHaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciecDEcDFcDGciecieckbckbcDHckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcDIcAXcDJcAXcDKcDLcDMcDNcBbcDOcwxcDPcqBcgQcqzcvpaaaaaaaaaaaaaaacvpcDQcvocDRcDRcwFcDScDTcwIcDUcvocoLcqGcvpaaaaaaaaaaaacvqcDVcDWcDXcDXcvxcDYcvxcDZcsBcnycEacEbcEccEdcEecEecEecEfcEgcyDcEhcyDcEicvIcsLcsLcCWcEjcEkcElcEmcEncEocCWcEpcEqcErcEscEtcEucDfcEvcEwcExcDhcEycEzcEAcEBcECczbcxBcEDcEEcEFcxBcsLcBOcBPaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDqcEHcEIcEJcEKcELcEMcENcEOcDwcDwcEPcDwcDwcDycDAcDAcDAcEQbGHcERbGGbGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccEScETclAcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczEczFczFczFczFczGczHczIczJczKczKczLcwxcsncoLcqFcoLcoLcoLcoLcoLcoLcoLcoLcoLcvocvocwIczMcwIcvocwIczMcvoczNcsqcngaaacymczOczPczQczRczSczTczUczRczRcgYczWczXczYczZczZcAacAbctYcAccAdcyBcyDcyDcyDcyDcAecvIcsLcsLcxhcAfcAgcAhcAicAjcAkcAkcAlcAmcAncAocyKcApcxhcAqcuocArcvYcAscAtcAucAvcAwcAxcxBcAycAzcAAcxBcABcACcADcAEcAEcAEcAEcAEcAFcAGcAHcAIcAJcAJcAKcAKcAJcALchUchWchVcAPcAPcAQcARcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAPcAScATcAUbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacnfcieciectJctJckbckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcAWcAXcAYcAXcAZcBacBbcBccBdcBecwxcsncgQcgQcBfcngcngcngcngcngcngcngcBgcvocwIcwIcwIcwIcBhcwIcwIcvocygcqGcngaaacymcBicBjcBkcBlcwOcBmcBncBocBpcvxcyvcsBcnycBqcsDcokcsDcvBcvBcvBcBscBtcyDcyDcBucBvcvIcsLcBwcxhcBxcBycBzcBAcBAcBBcBCcBDcBAcBAcBEcyKcBFcxhcBGcuocBHcvYcvYcBIcvYcvYcAwcBJcxBcBKcBLcBMcxBcBNcBOcBwcBPcBPcBPcBPcBPcBQcBQcBQcBPcBPaaaaaaaaaaaacBRcBScBTcBUcAPcBVcBWcBXcBYcBZcCacCbcCccCdcCecCfcCgcChcCicAPcAScCjcCkcClcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCmcCncCocieclzcieckbckbckbckbckbckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcCpcCqcCrcCsczJcCtcCucCvczJcCwcoocCycskcgQcoLcngaaaaaaaaaaaaaaacngcoLcCzcwFcCAcwIcwIcwIcwIcCBcCCcCDcCEcngaaacCFcwKcCGcwMcCHcwOcwOcCIcCJcCKcCLcCMcCNcCOcBqcsDcCPcCQcCRcCScCTcvHcCUcyDcyDcyDcCVcvIcsLcsLcCWcCWcCXcCYcCZcCZcDacDbcDccDdcDdcDecDfcDgcDfcAqcuocArcDhcDicDjcDkcDlcAwcDmcxBcDncDocDpcxBcsLcBOcBPcBPaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDqcDrcDscDtcDucDvcDwcDwcDxcDwcDwcDwcDwcDwcDycDzcDAcDBcDCbGHcDDcjUbGHbGHaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciecDEcDFcDGciecieckbckbcDHckbckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAVcDIcAXcDJcAXcDKcDLcDMcDNcBbcDOcwxcDPcqBcgQcqzcvpaaaaaaaaaaaaaaacvpcDQcvocDRcDRcwFcDScDTcwIcDUcvocoLcqGcvpaaaaaaaaaaaacvqcDVcDWcDXcDXcvxcDYcvxcDZcsBcnycEacEbcEccEdcEecEecEecqtcEgcyDcEhcyDcEicvIcsLcsLcCWcEjcEkcElcEmcEncEocCWcEpcEqcErcEscEtcEucDfcEvcEwcExcDhcEycEzcEAcEBcECczbcxBcEDcEEcEFcxBcsLcBOcBPaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacDqcEHcEIcEJcrQcELcEMcENcEOcDwcDwcEPcDwcDwcDycDAcDAcDAcEQbGHcERbGGbGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciccEScETclAcidciecieckbckcckbciecieaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacEUcEUcEUcEUcEUcwxcEVcEWcEWcEWcEWcEWaXpcEYcEYcEYcEWcEWcEWcEWcEWcEWcEWcEYcEYcEYcvocvocvocvocvocvocvocqFcEZcFacFacFacFacFacvqcvxcvxcvxcvxcvxcvxcvxcFbcsBcnycFccFdcFecFfcFgcFhcFicFjcFkcFlcFmcFncFocvIcsLcsLcCWcFpcFqcFrcFscFscFtcCWcFucFvcFvcFwcFvcFxcFycFzcFzcFzcFAcFBcFCcFDcDlcFEczbcFFcFFcFFcBPcBPcsLcBOcBQaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaacDqcFHcFIcFJcFKcFLcFMcFNcFOcDwcDwcDwcDwcFPcFQcFRcFScFTcFUbGHcERbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacicciccicciccidcidcieciecieciecifaabaabaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaacFVcFWcFXcFYcFXcFZcFWcGacGbcGccGccGdcGecGfcGgcGhcGicGjcGkcGlcGmcGmcGncGmcGocGpcGpcGqcGrcGscGtcGucGtcGtcGtcGscGtcGtcGvcGwcGxcGycsBcnycGzcGAcGBcGCcsDcGDczZcGEcGFcGGcGHcGIcGJcGKcsLcsLcCWcGLcGMcGNcGOcGPcGQcCWcGRcGScGTcGUcGVcGWcGXaaaaaaaaacFAcDhcGYcDhcDhcGZcHacHbcHccHdcHechfcsLcBOcBQaaaaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaacBScBRcHfcHgcBScHhcHicHjcHkcHlcHmcHncDwcDwcHocHpcHqcHrcHsbGHcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFVcFWcFXcFXcFXcFZcFWcHtcFXcHucFXcHvcHwcHxcHycHzcHAcHzcHBcHCcHDcHEcHDcHDcHFcnzcnzcHDcHGcHDcHDcHDcHDcHDcHDcHDcHDcHDcHDcHHcHIcHJcHKcHLcHMcHNcHOcHPcHQcHRcHScHTcHUcHVcHWcHXcHYcHZcAEcIacIbcIccIdcIecIfcIgcIhcDfcIicErcIjcIkcErcIlcGXaaaaaaaaacImcIncIocIpcIqcGZcIrcIscItcIucIvcracrecIwcBQaaaaaaaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaacBRcIxcIycIzcBRcAPcAPcAPcAPcAPcAPcIAcHncIBcICcIDcIEcAPcAPbGHcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFVcIFcFXcIGcFXcFZcIHcIIcIJcIKcILcIMcINcIOcIPcIQcIRcIScITcIUcIVcIWcIXcIYcqVcIZcqVcIUcJacIUcIUcIUcIUcIUcIUcIUcIUcIUcIUcJbcHDcJccJdcJecJfcJgcJhcJicJjcJkcJlcJmcJncJocJpcJqcJrcGHcrecJscJtcJucEmcElcEmcEmcJvcDfcJwcErcErcEscErcJxcGXaaaaaaaaacImcJycJzcJAcJBcJCcJDcJEcJFcHdcsLcuccJGcBOcBPaaaaaaaaaaaaaaaaabcBRcBRcBRcBRcBRcBRcBRcBRcBRcJHcJIcJJcxNcJKcJKcJLcBRaabcAPcAPcJMcAPcJNcJOcJPcAPcJQcuQcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJRcJScEWcEWcEWcEWcEXcEYcEYcEYcEYcJTcEYcJUcJVcJVcJWcJXcJYcEYcJZcKacKbcKbcKccKbcKdcKbcKbcKecKfcKbcKbcKfcKfcKfcKbcKbcKbcKbcKgcKhcKicKjcKkcKlcKmcKncKocKncKncKncKncKpcKqcKrcKscKtcGKcsLcKucKvcKwcKxcKycKzcKAcKBcDfcKCcKDcKEcKFcKGcKHcFyaaaaaaaaacImcKIcKJcKKcIqcKLcKMcJDcKNcHdcKOchfchfcBOcBPaaaaaaaaaaaaaaaaaacBRcKPcKQcKRcKScKTcKUcKVcxNcKWcKXcKYcxNcJKcKZcLacBRaabaabcLbcLccLdcLecLfcLgcLbbGGbGGcERcLhbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalwalvalvalwalvalvaabamhaabayiaaaayiayicLicLjcLkcLkcLkcLlcLmcEYcLncLocLpcLqcLrcLscEYcLtcLucKfcLvcLwcLxcLycLzcLAcLBcLCcLDcKbcLCcLEcLFcLGcLGcLHcKbcLIcLJcHCcLKcnycLLcLMcLNcLOcLPcLQcLPcLRcLScLTcLUcLVcLWcGKcGKcKucKvcCWcCWcLXcCWcCWcKvcLYcLZcLZcLZcMacLZcMbcFyaaaaaaaaacImcImcImcImcImcFFcMccMdcMecHdcsLcsLcMfcBOcBPaaaaaaaaaaaaaaaaaacBRcJKcMgcJKcMhcMicEHcJIcxNcxQcMjcxQcxNcJKcJKcMkcBRaabaaacLbcMlcMmcLecLecMncLbcMobGGcERbKlcMpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaabaabcLicLicMqcLicLicMrcMscEYcEYcEYcEYcEYcEYcEYcEYcLicLucKfcMtcMucMvcMwcMwcMwcMwcMxcMycMzcLGcMAcLGcLGcMBcLGcMCcMDcMEcMFcLKcnycMGcHQcMHcLOcMIcMJcMKcLOcMLcMMcMNcMOcMPcMQcMRcMScMTcMUcMUcMVcMWcMXcMYcMZcNacrecrecNbcsLcNccBPcBPcBPcBPcBPaaaaaaaaaaaacNdcNecNfcNgcHdcNhchfchfcBOcBPcBPcBPcBPcBPaaaaaacBRcJKcJKcJKcNicNjcNkcNlcNmcNncNocNpcxNcNqcNrcNscBRaaaaaacLbcNtcLecNucLecNvcLbbGGbGGcERcMpbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaacFVcFWcFXcFYcFXcFZcFWcGacGbcGccGccGdcGecGfcGgcGhcGicGjcGkcGlcGmcGmcGncGmcGocGpcGpcGqcGrcGscGtcGucGtcGtcGtcGscGtcGtcGvcGwcGxcGycsBcnycGzcGActVcGCcsDcGDczZcGEcGFcGGcGHcGIcGJcGKcsLcsLcCWcGLcGMcGNcGOcGPcGQcCWcGRcGScGTcGUcGVcGWcGXaaaaaaaaacFAcDhcGYcDhcDhcGZcHacHbcHccHdcHechfcsLcBOcBQaaaaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaaaaacBScBRcuHcHgcBScHhcHicHjcHkcHlcHmcHncDwcDwcHocHpcHqcHrcHsbGHcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFVcFWcFXcFXcFXcFZcFWcHtcFXcHucFXcHvcHwcHxcHycHzcwXcHzczVcHCcHDcHEcHDcHDcHFcnzcnzcHDcHGcHDcHDcHDcHDcHDcHDcHDcHDcHDcHDcHHcHIcHJcHKcHLcHMcHNcHOcHPcHQcHRcHScHTcHUcHVcHWcHXcHYcHZcAEcIacIbcIccIdcIecIfcIgcIhcDfcIicErcIjcIkcErcIlcGXaaaaaaaaacImcIncIocIpcIqcGZcIrcIscItcIucIvcracrecIwcBQaaaaaaaaaaaaaabaabaabaaaaaaaaaaaaaaaaaaaaacBRcIxcIycIzcBRcAPcAPcAPcAPcAPcAPcIAcHncIBcICcIDcIEcAPcAPbGHcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFVcIFcFXcIGcFXcFZcIHcIIcIJcIKcILcIMcINcIOcIPcIQcIRcIScAMcIUcIVcIWcIXcIYcqVcIZcqVcIUcJacIUcIUcIUcIUcIUcIUcIUcIUcIUcIUcJbcHDcJccJdcJecJfcJgcJhcJicJjcJkcJlcJmcJncJocJpcJqcJrcGHcrecJscJtcJucEmcElcEmcEmcJvcDfcJwcErcErcEscErcJxcGXaaaaaaaaacImcJycJzcJAcJBcJCcJDcJEcJFcHdcsLcuccJGcBOcBPaaaaaaaaaaaaaaaaabcBRcBRcBRcBRcBRcBRcBRcBRcBRcJHcJIcJJcxNcJKcJKcJLcBRaabcAPcAPcJMcAPcJNcJOcJPcAPcJQcuQcERbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJRcJScEWcEWcEWcEWcEXcEYcEYcEYcEYcJTcEYcJUcJVcJVcJWcJXcJYcEYcJZcKacKbcKbcKccKbcKdcKbcKbcKecKfcKbcKbcKfcKfcKfcKbcKbcKbcKbcKgcKhcKicKjcKkcKlcANcKncKocKncKncKncKncKpcKqcKrcKscKtcGKcsLcKucKvcKwcKxcKycKzcKAcKBcDfcKCcKDcKEcKFcKGcKHcFyaaaaaaaaacImcKIcKJcKKcIqcKLcKMcJDcKNcHdcKOchfchfcBOcBPaaaaaaaaaaaaaaaaaacBRcKPcKQcKRcKScKTcKUcKVcxNcKWcKXcKYcxNcJKcKZcLacBRaabaabcLbcLccLdcLecLfcLgcLbbGGbGGcERcLhbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalwalvalvalwalvalvaabamhaabayiaaaayiayicLicLjcLkcLkcLkcLlcLmcEYcLncLocLpcLqcLrcLscEYcLtcLucKfcLvcLwcLxcLycLzcLAcLBcLCcLDcKbcLCcLEcLFcLGcLGcLHcKbcLIcLJcHCcLKcnycLLcLMcLNcLOcLPcLQcLPcLRcLScLTcLUcLVcLWcGKcGKcKucKvcCWcCWcLXcCWcCWcKvcLYcLZcLZcLZcMacLZcMbcFyaaaaaaaaacImcImcImcImcImcFFcMccMdcMecHdcsLcsLcMfcBOcBPaaaaaaaaaaaaaaaaaacBRcJKcMgcJKcMhcMicEHcJIcxNcxQcAOcxQcxNcJKcJKcMkcBRaabaaacLbcMlcMmcLecLecMncLbcMobGGcERbKlcMpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaaaaabaabaaaaabaabaaaaaaaabaabaabaabaabcLicLicMqcLicLicMrcMscEYcEYcEYcEYcEYcEYcEYcEYcLicLucKfcMtcMucMvcMwcMwcMwcMwcMxcMycMzcLGcMAcLGcLGcMBcLGcMCcMDcMEcMFcLKcnycMGcHQcMHcLOcMIcMJcMKcLOcMLcBrcMNcMOcMPcMQcMRcMScMTcMUcMUcMVcMWcMXcMYcMZcNacrecrecNbcsLcNccBPcBPcBPcBPcBPaaaaaaaaaaaacNdcNecNfcNgcHdcNhchfchfcBOcBPcBPcBPcBPcBPaaaaaacBRcJKcJKcJKcNicNjcNkcNlcNmcNncNocNpcxNcNqcNrcNscBRaaaaaacLbcNtcLecNucLecNvcLbbGGbGGcERcMpbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNwaaaalwaaacNxcNycNzaaacNxcNycNzaaacNxcNycNzaaaaaacLicNAcNBcNCcLicNDcNEcLkcLkcLkcLkcLkcLkcLkcLkcLkcNFcKfcNGcLGcMBcNHcLGcLGcLGcNIcLGcNGcNGcLGcLGcLGcLGcNJcNKcMDcNLcHDcNMcywcHQcHQcNNcLOcNOcNPcNQcLOcNRcHVcNScNTcNUcNVcNWcNXcsLcNYcpscNYcsLcNZcOacObcObcObcObcOccOdcOdcOdcOdcOdcOecBPaaaaaaaaaaaacNdcNecNfcOfcOgcsLcxMchfcBOcsLcsLcsLcsKcBPaaaaaacBRcxNcxNcxNcxNcOhcEHcOicOjcOkcOlcOmcxNcOncOocOpcBRaaaaaacLbcOqcOrcOscLecOtcLbcOubGGcERbGHaabaabaabaabaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaacNxcOvcNzaaacNxcOvcNzaaacNxcOvcNzaaaayicLicNBcNBcNBcLicLicOwcOxcLicLicOxcOxcLicLicOxcOxcLucKfcNGcOycLGcOzcOAcOBcOBcMAcLGcNGcOCcLGcLGcLGcLGcODcOEcOFcOGclXcOHcOIcOJcOKcOLcLOcNOcOMcONcLOcOOcHVcGKcOPcGHcOQcORcOScOTcOUcOVcOWcOTcOXcOTcOTcOTcBPcBPcBPcBPcBPcBPcBPcBPcOYcBPaaaaaaaaaaaacNdcOZcPacPbcHdcsKcPcchfcPdcPecPecPfcsLcBPaaaaaacBRcKPcKQcKRcPgcPhcNkcPicPjcPkcPlcPmcPncPocPmcPpcBRaaaaaacLbcLbcPqcPrcPscLbcLbbGHbGGcPtcuQcuQcuQbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaacNxcOvcNzaaacNxcOvcNzaaacNxcOvcNzaaaayicLicNBcNBcNBcLicLicOwcOxcLicLicOxcOxcLicLicOxcOxcLucKfcNGcOycLGcOzcOAcOBcOBcMAcLGcNGcOCcLGcLGcLGcLGcODcOEcOFcOGclXcOHcOIcOJcOKcOLcLOcNOcOMcONcLOcOOcHVcGKcOPcGHcCxcORcOScOTcOUcOVcOWcOTcOXcOTcOTcOTcBPcBPcBPcBPcBPcBPcBPcBPcOYcBPaaaaaaaaaaaacNdcOZcPacPbcHdcsKcPcchfcPdcPecPecPfcsLcBPaaaaaacBRcKPcKQcKRcPgcPhcNkcPicPjcPkcPlcPmcPncPocPmcPpcBRaaaaaacLbcLbcPqcPrcPscLbcLbbGHbGGcPtcuQcuQcuQbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaayiaabcNxcOvcNzaaacNxcOvcNzaabcNxcOvcNzaaaaabcLicMrcPucNDcLiaaaaabaaaaaaaaaaaaaaaaabaaaaaacOxcLucKbcPvcLGcPwcPxcPycPzcPAcPzcPBcPzcPCcPDcLCcPEcNGcNGcNKcPFcPGcPHcPIcPJcPKcPLcPMcPNcPOcPPcPQcPRcPScPTcPUcPUcPVcPWcPXcPYcPZcQacQbcQccQdcQecQfcQgcQhcQicQicQicQicQicQicQjcBPcOYcQkcQkcQkcQkcQkcQkcQlcQmcQlcQncQkcQkcQkcQkcQkcQkcBOcsLcBPaaaaaacBRcJKcKZcJKcQocMicEHcQpcQqcQrcQscEHcEHcQtcEHcQucBRaaaaabaabcLbcLbcQvcLbcLbaaabGHbGGcERcuQcQwcQxbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacNxcOvcNzaabcNxcOvcNzaaacNxcOvcNzaabaaacLicLicOxcLicLiaaaaabaabaaaaabaaaaabaabaaaaaacQycQzcKbcQAcQBcQBcQCcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcJZcQDcJZcQEcJZcFacQFcQGcQHcQIcQIcQIcQJcQKcPTcQLcQMcQNcQOcQPcQQcPZcQRcQScQTcQUcQVcQWcQXcQYaabcQZcQZcQZcQZcQZcRacBPcRbcRccRdcRecRfcRgcQkcRhcRicRjcQkcRkcRlcRmcRncRocQkcBOcsLcBPaaaaaacBRcJKcJKcJKcRpcRqcNkcRrcRscRtcRucRvcRvcRwcEHcRxcBRaabaabaaaaaaaaacRyaaaaaaaaabGHbGGcERcuQbGGbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacNxcOvcNzaabcNxcOvcNzaaacNxcOvcNzaabaaacLicLicOxcLicLiaaaaabaabaaaaabaaaaabaabaaaaaacQycQzcKbcQAcQBcQBcQCcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcKbcJZcQDcJZcQEcJZcFacQFcEfcQHcQIcQIcQIcEKcQKcPTcQLcQMcQNcQOcQPcQQcPZcQRcQScQTcQUcQVcQWcQXcQYaabcQZcQZcQZcQZcQZcRacBPcRbcRccRdcRecRfcRgcQkcRhcRicRjcQkcRkcRlcRmcRncRocQkcBOcsLcBPaaaaaacBRcJKcJKcJKcRpcRqcNkcRrcRscRtcRucRvcRvcRwcEHcRxcBRaabaabaaaaaaaaacRyaaaaaaaaabGHbGGcERcuQbGGbGGbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvayiaaacNxcOvcNzaabcNxcOvcNzaaacNxcOvcNzaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcRzcRAcRAcRAcRAcQycRBcLucRCcRDcREcREcRFcRGcRHcRIcRIcRIcRIcRJcRKcRLcRMcRMcRNcRNcRMcROcRPcRQcRRcRRcRScRTcRUcRVcRWcRXcRXcRYcRZcSacSbcSccSdcQPcSecPZcSfcSgcShcSicSjcSkcSlcSmcQicSncSocSpcSqcQZcRacBQcOYcQkcSrcSscStcSucSvcSwcSxcSycQkcSzcSAcSBcSAcSCcQkcBOcsLcBPcBPaaacBRcxNcxNcxNcxNcSDcEHcQpcSEcSFcQscEHcSGcSHcSHcSIcSJcSKaabaaaaaaaaaaaaaaaaaaaaabGHbGGcPtbGGbGGcSLbGHaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaabcSMaabaabaabcSMaabaaaaabcSMaabaaaaaaaaaaaaaaaaaaaaaaaaaaacRzcRzcRzcSNcSOcSPcRAcSQcSRcNFcRCcRCcSScSTcKbcKbcMscSUcSUcSUcSUcSVcSWcSXcSWcSWcSWcRRcRRcSYcSZcTacTbcTccRXcTdcTecRXcRXcRXcRXcTfcPTcTgcThcQNcSdcQPcSdcPZcSfcSgcTicTjcTkcTlcTmcTnaabcTocTpcSqcTqcQZcRacBQcRbcRccTrcTscSAcTtcQkcTucTvcTwcQkcTxcTycSAcTzcTAcQkcBOcsLcTBcBPaaacBRcKPcKQcKRcTCcPhcNkcTDcTEcTFcTGcTGcTHcTIcTJcTKcBRaabaabaabaaaaaaaaaaaaaaaaaabGHcTLcERbGHbGHbGHbGHbGHaabaabaabcTMcTMcTMcTMcTMcTMaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcTNcTOcTOcTPcTQcTRcTRcTRcTQcTRcTRcTRcTQcTRcTRcTRcTScTOcTOcTOcTOcTOcTTcTUcTVcTWcTXcTYcTZcUacUbcNBcLucUccRCcKbcKbcKbcUdcMscSUcUecUfcUgcUhcUicUjcUkcUlcUmcUncUocUpcUqcUrcUscUncUtcUucTecUvcRXcRXcRXcUwcPTcUxcUxcSdcUycUzcUAcUBcUCcUDcUEcUFcUGcUHcUIcSmcUJcSncUKcSqcSqcQZcRacBQcOYcQkcULcUMcUNcQncQkcUOcUPcQncQkcUQcURcUScUTcUTcQkcBOcsLcUUcBPaaacBRcJKcMgcJKcUVcMicEHcUWcUXcUYcEHcUZcVacxNcxNcxNcBRaaaaaaaabaabaaaaaaaaaaaaaaabGHcJQcERbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaabcSMaabaabaabcSMaabaaaaabcSMaabaaaaaaaaaaaaaaaaaaaaaaaaaaacRzcRzcRzcSNcSOcSPcRAcSQcSRcNFcRCcRCcSScSTcKbcKbcMscSUcSUcSUcSUcSVcSWcSXcSWcSWcSWcRRcRRcSYcSZcTacTbcGBcRXcTdcTecRXcRXcRXcRXcTfcPTcTgcThcQNcSdcQPcSdcPZcSfcSgcTicTjcTkcTlcTmcTnaabcTocTpcSqcTqcQZcRacBQcRbcRccTrcTscSAcTtcQkcTucTvcTwcQkcTxcTycSAcTzcTAcQkcBOcsLcTBcBPaaacBRcKPcKQcKRcTCcPhcNkcTDcTEcTFcTGcTGcTHcTIcTJcTKcBRaabaabaabaaaaaaaaaaaaaaaaaabGHcTLcERbGHbGHbGHbGHbGHaabaabaabcTMcTMcTMcTMcTMcTMaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcTNcTOcTOcTPcTQcTRcTRcTRcTQcTRcTRcTRcTQcTRcTRcTRcTScTOcTOcTOcTOcTOcTTcTUcTVcTWcTXcTYcTZcUacUbcNBcLucUccRCcKbcKbcKbcUdcMscSUcUecUfcUgcUhcUicUjcUkcUlcUmcUncUocUpcUqcUrcUscUncUtcUucTecUvcRXcRXcRXcUwcPTcUxcUxcSdcUycUzcUAcHfcUCcUDcUEcUFcUGcUHcUIcSmcUJcSncUKcSqcSqcQZcRacBQcOYcQkcULcUMcUNcQncQkcUOcUPcQncQkcUQcURcUScUTcUTcQkcBOcsLcUUcBPaaacBRcJKcMgcJKcUVcMicEHcUWcUXcUYcEHcUZcVacxNcxNcxNcBRaaaaaaaabaabaaaaaaaaaaaaaaabGHcJQcERbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaabcVbaabaaaaabcVbaabaaaaabcVbaabaaaaaaaaaaaaaaaaaaaaaaaaaaacRzcRzcRzcVccVdcVecRAcVfcNBcNEcSRcSRcSRcSRcVgcSRcUbcSUcVhcVicVjcVkcVlcVmcVncVocVpcVqcVrcVscVtcVucVvcVwcUtcTdcTecVxcVycRXcRXcVzcPTcVAcVBcSdcVCcQPcVDcVEcVFcVGcVHcVIcVJcVKcVJcVLaabcQZcQZcQZcQZcQZcRacBPcOYcQkcVMcVNcVOcVPcVQcVRcVScVTcVUcVVcVWcSAcVXcVYcQkcBOcsLcVZcBPaaacBRcJKcJKcJKcWacWbcWccWdcWecWfcEHcEHcEHcEHcWgcWhcWiaaaaaaaaaaabaabaaaaaaaaaaaabGHbGHcERbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwaabcNxcWjcNzaaacNxcWjcNzaaacNxcWjcNzaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabcRzcRAcRAcRAcRAcWkcWlcWmcNBcWncNBcNBcMscWocNBcSUcWpcWqcVjcWrcUicWscWtcWucWucWvcWwcWxcWycWzcWAcWvcWBcWCcWDcWEcWFcWGcWHcWIcWJcWKcUAcWLcWMcWNcWOcWPcWQcWRcWScWTcWUcWVcWWcWXcQicSncWYcWZcWZcQZcRacBPcOYcQkcQkcQkcQkcQkcXacXbcXccXdcXecXfcXgcXhcXicXjcQkcBOcXkcXlcXlcXlcXmcXmcXmcXmcXmcXncXocXpcXqcXrcNkcXscNkcXscNkcXtcWiaaaaaaaaaaaaaabaabaaaaaaaaaaaabGHcERbGHaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNxcWjcNzaabcNxcWjcNzaaacNxcWjcNzaaaaaaaaaaaaaabaaaaaaaaaaaaaabaabaabaaaaaaaabaabcXucXucXucXucXucXucXucXvcXucXucSUcXwcXxcVjcWrcUicXycUicUicXzcRRcXAcXBcUrcXCcXDcRRcXEcRXcTecXFcXGcXHcWHcXIcXJcXKcXLcXMcXNcXOcXLcXPcXQcXRcXScSdcXTcXUcXVcXWaabcTocXXcXYcXZcQZcRacBQcYacYbcYbcYbcYccQkcYdcUMcYecYfcURcYgcUTcUTcURcYhcQkcBOcYichfcsLcYjcYkcBPaaaaaacBRcYlcYmcYncYocYlcYmcYpcYqcYlcYmcYrcBRaabaabaabaabaabaabaabaabaabaabbGHcERbGHbGHbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacYsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNxcWjcNzaaacNxcWjcNzaaacNxcWjcNzaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabcXucYtcYtcYucYvcYwcYwcYxcYycYycYzcYAcYBcVjcWrcVjcYCcVjcVjcVjcRRcYDcYEcYFcYGcYHcYIcYJcYKcYLcYMcYMcYMcYNcYOcYPcYQcYRcYScVCcQPcYTcYUcYVcYWcYXcSdcXTcYYcYZcZacZbcSncZccWZcWZcQZcRacBQcOYchfchfchfckJcQkcZdcZecZfcZgcURcZhcZicUTcZjcZkcQkcBOcYichfcsLcJGcsLcBPaaaaaacBRcZlcZmcZncxNcZocZpcZqcxNcZrcZscZtcBRaabaabaaaaaaaaaaaaaaaaaaaaaaaabGHcERbGGbGGbGHaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNxcWjcNzaaacNxcWjcNzaaacNxcWjcNzaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabcXucYtcYtcYucYvcYwcYwcYxcYycYycYzcYAcYBcVjcWrcVjcYCcVjcVjcVjcRRcYDcYEcYFcYGcYHcYIcYJcHAcYLcYMcYMcYMcYNcYOcYPcYQcYRcYScVCcQPcYTcYUcYVcYWcYXcSdcXTcYYcYZcZacZbcSncZccWZcWZcQZcRacBQcOYchfchfchfckJcQkcZdcZecZfcZgcURcZhcZicUTcZjcZkcQkcBOcYichfcsLcJGcsLcBPaaaaaacBRcZlcZmcZncxNcZocZpcZqcxNcZrcZscZtcBRaabaabaaaaaaaaaaaaaaaaaaaaaaaabGHcERbGGbGGbGHaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNxcWjcNzaaacNxcWjcNzaabcNxcWjcNzaabaabaabaabaaaaabaaaaaaaabaabaaaaaaaaaaabaaaaaacXucYtcYtcYucZucZucZucZvcZwcZxcSUcZycZzcZAcZBcZCcZDcZEcZFcZFcZGcZHcZIcVjcVjcVjcZJcZKcZLcZMcZNcZOcZPcZQcZRcSUcZScZScZTcVCcQPcZUcZVcZWcZXcZYcSdcZZdaadabdacdadcQZcQZcQZcQZcQZcRacBQcOYdaecsLcsLckJcQkdafcSAcSAdagdahdaidajcUTdakdalcQkcBOcYicMfcsLcuccTBcBPaaaaaacBRcMkcJKcJKcxNcMkcJKcJKcxNcMkcJKcJKcBRaaaaabaabaaaaaaaaaaaaaaacuQcuQbGHdamcuQbGGbGHbGHbGHcTMcTMaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamhaabcNxdancNzaaacNxdancNzaaacNxdancNzaabalvaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaabcXudaodapcZucZucZudaqdardardardardardardardasdatdaudavdawdawdawdaxdaydazdaAdaBdawdaydaCdaDdaEcZOdaFcZQcZRdaGdaHdaIdaJdaKdaLdaMdaNcYXdaOdaPdaQdaRdaSdaTcWXdaUcSndaVdaWdaWcQZcRacBPcOYchfcBNdaXckJcQkdaYcSAdaZdbacURdbbdbccUTdbddbecQkcBOcYichfcsLchfchfcBPaabaabcBRdbfcKZcJKcxNdbfcKZcJKcxNdbfcKZcJKcBRaaaaaaaabaabaaaaaaaaaaaacuQdbgbGGcERcuQdbhcuQdbibGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaaaaabaaaaaaaaaaabaabaabaaaaaaaabaabaaaalvaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabcXudbjcZucZucZucZucZudardbkdbldbmdbndbodardbpdbqdbrcXxcVjcVjdbsdbtdbudbvdbwdbxdbydbzcSUdbAdaEcZOdbBcZQdbCcSUdbDcZSdbEdbFcSddaMdaNdbGcSddaPdaQcXTcXUdbHcXWdbIcTodbJdbKdbLcQZcRacBPcOYchfdbMdbMckJcQkcQkdbNdbOcQkdbPcQkcQkcQkcQkcQkcQkcBOcYichfcsLcsLdbQcBPaaaaaacBRdbRcJKcJKcxNdbRcJKcJKcxNdbRcJKcJKcBRaaaaaaaaaaabaabaaaaaadbScuQbGGbGGcERcuQbGGbGGbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamhaabcNxdancNzaaacNxdancNzaaacNxdancNzaabalvaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaabcXudaodapcZucZucZudaqdardardardardardardardasdatdaudavdawdawdawdaxdaydazdaAdaBdawdaydaCcHBdaEcZOdaFcZQcZRdaGdaHdaIdaJdaKdaLdaMdaNcYXdaOdaPdaQdaRdaSdaTcWXdaUcSndaVdaWdaWcQZcRacBPcOYchfcBNdaXckJcQkdaYcSAdaZdbacURdbbdbccUTdbddbecQkcBOcYichfcsLchfchfcBPaabaabcBRdbfcKZcJKcxNdbfcKZcJKcxNdbfcKZcJKcBRaaaaaaaabaabaaaaaaaaaaaacuQdbgbGGcERcuQdbhcuQdbibGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaaaaabaaaaaaaaaaabaabaabaaaaaaaabaabaaaalvaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabcXudbjcZucZucZucZucZudardbkdbldbmdbndbodardbpdbqdbrcXxcVjcVjdbsdbtdbudbvdbwdbxdbydbzcSUdbAdaEcZOdbBcZQdbCcSUdbDcZSdbEbmCcSddaMdaNdbGcSddaPdaQcXTcXUdbHcXWdbIcTodbJdbKdbLcQZcRacBPcOYchfdbMdbMckJcQkcQkdbNdbOcQkdbPcQkcQkcQkcQkcQkcQkcBOcYichfcsLcsLdbQcBPaaaaaacBRdbRcJKcJKcxNdbRcJKcJKcxNdbRcJKcJKcBRaaaaaaaaaaabaabaaaaaadbScuQbGGbGGcERcuQbGGbGGbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwalwamhalvalvalvalvalwalvalvalwdbTaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacXudbUcZwcZucZucZudbVdardbldbWdbXdbYdbZdcadcbdccdcddcecVjdcfdcgdchdcidcjdckdcldcmdcndcodbrcXxdcpdcqcZMdcrcSUdcscZSdctdcucSddaMdaNcYXcSddcvdaQcXTdcwdcxcZadcycSndczdaWdaWcQZcRacBQcOYdcAcuccABckJdcBcQkcQkdcCcQkdcDdcEdcFchfdcGdcHcsLcBOcYichfcsLdcIcTBcBPaaaaaacBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRaaaaaaaaaaaaaabaabaaaaaabGHbGHbGHcERcuQdcJdcKbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcXucXucXudcLdcMdcMdcMdardcNdcOdcPdcPdcQdcRdawdcSdcTdcUdcVdcWdcXdcYdcZddaddbddcddddcYddeddfddgddhddiddjddkddldbDcZSddmddncSddaMcSdddocSddaPdaQcXTcXUddpcXWdbIcQZcQZcQZcQZcQZcRacBQddqcYccuccTBddrddsddsddsddtchfdduddvddwchfddxcYbcYbddyddzcMfcsLcsLcBPcBPaaaaaaddAaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaabaaabGHcJQddBddCcuQddDddEbGGbZZaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaddFcXucZucZucZudcMaabaabdarddGddHdcPdcPddIdarddJddKddLddMddNddOddPcSUddQddRddScVjddTcSUddUddVddWddMddMddXddYcSUddZcZSdeadebcSddaMcSdcZUcZVdecdeddaRdeedefcWXdegcSndehdeideicQZcRacBQdejdekchfchfcOYchfchfcsLdelchfchfdemchfchfdendeodepdeqdercBPcBPcBPcBPaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaabaabbGHdbgcASbZYcuQcuQcuQbGGbGHaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcXucZucZucZudcMaabaaadardesddHdcPdcPdetdardeudevcSUdewdexdexdeycSUdezdeAdeBdeCdeDcSUdexdexdexdewcSUdeEdeucSUdbDcZSdeFdeGdeHdeIdeJdeKdeLdeMcWUdeNcXUdeOcXWdbIcTodePdeQdeRcQZcRacBPcBPcOYcprdeScOYdeTchfcsLdeUdeVdeWdeXddsddsdeYcYichfdeZcBPcBPaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabGHbGHbGHbGHbGHdfabZYcuQdfbdfcbGGbGHaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacXucXudcMdcLdfdaaaaaadardfedffdcPdcPdfgdardfhdfidfjdfkdfldfmdfndfodfpdfqdfrdfsddkdfodfldfldfldftdfjdfudfvcSUdbDdfwdaMdfxdfydeLdfzdfAdfBdfCdfDdfEdfFdfGcZadcycSndfHdeideicQZcRacBPcsLdfIdfJdfKdeYcsKchfcsLcsLcsLcYidfLcsLcXkdfMddzcuQcERbGHaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabGHbGGbGGbGGcJQdfNdfOcuQdfPbGGbGGbGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadfRdfSdfSdfTdfSdfSdfUdardfVdcOdcPdcPdfWdardaGdfXcSUcSUdfodfodfodfodfYdfZdgaddMdgbdfodfodfodfocSUcSUdgcdgdcSUdbDcZSdgedgfdfydggdghcSdcSddgicXPdggcXUdgjcXWdbIcQZcQZcQZcQZcQZcRacBPcTBcsLdgkdglcsLdgmchfchfdgnchfdgocpscJGdgpchfchfcuQcERbGHaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaabGHbGHcuQdgqdgrcJQdfNbZYbGGbGGbGGdgsbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdgwdgvdgxdgydardgzdgAdcPdcPdgBdarcSUdgCcSUdgDaacdgEdfodfodfodfodgFdfodfodfodfodgEaacdgDcSUdgGcSUcSUdbDcZSdgHdeHdgIdgJdgKdgLdgMdgJdgMdgJdgNdeLdgOdbIdgPdgQdgQdgQdgQdgRdgSdgTdgTdgUdgVdgTdgTdgTdgWdgXdgYdgodgZchfdgochfdhacuQcERbGHbZZbZZbZZbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHbGHbGHbGHbGHbGHbGHbGHbGHbGHcMpbGHcJQcuQdhbbGGcQwdfNbZYcuQcuQdbhcuQbGHaabdhcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdgwdgwdhddhedardhfdhgdcPdcPdhhdardhidhjdhkaacdhldhmdhmdhmdhmdhmdhndhmdhmdhmdhmdhmdhoaacdhpdhqdhrcSUdhsdaIdhtdhudhvdhwdhxdhydhzdhAcSddhBdhCdhDdhEdbIdhFaaaaabaabaaadhGdhHdhIdhJdhKdhLdhMdhNdgTdhOcsLcsLdhPcpsdhQcYicsLcsLcEGaYNdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhTdhSdhSdhSdhSczDcuQbPAcAUbGGdhUcMpcuQcuQcuQdbhcuQdfNbZYcuQdhVbGGbGGbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdhWdgvdhXdhYdardfVdcOdcPdcPdhZdardiadibdibaaadicaacaacaacaacaacaacaacaacaacaacaacdicaaadibdibdiacSUdaGcZSdhEdiddiedifdigdihdhEdifdhEcXWdhEcXWdhEdbIdhFaaaalwalwdiidhHdijdikdildimdindiodipdgTcsLcsLchfdgodiqchfcYicXkdfMdhRcFGditditditditditditdiudivditditditditditditdiwdixdiydizdiAdiBdiCdiCdiCdiCdiDdiEdiFdiCdiCdiCdiCdiGcjUcuQdfcbGGdiHbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadiIdfSdfSdfSdfSdfSdiJdardiKdiLdcPdcPdiMdardiNdiOdiPaabdicaacdiQaaaaaaaaaaaadiQaaaaaadiQaacdicaaadiRdiSdiTcSUdaGcSUaabdiUaabdiVdiWdiXdiYdiZdiYdjadiYdjadjbdjcdhFaaaalwaabdjddgSdjedjfdjgdjhdjidjjdjkdgTdjlcsLcsLcYidjmchfcYicYidjnbGHbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHdjobGGcuQcTLbGGcuQcuQbZZbZZcxScuQdjpbGGdjpcuQdjqbZYdjrbGHbGHbGHbGHbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdgwdgvdgxdgydardgzdgAcITdcPdgBdarcSUdgCcSUdgDafOdgEdfodfodfodfodgFdfodfodfodfodgEafOdgDcSUdgGcSUcSUdbDcZSdgHdeHdgIdgJdgKdgLdgMdgJdgMdgJdgNdeLdgOdbIdgPdgQdgQdgQdgQdgRdgSdgTdgTdgUdgVdgTdgTdgTdgWdgXdgYdgodgZchfdgochfdhacuQcERbGHbZZbZZbZZbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHbGHbGHbGHbGHbGHbGHbGHbGHbGHcMpbGHcJQcuQdhbbGGcQwdfNbZYcuQcuQdbhcuQbGHaabdhcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdgwdgwdhddhedardhfdhgdcPdcPdhhdardhidhjdhkafOdhldhmdhmdhmdhmdhmdhndhmdhmdhmdhmdhmdhoafOdhpdhqdhrcSUdhsdaIdhtdhudhvdhwdhxdhydhzdhAcSddhBdhCdhDdhEdbIdhFaaaaabaabaaadhGdhHdhIdhJdhKdhLdhMdhNdgTdhOcsLcsLdhPcpsdhQcYicsLcsLcEGaYNdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhSdhTdhSdhSdhSdhSczDcuQbPAcAUbGGdhUcMpcuQcuQcuQdbhcuQdfNbZYcuQdhVbGGbGGbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadgtdgudgvdhWdgvdhXdhYdardfVdcOdcPdcPdhZdardiadibdibaaadicafOafOafOafOafOafOafOafOafOafOafOdicaaadibdibdiacSUdaGcZSdhEdiddiedifdigdihdhEdifdhEcXWdhEcXWdhEdbIdhFaaaalwalwdiidhHdijdikdildimdindiodipdgTcsLcsLchfdgodiqchfcYicXkdfMdhRcFGditditditditditditdiudivditditditditditditdiwdixdiydizdiAdiBdiCdiCdiCdiCdiDdiEdiFdiCdiCdiCdiCdiGcjUcuQdfcbGGdiHbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadiIdfSdfSdfSdfSdfSdiJdardiKdiLdcPdcPdiMdardiNdiOdiPaabdicafOdiQaaaaaaaaaaaadiQaaaaaadiQafOdicaaadiRdiSdiTcSUdaGcSUaabdiUaabdiVdiWdiXdiYdiZdiYdjadiYdjadjbdjcdhFaaaalwaabdjddgSdjedjfdjgdjhdjidjjdjkdgTdjlcsLcsLcYidjmchfcYicYidjnbGHbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHbZZbZZbZZbZZbGHdjobGGcuQcTLbGGcuQcuQbZZbZZcxScuQdjpbGGdjpcuQdjqbZYdjrbGHbGHbGHbGHbGHaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadardjsdiLdcPdcPdjtdardjudibdjvaaadjwdjxaaaaaaaaaaaaaaadjyaaaaaaaaadjzdjAaaadibdibdjucSUdaGcSUcQZdjBcTodjBcQZdjBcTodjBcQZdjCcTodjDcQZaabdhFaaaalwaabdjEdgSdjFdjfdjGdjHdjidjIdjJdjKdirdjLdjMcYicpscsLdjNdgochfcBPaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabGHdjOcLhcuQdjPbGGcuQaaaaaaaaaaaacuQbGGbGGdbgdjQdjQdjRdjSdjQaaaaabaabaabaabdjTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadardjUdcOdcPdcPdhZdardjVdjWdibaaadicaacaaaaaaaabaabaabaabaabaaaaaaaacdicaaadibdjXdjYcSUdjZcSUcQZdkadkbdkccQZdkddkedkfcQZdkgdkhdkicQZaabdhFaaaalwaaadjEdkjdkkdkldkmdkndkodkpdkqdgTdkrdgochfdgodkschfdktdgocBNcBPcBQcBQcBQaHQaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabGHdkucuQcuQcQxbGGcuQcuQbZZbZZcuQcuQbGGdkvcLhdjQdkwdkxdkydjQaaaaaaaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdardardardardardardarcSUdiadibaaadicaacdiQaabaabdkzdkAdkBaabdkCaaaaacdicaaadibdiacSUcSUdaGcSUcQZdkDdkEdkDcQZdkFdkGdkFcQZdkHdkIdkHcQZaabdhFaaaalwaaadjddgSdkJdkKdkLdkldkMdkNdkOdgTdkPdkQdkRdkSdkTcsLcYicYidkUdkVdkWcsLdkXaHQaaaaabaaabZZbZZbZZbGHbGHbGHbGHbGHbGHdkYcJQcuQdkZbGGbGGcuQbGGbGGbGGbGGdhbbGGdfPdjQdladlbdlcdjQaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaacaacaabaabaabalwalwcSUcSUdlddibaaadjwdjxaaaaaaaabdledlfdlgaabaaaaaadjzdjAaaadibdlhcSUcSUdaGcSUcQZdkDdlidkDcQZdkFdljdkFcQZdkHdlkdkHcQZaabdhFaaaalwaaadjddgSdgSdgSdlldlmdlndlodlndlmdkPdlpcsLdlqdlrdfMddzcYidlscBPcBQcBQcBQdltaabaabaaabZZdludlvcuQbGGdlwdlxdbgcuQdlybGGcuQdlzbGGbGGdlAbGGbGHbGHbGHbZZbZZbGHdjQdlBdlCdlDdjQaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabalwcSUcSUdiadibaaadicaacaaadlEaabdlFdlGdlHaabaabdiQaacdicaaadibdiacSUcSUdaGcSUcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZaabdhFaaaayiaaadjdaaaaaaaaadlIdlmdlJdlKdlLdlmcsLdlMcsLcsLdlNdlOcXkdlPdlQcBPaaaaaaaaaaaaaaaaabaaabZZdlRdlSdlAbGGdgrbGGbGGdlAdjobGGcuQcuQcuQcuQcuQbGGbGHaabaaaaaaaaaaabdlTdlTdlUdlTdlTaabaabdhcaabaabdjTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcSUdjXdjYdibaaadicaacaaaaaaaabaabaabaabaabaaaaaaaacdicaaadibdjVdjWcSUdlVcSUcSUcSUcSUdlWdgQdgQdgQdgQdgQdgQdgQdgQdgQdgQdlXaabaabaabdjEaaaaaaaaadlYdlmdlndlZdlndlmdmadmbdfMdfMdmcdmddmecBPcBPcBPaaaaaaaaaaaaaaaaabaaabZZdludmfcuQdbgbGGbGGdmgcuQdmhbGGbGGbGGbGGbGGbGGbGGbGHaabaaaaaaaaaaabaaadlTdmidlTaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadardjUdcOdcPdcPdhZdardjVdjWdibaaadicafOaaaaaaaabaabaabaabaabaaaaaaafOdicaaadibdjXdjYcSUdjZcSUcQZdkadkbdkccQZdkddkedkfcQZdkgdkhdkicQZaabdhFaaaalwaaadjEdkjdkkdkldkmdkndkodkpdkqdgTdkrdgochfdgodkschfdktdgocBNcBPcBQcBQcBQaHQaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabGHdkucuQcuQcQxbGGcuQcuQbZZbZZcuQcuQbGGdkvcLhdjQdkwdkxdkydjQaaaaaaaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafOdardardardardardardarcSUdiadibaaadicafOdiQaabaabdkzdkAdkBaabdkCaaaafOdicaaadibdiacSUcSUdaGcSUcQZdkDdkEdkDcQZdkFdkGdkFcQZdkHdkIdkHcQZaabdhFaaaalwaaadjddgSdkJdkKdkLcKmdkMdkNdkOdgTdkPdkQdkRdkSdkTcsLcYicYidkUdkVdkWcsLdkXaHQaaaaabaaabZZbZZbZZbGHbGHbGHbGHbGHbGHdkYcJQcuQdkZbGGbGGcuQbGGbGGbGGbGGdhbbGGdfPdjQdladlbdlcdjQaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabafOaabafOafOaabaabaabalwalwcSUcSUdlddibaaadjwdjxaaaaaaaabdledlfdlgaabaaaaaadjzdjAaaadibdlhcSUcSUdaGcSUcQZdkDdlidkDcQZdkFdljdkFcQZdkHdlkdkHcQZaabdhFaaaalwaaadjddgSdgSdgSdlldlmdlndlodlndlmdkPdlpcsLdlqdlrdfMddzcYidlscBPcBQcBQcBQdltaabaabaaabZZdludlvcuQbGGdlwdlxdbgcuQdlybGGcuQdlzbGGbGGdlAbGGbGHbGHbGHbZZbZZbGHdjQdlBdlCdlDdjQaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabalwcSUcSUdiadibaaadicafOaaadlEaabdlFdlGdlHaabaabdiQafOdicaaadibdiacSUcSUdaGcSUcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZcQZaabdhFaaaayiaaadjdaaaaaaaaadlIdlmdlJdlKdlLdlmcsLdlMcsLcsLdlNdlOcXkdlPdlQcBPaaaaaaaaaaaaaaaaabaaabZZdlRdlSdlAbGGdgrbGGbGGdlAdjobGGcuQcuQcuQcuQcuQbGGbGHaabaaaaaaaaaaabdlTdlTdlUdlTdlTaabaabdhcaabaabdjTaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcSUdjXdjYdibaaadicafOaaaaaaaabaabaabaabaabaaaaaaafOdicaaadibdjVdjWcSUdlVcSUcSUcSUcSUdlWdgQdgQdgQdgQdgQdgQdgQdgQdgQdgQdlXaabaabaabdjEaaaaaaaaadlYdlmdlndlZdlndlmdmadmbdfMdfMdmcdmddmecBPcBPcBPaaaaaaaaaaaaaaaaabaaabZZdludmfcuQdbgbGGbGGdmgcuQdmhbGGbGGbGGbGGbGGbGGbGGbGHaabaaaaaaaaaaabaaadlTdmidlTaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaabcSUdjudibdmjaaadjwdjxaaaaaaaaaaabaaaaaaaaaaaaaaadjzdjAaaadibdibdjucSUdmkdmldmmdaGdmndlXaabaabaabaabaabaabaabdmoaabaabaabaabaabaabdjEaabaabaabdlYdlmdmpdmqdmrdmsaabdmacBPcBQdmtcBQcBPcBPaaaaabaaaaaaaaaaaaaaaaabaabbZZbZZbZZbGHbGHbGHbGGcuQbGHdmubGHbGHdbgbPAcLhbKlcMpbGHaabaaaaaaaaaaabaaadlTdmvdlTaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcSUdmwdmxdiPaabdicaacdiQaaaaaadiQaaaaaaaaaaaadiQaacdicaaadiRdmydmzcSUdmAcSUcSUcSUcSUcSUcSUaaaaaaaabaaaaaaaaadmoaaaaaadmBdmBdmBdmBdmCaaaaaaaabdlYdmDdlmdmEdlmdlmaaaaabaaaaaadmFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaabGHdlSdmGbGHdmHaabbGHbGHbZZbZZcMpbGHaaaaabaaaaaaaaaaabaaaaaadmIaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdmJdmKdmLaaadicaacaacdmMaacaacdmMaacaacdmMaacaacdicaaadmNdmKdmOcSUdmPdmQdmRdmSdmTdmUdmVdmWdmWdmXdmWdmWdmWdmYdmWdmWdmZdnadnbdncdmCaaaaaaaabdndaHQdlmdnedlmdnfaabaabaaaaaadngaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaabpaaaaaabGHdnhdnibGHdnjaabaaaaabaaaaaaaabaaaaaaaabaaaaaaaaaaabaaaaaadnkaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcSUdmwdmxdiPaabdicafOdiQaaaaaadiQaaaaaaaaaaaadiQafOdicaaadiRdmydmzcSUdmAcSUcSUcSUcSUcSUcSUaaaaaaaabaaaaaaaaadmoaaaaaadmBdmBdmBdmBdmCaaaaaaaabdlYdmDdlmdmEdlmdlmaaaaabaaaaaadmFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaabGHdlSdmGbGHdmHaabbGHbGHbZZbZZcMpbGHaaaaabaaaaaaaaaaabaaaaaadmIaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdmJdmKdmLaaadicafOafOdmMafOafOdmMafOafOdmMafOafOdicaaadmNdmKdmOcSUdmPdmQdmRdmSdmTdmUdmVdmWdmWdmXdmWdmWdmWdmYdmWdmWdmZdnadnbdncdmCaaaaaaaabdndaHQdlmdnedlmdnfaabaabaaaaaadngaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaabpaaaaaabGHdnhdnibGHdnjaabaaaaabaaaaaaaabaaaaaaaabaaaaaaaaaaabaaaaaadnkaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadnlcSUcSUdnmaaadnndhmdhmdnodhmdhmdnodhmdhmdnodhmdhmdnpaaadnmcSUcSUcSUdmPdnqdnrdnsdntdnudfoaaaaaaaabaaaaaaaaadmodmBdmBdmBdnvdnwdnvdmCaaaaaaaabaabaHQdnxdnydnxaHQaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaaaaaaaabZZdnzbZZbZZaabdhcaaaaabaaaaaaaabaaaamWamWalwayiaabaabaabaabdnAaabaabaabaabdhcamhamWamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcSUcYNdnBdmLaabaabaabaabaaaaaaaaaaaaaaaaabaabaabaabdmNdnCcYNcSUcSUdnDcSUcSUcSUcSUdfocSUaabaabaabaabaabaabdmodnEdnFdnEdnFdnGdnFdmCaaaaaaaaaaabaHQaaaaaaaaaaHQaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaabZZdnHbZZaaaaaaaaaaaaaabaaaaaaaabaaaamWaaaaaaaabaaaaabaaaaaadnIaaaaaaaabaaaaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacSUcSUdnBdnJdnJdnJdnJdnJdnJdnJdnJdnJdnJdnJdnJdnJdnCcSUcSUcSUdnKdnLcSUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadnMdnNdnOdnPdnQdnRdnSdnTaaaaaaaaaaabaHQaHQaHQaHQaHQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaabZZdnUbZZaaaaaaaaaaaaaabaaaaaaaabaaaamWaaadnVdnVdnVdnVdnVaabdnWaabdnVdnVdnVdnVdnVaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUcSUaaacSUcSUdnXcSUcSUcSUcSUaaaaaaaaaaaaaaaaaaaaaaaadnYdnZdnZdnZdnZdoadobdocdoddoeaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaabZZdofbZZaaaaaaaaaaaaaaaaaaaaaaabaaaamWaabdogdohdohdohdohdoidojdokdoldoldoldoldomaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdaGdaGdondoodoodopaaaaaaaaaaaaaaaaaaaaaaaadjdaaadnZdnZdoqdordosdnZdnZdnZdnZdnZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdotdoudouaaaaaaaaaaaaaaaaaaaaaaabaaaamWaabdovdovdovdovdovaaadnWaaadovdovdovdovdovaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdjZdaGdowdoxdoydozaaaaaaaaaaaaaaaaaaaaaaaadjdaaadnZdoAdoBdoCdoDdoEdoFdoGdoHdnZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabaaaamWaaaaabaaaaabaabaabaaadnWaaaaabaaaaabaaaaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdjZdaGdowdoxdoydozaaaaaaaaaaaaaaaaaaaaaaaadjdaaadnZdoAdoBdoCdoDdoEcMjdoGdoHdnZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabaaaamWaaaaabaaaaabaabaabaaadnWaaaaabaaaaabaaaaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadoIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacSUdoJdaGdoKdoodoodoLaaaaaaaaaaaaaaaaaaaaaaaadjdaaadnZdoMdoNdoOdoPdoQdoRdoSdoTdnZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaamWaaadnVdnVdnVdnVdnVaabdnWaabdnVdnVdnVdnVdnVaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadnlcSUcSUcSUcSUcSUcSUaaaaaaaaaaaaaaaaaaaabaabdjEaabdnZdoUdoVdoWdoXdoYdoZdpadpbdnZaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabdogdohdohdohdohdoidojdokdoldoldoldoldpcaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdpddpedpddpfdpgdphdpidpjdpkdpfdpfdpfdpfaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabdovdovdovdovdovaaadnWaabdovdovdovdovdovaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 2a0ec563b73..b832fff59f3 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -2,13 +2,13 @@ "ab" = (/turf/unsimulated/floor/snow,/area/syndicate_mothership) "ac" = (/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow,/area/syndicate_mothership) "ad" = (/obj/structure/flora/bush,/turf/unsimulated/floor/snow,/area/syndicate_mothership) -"ae" = (/obj/structure/flora/tree/pine{pixel_x = 2},/turf/unsimulated/floor/snow,/area/syndicate_mothership) -"af" = (/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"ae" = (/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"af" = (/obj/machinery/door/airlock/external{id_tag = "syndicate_away"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ag" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"ah" = (/obj/structure/flora/tree/pine{pixel_x = 0},/turf/unsimulated/floor/snow,/area/syndicate_mothership) +"ah" = (/obj/docking_port/stationary{area_type = /area/syndicate_mothership; dir = 1; dwidth = 11; height = 13; id = "emergency_syndicate"; name = "404 Not Found"; turf_type = /turf/unsimulated/floor/snow; width = 24},/turf/unsimulated/floor/snow,/area/syndicate_mothership) "ai" = (/turf/unsimulated/floor/snow,/area/space) -"aj" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"ak" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"aj" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/syndicate_mothership) +"ak" = (/turf/unsimulated/wall/fakeglass{dir = 0; icon_state = "fakewindows"; tag = "icon-fakewindows (EAST)"},/area/syndicate_mothership) "al" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "am" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHEAST)"; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "an" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) @@ -42,18 +42,18 @@ "aP" = (/obj/structure/window/reinforced,/turf/unsimulated/wall{tag = "icon-iron12"; icon_state = "iron12"},/area/space) "aQ" = (/turf/unsimulated/wall{tag = "icon-iron14"; icon_state = "iron14"},/area/space) "aR" = (/turf/unsimulated/wall{tag = "icon-iron10"; icon_state = "iron10"},/area/space) -"aS" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (EAST)"; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) -"aT" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) -"aU" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"aS" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) +"aT" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) +"aU" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "aV" = (/obj/machinery/door/airlock/external{id_tag = "syndicate_away"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "aW" = (/obj/docking_port/stationary{area_type = /area/syndicate_mothership; dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_away"; name = "syndicate recon outpost"; turf_type = /turf/unsimulated/floor/snow; width = 18},/turf/space,/area/space) "aX" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTHEAST)"; icon_state = "gravsnow_corner"; dir = 5},/area/syndicate_mothership) "aY" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'FOURTH WALL'."; name = "\improper FOURTH WALL"; pixel_x = -32},/turf/unsimulated/floor/snow,/area/syndicate_mothership) -"aZ" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"aZ" = (/obj/machinery/light{dir = 1; on = 1},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ba" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) -"bb" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) -"bc" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"bd" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"bb" = (/obj/machinery/light{dir = 4},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"bc" = (/turf/unsimulated/floor/snow,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) +"bd" = (/obj/machinery/door/airlock/centcom{name = "Shuttle Dock #2"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "be" = (/obj/machinery/computer/shuttle/ert,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "bf" = (/obj/machinery/door/airlock/external{id_tag = "specops_away"; name = "Shuttle Hatch"; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) "bg" = (/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "specops_away"; name = "centcom bay 3"; width = 5},/turf/space,/area/space) @@ -436,7 +436,7 @@ "it" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_mothership) "iu" = (/obj/effect/decal/warning_stripes/southeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "iv" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/assault_pod) -"iw" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"iw" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (SOUTHWEST)"; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) "ix" = (/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/wizard_station) "iy" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/wizard_station) "iz" = (/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/wizard_station) @@ -447,7 +447,7 @@ "iE" = (/turf/space,/turf/unsimulated/wall{dir = 1; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/space) "iF" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/turf/simulated/floor/plating,/area/shuttle/assault_pod) "iG" = (/obj/effect/decal/warning_stripes/southwest,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) -"iH" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"iH" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine{pixel_x = 1},/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) "iI" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "iJ" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) "iK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) @@ -484,8 +484,8 @@ "jp" = (/turf/simulated/floor/plasteel,/area/tdome/arena_source) "jq" = (/turf/simulated/floor/plasteel{icon_state = "green"; dir = 4},/area/tdome/arena_source) "jr" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/energy/sword/saber/green,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) -"js" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod) -"jt" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"js" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (EAST)"; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) +"jt" = (/obj/item/weapon/storage/fancy/crayons,/obj/machinery/light{dir = 1; on = 1},/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "ju" = (/obj/effect/decal/warning_stripes/northeast,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "jv" = (/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "jw" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/obj/docking_port/mobile/assault_pod,/turf/simulated/floor/plating,/area/shuttle/assault_pod) @@ -622,7 +622,7 @@ "lX" = (/obj/structure/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/vest,/obj/item/clothing/head/helmet/swat,/obj/item/weapon/gun/energy/laser,/obj/item/weapon/shield/energy,/obj/machinery/recharger/wallcharger{pixel_x = 3; pixel_y = -30},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome/arena_source) "lY" = (/obj/effect/landmark/abductor/agent{team = 3},/turf/unsimulated/floor/abductor,/area/abductor_ship) "lZ" = (/obj/structure/closet/secure_closet/guncabinet,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/ammo_box/magazine/m10mm,/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/obj/item/weapon/gun/projectile/automatic/pistol{name = "pistol"},/turf/simulated/floor/engine,/area/shuttle/gamma/space) -"ma" = (/obj/effect/decal/cleanable/molten_item,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) +"ma" = (/obj/effect/decal/cleanable/molten_object,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) "mb" = (/turf/unsimulated/wall/fakeglass,/area/wizard_station) "mc" = (/obj/item/trash/chips,/obj/machinery/light/spot,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "md" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/cable,/turf/simulated/floor/plasteel,/area/shuttle/gamma/space) @@ -744,11 +744,20 @@ "op" = (/obj/machinery/light/spot,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/escape) "oq" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/escape) "or" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/escape) +"os" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon,/obj/item/weapon/reagent_containers/food/snacks/grown/berries,/obj/item/weapon/reagent_containers/food/snacks/grown/banana,/obj/item/weapon/reagent_containers/food/snacks/grown/cherries,/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange,/obj/item/weapon/reagent_containers/food/snacks/grown/corn,/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) +"ot" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"ou" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"ov" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) +"ow" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall3"; icon_state = "diagonalWall3"; dir = 2},/area/shuttle/assault_pod) +"ox" = (/turf/simulated/floor/pod,/turf/space,/obj/machinery/porta_turret/syndicate/pod,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) +"oy" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (NORTH)"; icon_state = "gravsnow_corner"; dir = 1},/area/syndicate_mothership) +"oz" = (/turf/unsimulated/floor/snow,/obj/structure/flora/grass/brown,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) +"oA" = (/turf/unsimulated/floor/snow,/obj/structure/flora/tree/pine,/turf/unsimulated/floor/snow{icon_state = "gravsnow_corner"},/area/syndicate_mothership) "oB" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) "oC" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/syndicate_mothership) +"oD" = (/turf/unsimulated/floor/snow,/obj/structure/flora/bush,/turf/unsimulated/floor/snow{tag = "icon-gravsnow_corner (WEST)"; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "oH" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "oI" = (/obj/machinery/washing_machine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"oJ" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/obj/machinery/light{dir = 1; on = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "oO" = (/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "oQ" = (/obj/machinery/vending/syndisnack,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "oR" = (/obj/machinery/vending/syndicigs,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) @@ -1220,7 +1229,6 @@ "ER" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/ammo_box/magazine/m75,/obj/item/weapon/gun/projectile/automatic/gyropistol,/obj/item/weapon/gun/projectile/automatic/gyropistol{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "ES" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/ammo_box/magazine/m50,/obj/item/weapon/gun/projectile/automatic/pistol/deagle,/obj/item/weapon/gun/projectile/automatic/pistol/deagle{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "ET" = (/obj/structure/rack,/obj/item/ammo_box/a357,/obj/item/ammo_box/a357,/obj/item/weapon/gun/projectile/revolver/mateba,/obj/item/weapon/gun/projectile/revolver/mateba{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"EU" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/grown/lemon,/obj/item/weapon/reagent_containers/food/snacks/grown/berries,/obj/item/weapon/reagent_containers/food/snacks/grown/banana,/obj/item/weapon/reagent_containers/food/snacks/grown/cherries,/obj/item/weapon/reagent_containers/food/snacks/grown/orange,/obj/item/weapon/reagent_containers/food/snacks/grown/corn,/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) "EV" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/storage/box/autoinjectors,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) "EW" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/obj/item/weapon/grenade/chem_grenade/large,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) "EX" = (/obj/structure/table,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/infra,/obj/item/device/assembly/infra,/obj/item/device/assembly/infra,/obj/item/device/assembly/infra,/obj/item/device/assembly/infra,/obj/item/device/assembly/prox_sensor,/obj/item/device/assembly/prox_sensor,/obj/item/device/assembly/prox_sensor,/obj/item/device/assembly/prox_sensor,/obj/item/device/assembly/prox_sensor,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) @@ -1468,61 +1476,61 @@ aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckck aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNisaNaNaNaNaNmtkjknknmuknkjkokpmvkrksaNaNaNaNaNaNmKmEmLmNmMmOmOmMmEmQmPatatbkatatatatatatatatatatatatatbkatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNititititititititititititititititititaNaNaNaNaNaNmKmEmEmEmEmEmEmEmEmQmRatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckbmckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmKmEmMmOmOmOmSmMmEmEmTatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckaackckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNmUmVmEmEmEmEmEmEmEmEatatblblatatatatatatatatatatatatatblblatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckaEckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababacababababababababababababababababababnjaNaNaNaNaNmrmrmrmWmrmXmOmOmMmEmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbnaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababacabababababababababababababababababababababababababnjaNaNaNaNaNmrmYnamZmrmEmEmEmEnbncataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababadababababababababababababaeababacabafababnjaNaNaNaNaNmrndndnemrnfngngngnhniataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckawckckckckckaxckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababababafabafababababafabababnjaNaNaNaNaNmrndnkmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababacababadababacafabadabababnjaNaNaNaNaNmrmrmrmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababagagagagagagagababababahababacabahabababacabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiacabababababajagagakagakababafabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlnmataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababacamnjnjoBoCnjnjanagagagnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababaonjnjoHoIoIoJnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalababadaonjaLoOoOoOoOfZoQoRnjfYjMmgnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiababababaSnjpaoOmfmfpcoOpdpepWpXpXganjnjnjnjnjnjnjnjnjnjnjnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNaTagagababaUamnjplmfpmjNmfoOmkppnjpXggnjnjghgjgigxgxhggxgxhxhGnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNpupvpvpvpvpvoCnjmhmfpwpxmfoOmkppnjnjnjnjnjgjgiiuiwiviFiviHiGhxnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaiaNaNaNaNaNaNaNaNaNpypzpApzpzpzpzpCoOJboOoOoOoOmkppnjnjnjnjnjgjiIiwiviJiSiKiviHiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNpFaVoBpvpvpvoCnjmimfmfmfmhoOmkppoBpvpvpvpvpvpviviJiSiUiSiKiviTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaWaNaiababaXnjpRpSpTpSjOoOpUpViWiViViXiViViWiFiSiYjjjiiSiFiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjaYabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaZabaonjqfqgqhqiqjoOoOoOoBpvpvpvpvpvpviviJiSjkiSiSiviTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaNaNaNalabaonjnjppqtqrqunjqwoOnjnjnjnjnjgjiIjsiviJiSiKivjtiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaNaNaNanabababnjnjnjnjnjnjqDqDqEqFqGqHnjgjjvjujsivjwivjtjxjynjaNaNaNatatatatatatatatatatatatatatatatatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaiabababbababbaXnjqLqMqMqMqMqMnjjzgjjvjJjJjKjJjJjyjznjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababacababaoqXqMqMqMqMqMmlnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababadbcakamnjrerererererfnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababaonjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbdabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbXbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNabaNaNaNaNaNabaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNabaiaNaNaNaiabaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaiaNaNaNaiabababababababaiaNaNaNaiababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErHrErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqasaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -rKrErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWcPbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNbZbZbZbZbZbZrPrQdebZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNbZcYlZrUrVrWrXrXrXbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNbZrXrXrXrXrXrXrYrZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNbZsasbsbsbscsdsesbbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckaackckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmUmVmEmEmEmEmEmEmEmEatatblblatatatatatatatatatatatatatblblatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckaEckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmrmrmrmWmrmXmOmOmMmEmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbnaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmrmYnamZmrmEmEmEmEnbncataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmrndndnemrnfngngngnhniataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckawckckckckckaxckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmrndnkmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNmrmrmrmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababacababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababacabababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNnlnmataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababacaeabababaeababababacabaeabababababababacababaeabababacabnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaeabacababaeabababaeabababababacababaeabababababababacaeabababnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatatatatatatatatatatatatatatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababahababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababaonjafnjafnjalabaonjafnjafnjalababababababacabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababaoajoOajoOajalabaoajoOajoOajalabacababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbXbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaeabamakoOakoOakanagamakoOakoOakaSagagababaeabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaeababacaeababaonjnjafnjafnjaTpvoCnjafnjafnjnjnjnjaUababacababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaeababababacaonjaZoOoOoOaZoOoOoOaZoOoOoOaZoOoOnjalabababaeabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababaeabababaonjoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOnjalacababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjaeababababaeabaeaonjaTpvpvpvpvpvpvpvpvpvpvpvoCnjbbnjalabaeabacabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaeacababagagagbcbcbcbcbababababababababaaXnjoOnjaUabacabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiacababaeababagagamnjoOnjalabababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjacaeabababaNaNaNaNaNaNaNaNaNaUabababacamnjnjqXnjbdnjiwagiHagiHagnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababaonjnjoHoIjtoOnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalaeabadaonjaLoOoOoOoOfZoQoRnjfYjMmgnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabosabababaiaNaNaNaNaNaNaNaiababababjsnjpaoOmfmfpcoOpdpepWpXpXganjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErHrErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNiwagagagagiHamnjplmfpmjNmfoOmkppnjpXggnjnjghgjgigxgxhggxgxhxhGnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababaeabababaNaNaNaNaNpupvpvpvpvpvoCnjmhmfpwpxmfoOmkppnjnjnjnjnjgjgiiuotiviFivouiGhxnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjacabaiaNaNaNaNaNaNaNaNaNpypzpApzpzpzpzpCoOJboOoOoOoOmkppnjnjnjnjnjgjiIotiviJiSiKivouiTnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNpFaVoBpvpvpvoCnjmimfmfmfmhoOmkppoBpvpvpvpvpvpviviJiSiUiSiKiviTnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaWaNaiababaXnjpRpSpTpSjOoOpUpViWiViViXiViViWiFiSiYjjjiiSiFiTnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqasaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjaYabaNaNaNaNaNaNaNaNaNaNaNaNaNaNovabaonjqfqgqhqiqjoOoOoOoBpvpvpvpvpvpviviJiSjkiSiSiviTnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rErErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjaeabaNaNaNaNaNaNaNaNaNaNaNaNaNaNalabaonjnjppqtqrqunjqwoOnjnjnjnjnjgjiIowiviJiSiKivoxiTnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +rKrErErErErErErErErErErErErErEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWcPbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaNaNaNanabababnjnjnjnjnjnjqDqDqEqFqGqHnjgjjvjuowivjwivoxjxjynjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaiabababbabaoyaXnjqLqMqMqMqMqMnjjzgjjvjJjJjKjJjJjyjznjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababacababaoqXqMqMqMqMqMmlnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababadoAozamnjrerererererfnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababaonjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNoDaeababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNabaNaNaNaNaNabaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNbZbZbZbZbZbZrPrQdebZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNabaiaNaNaNaiabaNaNaNaNaNalabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNbZcYlZrUrVrWrXrXrXbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaiaNaNaNaiabababababababaiaNaNaNaiababaeabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNbZrXrXrXrXrXrXrYrZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNbZsasbsbsbscsdsesbbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNsfsgsgsgsgsashsisjbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNbZsgskslsmsasnsomdbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaqaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNbZbZbZbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1635,7 +1643,7 @@ aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbW aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwEtDKDKDKDKDKDKDKDKDKDKDKDKEuDAEnaNDvDwEvEwExEyEwEzDwjIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEBDKECDKDKDKDKDKDKDKDKDKDKDKDKDKDKDAaNaNaNEDEEEFEwEwEwEGEDaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWnnbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwDwDwDwDMEHDMDwDwDwDwDwEIDKDKDAaNaNaNEJEKEwEwEwEwELEJaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEnaNEMDAENEOEPDKDKEQERESETEuDADKDKDAiEaNDtDAEUEwEVEWEwEXDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEnaNEMDAENEOEPDKDKEQERESETEuDADKDKDAiEaNDtDAosEwEVEWEwEXDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWjLbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKDKDKDKDKDKDKEYDKDKDADwEZDwDwDwFaDwDwFaDwDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFbFcFdDKDKDKFeFeFeDKEHDKDKDAFfEwEwdfDADKDAFhFiFjDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKkhFkDwDwDwDwDADKDKDAEwEwFlFmDADKDAFnFoFpDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/_maps/map_files/cyberiad/z4.dmm b/_maps/map_files/cyberiad/z4.dmm index cf6f91d08f6..d1d1e19b27d 100644 --- a/_maps/map_files/cyberiad/z4.dmm +++ b/_maps/map_files/cyberiad/z4.dmm @@ -247,6 +247,7 @@ "eM" = (/obj/machinery/field/generator,/turf/simulated/floor/plating/airless,/area/space) "eN" = (/obj/item/weapon/grenade/chem_grenade/drugs,/turf/simulated/floor/plating,/area/exploration/methlab) "eO" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/drugs/meth,/obj/item/weapon/reagent_containers/glass/beaker/drugs/meth,/obj/item/weapon/reagent_containers/glass/beaker/drugs/meth,/turf/simulated/floor/plating,/area/exploration/methlab) +"eP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plating,/area/constructionsite/atmospherics) "fe" = (/turf/simulated/floor/plasteel/airless{icon_state = "white"},/area/constructionsite/medical) "ff" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/constructionsite/medical) "fg" = (/obj/machinery/sleeper{dir = 8},/turf/simulated/floor/plasteel/airless{icon_state = "white"},/area/constructionsite/medical) @@ -262,7 +263,6 @@ "fv" = (/turf/simulated/wall,/area/constructionsite/atmospherics) "fw" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plating/airless,/area/constructionsite/atmospherics) "fx" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "d_air_in"; name = "Mixed Air Supply Control"; output_tag = "d_air_out"; pressure_setting = 2000; sensors = list("d_air_sensor" = "Tank")},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plating/airless,/area/constructionsite/atmospherics) -"fy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plating,/area/constructionsite/atmospherics) "fz" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; external_pressure_bound = 0; frequency = 1443; icon_state = "in"; id_tag = "d_air_out"; internal_pressure_bound = 2000; on = 1; pressure_checks = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/constructionsite/atmospherics) "fA" = (/obj/machinery/light/small{dir = 1},/obj/machinery/air_sensor{frequency = 1443; id_tag = "d_air_sensor"; output = 7},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/constructionsite/atmospherics) "fB" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating/airless,/area/constructionsite/atmospherics) @@ -458,13 +458,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdhdtdtdhfrfqfrfqfrfqfqfmfqfmfqfmfqfmdCdidididCfhfhfhfhfififififhfhfhfhfhfhdhdjdjdhabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdhdtdtdhfqfqfqfqfqfqfqfqfmfmfmfmdhdhdhdidididhdhdhfhfhfififififhfhfhfhfhfhdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtdtdtfufrfqfrfqfrfqfrfrfrfqfqdhdhdidididididididhdhfifififififhfhfhfvfvfvdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafudtdtdtfqfqfqfqfqfqfqfqfqfqfqdhdidididididididididhfififififififwfxfyfzfAdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafudtdtdtfqfqfqfqfqfqfqfqfqfqfqdhdidididididididididhfififififififwfxePfzfAdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafudtdtfufrfrfrfrfrfrfrfrfrfqfqdhdidididididididididhfifififhfhfhfBfwfCfDfEdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafufufufufrfrfmfrfrfmfmfmfmfmfmfFdididididididididiftfifififhfhfhfhfhfvfvfvdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafufufufufmfrfmfrfmfqfmfqfmfqfmfFdididididididididiftfififififififGfHfyfIfJdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafufufufufmfrfmfrfmfqfmfqfmfqfmfFdididididididididiftfififififififGfHePfIfJdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafufufufufrfrfrfrfrfmfmfmfmfmfmfFdididididididididiftfifififififififGfCfKfLdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafufufufufrfrfrfrfrfrfrfrfrfqfqdhdidididididididididhfififififififififvfvfvdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafMfNfNfNfNfNfNfNfNfNfNfNfMfqfqfqfqfqdhdidididididididididhfififififififGfOfyfPfQdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafMfNfNfNfNfNfNfNfNfNfNfNfMfqfqfqfqfqdhdidididididididididhfififififififGfOePfPfQdhdjdjdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafMfRfSfRfSfRfRfRfRfRfRfSfNfrfqfrfmfmdhdhdidididididididhdhfvfvfififTfGfifGfCfUfVdhdtdtdCabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafMfRfRfRfRfRfSfRfSfMfSfSfNaaabaafSfRfSdhdhdhdidididhdhdhababfvfvfvfvfvfvfvfvfvfvdhdjdjdCalabalabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafMfRfSfRfSfRfRfRfRfRfRfWfNabababfRfRfRfRfRdhdidididhfSfSfRfRfSfRfSfRfRfRfRfSfRfSdjdtdtdjabababalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/z5.dmm b/_maps/map_files/cyberiad/z5.dmm index cef2e888446..d7b92fbf843 100644 --- a/_maps/map_files/cyberiad/z5.dmm +++ b/_maps/map_files/cyberiad/z5.dmm @@ -12,7 +12,7 @@ "al" = (/obj/machinery/light/small,/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "am" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "an" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/mineral,/area/mine/dangerous/explored) -"ao" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"ao" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "ap" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/space,/area/space) "aq" = (/obj/structure/transit_tube{icon_state = "D-NW"},/obj/structure/lattice,/turf/space,/area/space) "ar" = (/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) @@ -20,17 +20,17 @@ "at" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "au" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/mineral,/area/mine/dangerous/explored) "av" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) -"aw" = (/obj/structure/transit_tube,/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"aw" = (/obj/structure/transit_tube,/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "ax" = (/obj/structure/transit_tube/station,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) "ay" = (/obj/structure/transit_tube,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"az" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"az" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "aA" = (/obj/structure/transit_tube,/obj/structure/lattice,/turf/space,/area/space) "aB" = (/obj/structure/transit_tube{icon_state = "W-SE"},/obj/structure/lattice,/turf/space,/area/space) "aC" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) "aD" = (/obj/structure/transit_tube{icon_state = "S-NE"},/obj/structure/lattice,/turf/space,/area/space) "aE" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "aF" = (/obj/structure/closet/hydrant{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aG" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/stock_parts/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) +"aG" = (/obj/structure/table,/obj/item/device/plant_analyzer,/obj/item/weapon/stock_parts/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "aH" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "aI" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) "aJ" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) @@ -62,17 +62,17 @@ "bj" = (/turf/simulated/mineral/random,/area/mine/dangerous/unexplored) "bk" = (/obj/structure/transit_tube{icon_state = "N-SW"},/obj/structure/lattice,/turf/space,/area/space) "bl" = (/turf/simulated/wall/r_wall,/area/research_outpost/spectro) -"bm" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weedkiller/triclopyr,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) +"bm" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "bn" = (/obj/machinery/light/small,/obj/structure/closet/walllocker/emerglocker/north{dir = 1; pixel_y = -32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) "bo" = (/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"bp" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_access_txt = "0"; req_one_access_txt = "65;12"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/maintstore1) +"bp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_access_txt = "0"; req_one_access_txt = "65;12"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/maintstore1) "bq" = (/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "br" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "bs" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/camera{c_tag = "Research Outpost Auxiliary Storage"; dir = 8; network = list("Research Outpost")},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel,/area/research_outpost/maintstore1) "bt" = (/obj/structure/table,/turf/simulated/floor/carpet,/area/research_outpost/hallway) "bu" = (/obj/machinery/light_switch{pixel_y = -23},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bv" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rminingdorm1"; name = "Dorm 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) -"bw" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) +"bv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rminingdorm1"; name = "Dorm 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) +"bw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) "bx" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/lattice,/turf/space,/area/space) "by" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SE"},/turf/space,/area/space) "bz" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/structure/lattice,/turf/space,/area/space) @@ -89,15 +89,15 @@ "bK" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel,/area/research_outpost/hallway) "bL" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitecorner"},/area/research_outpost/hallway) "bM" = (/turf/simulated/wall/r_wall,/area/research_outpost/atmos) -"bN" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"bO" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) +"bN" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/atmos) +"bO" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/atmos) "bP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "bQ" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plasteel/airless,/area/mine/abandoned) "bR" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "S-NE"},/turf/space,/area/space) "bS" = (/obj/structure/dresser,/turf/simulated/floor/carpet,/area/research_outpost/hallway) "bT" = (/obj/structure/stool,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "bU" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"bV" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Spectrometry Lab Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) +"bV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Spectrometry Lab Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "bW" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "bX" = (/obj/structure/sign/nosmoking_2{pixel_y = 32},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "bY" = (/obj/structure/table,/obj/machinery/light{dir = 1},/obj/machinery/reagentgrinder,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) @@ -105,7 +105,7 @@ "ca" = (/obj/machinery/door/window/westleft{dir = 1; name = "Sample Preparation Loading"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteblue"},/area/research_outpost/sample) "cb" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "bluecorner"},/area/research_outpost/sample) "cc" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/research_outpost/spectro) -"cd" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/research_outpost/maintstore1) +"cd" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/research_outpost/maintstore1) "ce" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) "cf" = (/obj/structure/sink{pixel_y = 30},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "cg" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) @@ -124,18 +124,18 @@ "ct" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/research_outpost/spectro) "cu" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "cv" = (/obj/machinery/power/apc{dir = 4; name = "Mass Spectrometry APC"; pixel_x = 24; pixel_y = 0; pixel_x = 0},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"cw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHEAST)"; icon_state = "whitegreen"; dir = 5},/area/research_outpost/maintstore1) +"cw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHEAST)"; icon_state = "whitegreen"; dir = 5},/area/research_outpost/maintstore1) "cx" = (/obj/structure/stool,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cy" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cA" = (/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/sample) "cB" = (/obj/structure/disposaloutlet{dir = 8},/obj/structure/disposalpipe/trunk{dir = 2},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"cC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHEAST)"; icon_state = "whitegreen"; dir = 6},/area/research_outpost/maintstore1) +"cC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHEAST)"; icon_state = "whitegreen"; dir = 6},/area/research_outpost/maintstore1) "cD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) "cE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall,/area/research_outpost/hallway) "cF" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/curtain/open/shower,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "cG" = (/obj/machinery/door_control{id = "rbath"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) +"cH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/research_outpost/hallway) "cI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "cJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "cK" = (/obj/machinery/light/small{dir = 8},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 5; level = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -155,7 +155,7 @@ "cY" = (/obj/machinery/light/small{dir = 4},/obj/machinery/power/apc{dir = 4; name = "Sample Preparation APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "cZ" = (/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) "da" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) -"db" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/anomaly) +"db" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/anomaly) "dc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "de" = (/obj/machinery/atmospherics/unary/heat_reservoir/heater{dir = 4},/obj/structure/sign/nosmoking_1{pixel_x = -32},/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -173,15 +173,15 @@ "dq" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/camera{c_tag = "Research Outpost Sample Preparation"; dir = 1; network = list("Research Outpost")},/obj/item/weapon/reagent_containers/glass/beaker/water,/obj/item/weapon/reagent_containers/glass/beaker/fuel,/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 3; pixel_x = 2; pixel_y = 2},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) "dr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) "ds" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dt" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"dt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "du" = (/obj/machinery/power/apc{dir = 1; name = "Anomalous Materials APC"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) "dv" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dx" = (/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dy" = (/obj/machinery/light{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dz" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) -"dA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/door/firedoor{dir = 1; name = "Firelock North"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) +"dA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) +"dB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dC" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/atmos) "dD" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) "dE" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; layer = 2.4; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8; initialize_directions = 11; level = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -194,9 +194,9 @@ "dL" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged5"},/area/mine/abandoned) "dM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/mine/abandoned) "dN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"dO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) +"dO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/spectro) "dP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/sample) -"dQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) +"dQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/sample) "dR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/research_outpost/sample) "dS" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) "dT" = (/obj/structure/table,/obj/item/weapon/lighter/random,/obj/item/weapon/crowbar,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) @@ -206,7 +206,7 @@ "dX" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/structure/plasticflaps,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) "dY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) "dZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"ea" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/atmos) +"ea" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/atmos) "eb" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) "ec" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) "ed" = (/obj/machinery/meter,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/research_outpost/atmos) @@ -227,7 +227,7 @@ "es" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/alarm{dir = 2; pixel_y = 25},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "et" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"ev" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) +"ev" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "ew" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "ex" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/sign/chemistry{desc = "A warning sign which reads 'SAMPLE PREPARATION'"; name = "\improper SAMPLE PREPARATION"; pixel_y = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "ey" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) @@ -240,7 +240,7 @@ "eF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "eG" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) "eH" = (/turf/simulated/wall/r_wall,/area/research_outpost/power) -"eI" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plasteel,/area/research_outpost/power) +"eI" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plasteel,/area/research_outpost/power) "eJ" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/wall/r_wall,/area/research_outpost/power) "eK" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/wall/r_wall,/area/research_outpost/power) "eL" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/mineral,/area/mine/dangerous/explored) @@ -258,17 +258,17 @@ "eX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "eZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"fa" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) +"fa" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) "fb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10; initialize_directions = 10; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) "fc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/research_outpost/hallway) -"fd" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"fd" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "fe" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) "ff" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "fg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "fh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) "fi" = (/obj/structure/sign/nosmoking_1{pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/power) "fj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fk" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"fk" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "fl" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurple"},/area/research_outpost/hallway) "fm" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) "fn" = (/obj/structure/sign/science,/turf/simulated/wall/r_wall,/area/research_outpost/entry) @@ -299,7 +299,7 @@ "fM" = (/obj/machinery/camera{c_tag = "Research Outpost Anomalous Materials Lab"; dir = 8; network = list("Research Outpost")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "fN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = -32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "fO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"fP" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) +"fP" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) "fQ" = (/turf/simulated/floor/plating,/area/research_outpost/power) "fR" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable,/turf/simulated/floor/plating,/area/research_outpost/power) "fS" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) @@ -315,17 +315,17 @@ "gc" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp/granted,/turf/simulated/floor/wood,/area/research_outpost/hallway) "gd" = (/turf/simulated/floor/wood,/area/research_outpost/hallway) "ge" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"gg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"gh" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) -"gi" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"gf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) +"gg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"gh" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) +"gi" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "gj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/camera{c_tag = "Research Outpost Hallway Engineering"; dir = 4; network = list("Research Outpost")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "gk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) "gl" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/power/apc{dir = 8; name = "Outpost Power APC"; pixel_x = -24; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/research_outpost/power) "gm" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/research_outpost/power) "gn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/research_outpost/power) "go" = (/obj/machinery/portable_atmospherics/scrubber,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/research_outpost/power) -"gp" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/power) +"gp" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/power) "gq" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power) "gr" = (/obj/machinery/mass_driver{dir = 4; id_tag = "researchdriver"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power) "gs" = (/obj/item/stack/rods,/obj/structure/lattice,/turf/space,/area/space) @@ -367,11 +367,11 @@ "hc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "hd" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/mine/abandoned) "he" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/wall,/area/research_outpost/entry) -"hf" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"hf" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "hg" = (/obj/machinery/door/airlock/external{id_tag = "mining_away"; name = "Mining Dock Airlock"; req_access_txt = "48"},/turf/simulated/floor/plating,/area/mine/lobby) "hh" = (/turf/simulated/floor/plating,/area/research_outpost/tempstorage) -"hi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"hj" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"hi" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"hj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "hk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/effect/spawner/window/reinforced,/turf/simulated/floor/wood,/area/research_outpost/hallway) "hl" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/wood,/area/research_outpost/hallway) "hm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) @@ -389,7 +389,7 @@ "hy" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal,/turf/simulated/floor/plating,/area/research_outpost/power) "hz" = (/obj/structure/rack,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) "hA" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power) -"hB" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) +"hB" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/hallway) "hC" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) "hD" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) "hE" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) @@ -397,7 +397,7 @@ "hG" = (/obj/effect/gibspawner/robot,/turf/simulated/floor/plasteel/airless{icon_state = "floorscorched1"},/area/mine/abandoned) "hH" = (/obj/effect/gibspawner/human,/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/mine/abandoned) "hI" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/remains/xeno,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"hJ" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"hJ" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "hK" = (/obj/machinery/computer/shuttle/science,/turf/simulated/floor/plasteel{icon_state = "bot"},/area/research_outpost/entry) "hL" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "hM" = (/obj/docking_port/stationary{dir = 8; dwidth = 3; height = 5; id = "mining_away"; name = "asteroid mine"; width = 7},/turf/space,/area/space) @@ -412,7 +412,7 @@ "hV" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/fire,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "hW" = (/turf/simulated/wall/r_wall,/area/research_outpost/tempstorage) "hX" = (/obj/machinery/camera{c_tag = "Research Outpost Temporary Storage"; dir = 2; network = list("Research Outpost")},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) -"hY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating,/area/research_outpost/maint) +"hY" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "hZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/light_switch{pixel_x = 0; pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) "ia" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/tempstorage) "ib" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Central"; dir = 4; network = list("Research Outpost")},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) @@ -424,16 +424,16 @@ "ih" = (/obj/structure/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/color/latex,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/anomaly) "ii" = (/obj/machinery/door/window/westleft{dir = 2; name = "Monkey Pen"; req_access_txt = "47"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) "ij" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/anomaly) -"ik" = (/obj/machinery/door/firedoor{layer = 2.6; name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"il" = (/obj/machinery/door/firedoor{layer = 2.6; name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"im" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) +"ik" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"il" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Power substation"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/power) +"im" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/harvesting) "in" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) "io" = (/obj/structure/transit_tube{icon_state = "E-NW"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) "ip" = (/obj/structure/transit_tube/station,/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = 32; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) "iq" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "ir" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "is" = (/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"it" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/harvesting) +"it" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "iu" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "iv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "iw" = (/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/mine/abandoned) @@ -443,23 +443,23 @@ "iA" = (/obj/machinery/door/airlock,/turf/simulated/floor/plasteel/airless,/area/mine/abandoned) "iB" = (/obj/structure/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plasteel/airless{icon_state = "damaged5"},/area/mine/abandoned) "iC" = (/obj/structure/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/plasteel/airless{icon_state = "damaged5"},/area/mine/abandoned) -"iD" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"iD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "iE" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/research_outpost/entry) "iF" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"iG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"iG" = (/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_medical{id_tag = ""; name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "iH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "iI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "iJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/entry) -"iK" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_medical{id_tag = ""; name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) +"iK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "iL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "iM" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/med) "iN" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/entry) "iO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "iP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"iQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) +"iQ" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "iS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) -"iT" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"iT" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "iW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) @@ -472,7 +472,7 @@ "jd" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) "je" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellow"},/area/research_outpost/hallway) "jf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"jg" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research Outpost"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"jg" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "D-NE"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "jh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurple"},/area/research_outpost/hallway) "ji" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) "jj" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Airlock"; dir = 2; network = list("Research Outpost")},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) @@ -491,7 +491,7 @@ "jw" = (/obj/structure/table,/turf/simulated/floor/plasteel/airless,/area/mine/abandoned) "jx" = (/turf/simulated/floor/plasteel/airless{icon_state = "floorgrime"},/area/mine/abandoned) "jy" = (/obj/structure/rack,/turf/simulated/floor/plasteel/airless,/area/mine/abandoned) -"jz" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "D-NE"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"jz" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "jA" = (/obj/structure/transit_tube{icon_state = "S-NW"},/turf/simulated/floor/plasteel{icon_state = "delivery"; name = "floor"},/area/research_outpost/entry) "jB" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "jC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Research Outpost Shuttle Dock"; dir = 8; network = list("Research Outpost")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/research_outpost/entry) @@ -508,7 +508,7 @@ "jN" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/research_outpost/tempstorage) "jO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "jP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"jQ" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) +"jQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "jR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) "jS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "jT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM ONE'"; name = "\improper ISOLATION ROOM ONE"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) @@ -519,14 +519,14 @@ "jY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) "jZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM THREE'"; name = "\improper ISOLATION ROOM THREE"; pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) "ka" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"kb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) +"kb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "kc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/obj/machinery/firealarm{pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "white"},/area/research_outpost/hallway) "kd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/biohazard{pixel_y = -32},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) "ke" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) +"kf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "kg" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/research_outpost/harvesting) "kh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"ki" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) +"ki" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating,/area/research_outpost/maint) "kj" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) "kk" = (/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) "kl" = (/obj/structure/table,/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) @@ -548,7 +548,7 @@ "kB" = (/obj/machinery/light/small,/obj/machinery/camera{c_tag = "Research Outpost Medbay"; dir = 8; network = list("Research Outpost")},/obj/machinery/sleeper,/turf/simulated/floor/plasteel{icon_state = "warnwhite"; dir = 5},/area/research_outpost/med) "kC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "kD" = (/turf/simulated/wall/r_wall,/area/research_outpost/entry) -"kE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Expedition Prep"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) +"kE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) "kF" = (/turf/simulated/wall/r_wall,/area/research_outpost/maint) "kG" = (/obj/machinery/light/small{dir = 1},/obj/machinery/conveyor{dir = 4; id = "anosample"},/turf/simulated/floor/plating,/area/research_outpost/maint) "kH" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso1) @@ -560,10 +560,10 @@ "kN" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso3) "kO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/iso3) "kP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation Room Three"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/iso3) -"kQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) +"kQ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) "kR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) "kS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage) -"kT" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) +"kT" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SW"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/entry) "kU" = (/obj/machinery/alarm{dir = 1; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "kV" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/harvesting) "kW" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) @@ -574,15 +574,15 @@ "lb" = (/turf/simulated/wall,/area/mine/dangerous/unexplored) "lc" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) "ld" = (/turf/simulated/wall/r_wall,/area/research_outpost/gearstore) -"le" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SW"},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) +"le" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Expedition Prep"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/entry) "lf" = (/turf/simulated/wall,/area/research_outpost/entry) "lg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{level = 1},/turf/simulated/wall,/area/research_outpost/entry) "lh" = (/obj/structure/closet/bombcloset,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "li" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/wall,/area/research_outpost/entry) "lj" = (/turf/simulated/wall,/area/research_outpost/tempstorage) -"lk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) +"lk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access_txt = "65"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) "ll" = (/obj/machinery/light_switch{pixel_x = 0; pixel_y = 23},/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 4; pixel_y = 4},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) -"lm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Loading Area"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) +"lm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Loading Area"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/tempstorage) "ln" = (/obj/machinery/conveyor{dir = 4; id = "anosample"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maint) "lo" = (/obj/machinery/disposal/deliveryChute{dir = 8},/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/light_switch{pixel_x = 0; pixel_y = 23},/turf/simulated/floor/plating,/area/research_outpost/maint) "lp" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "Maintenance APC"; pixel_x = 24; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/research_outpost/maint) @@ -602,7 +602,7 @@ "lD" = (/obj/structure/sign/nosmoking_2{pixel_y = -32},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Lab"; dir = 4; network = list("Research Outpost")},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) "lE" = (/obj/machinery/alarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/research_outpost/harvesting) "lF" = (/obj/machinery/artifact_scanpad,/obj/machinery/light/small,/obj/machinery/firealarm{pixel_y = -24},/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) -"lG" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor/plasteel/airless{icon_state = "dark"},/area/mine/abandoned) +"lG" = (/obj/machinery/hydroponics/constructable,/turf/simulated/floor/plasteel/airless{icon_state = "dark"},/area/mine/abandoned) "lH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "lI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) "lJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned) @@ -652,7 +652,7 @@ "mB" = (/obj/structure/transit_tube{tag = "icon-NE-SW"; icon_state = "NE-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "mC" = (/obj/structure/transit_tube{tag = "icon-D-SE"; icon_state = "D-SE"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "mD" = (/obj/structure/transit_tube{tag = "icon-D-NW"; icon_state = "D-NW"},/turf/simulated/mineral,/area/mine/dangerous/unexplored) -"mE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Equipment Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) +"mE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_research{name = "Equipment Storage"; req_access_txt = "65"},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "mF" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "mG" = (/obj/structure/table,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "mH" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/floor/plating,/area/research_outpost/gearstore) @@ -784,7 +784,7 @@ "pd" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"; tag = "icon-closed (EAST)"},/obj/effect/decal/warning_stripes/yellow/hollow,/turf/simulated/floor/plasteel/airless,/area/mine/dangerous/explored) "pe" = (/obj/structure/transit_tube{tag = "icon-W-NE"; icon_state = "W-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "pf" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area/space) -"pg" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) +"pg" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/research_outpost/gearstore) "ph" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/engine/vacuum,/area/mine/podbay) "pi" = (/turf/simulated/floor/engine,/area/mine/podbay) "pj" = (/obj/structure/transit_tube{tag = "icon-D-SE"; icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) @@ -1049,10 +1049,10 @@ "ui" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/space,/area/mine/dangerous/explored) "uj" = (/obj/structure/lattice,/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/space,/area/mine/dangerous/explored) "uk" = (/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) -"ul" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) +"ul" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) "um" = (/turf/simulated/wall/r_wall,/area/mine/maintenance) "un" = (/obj/item/clothing/under/rank/miner,/obj/effect/decal/remains/human,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) -"uo" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/dangerous/explored) +"uo" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/dangerous/explored) "up" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/structure/table/reinforced,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/weapon/crowbar,/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/dangerous/explored) "uq" = (/turf/simulated/floor/bluegrid,/area/mine/maintenance) "ur" = (/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/power/apc{dir = 1; name = "Mining Communications APC"; pixel_x = 1; pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/mine/maintenance) @@ -1069,7 +1069,7 @@ "uC" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 5},/area/mine/dangerous/explored) "uD" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/obj/machinery/light,/turf/space,/area/mine/dangerous/explored) "uE" = (/turf/simulated/wall,/area/mine/living_quarters) -"uF" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Mining Station Communications"; req_access_txt = "48"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/mine/maintenance) +"uF" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Mining Station Communications"; req_access_txt = "48"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/mine/maintenance) "uG" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/dangerous/explored) "uH" = (/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/dangerous/explored) "uI" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/carpet,/area/mine/living_quarters) @@ -1078,30 +1078,30 @@ "uL" = (/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/dangerous/explored) "uM" = (/obj/structure/table,/turf/simulated/floor/carpet,/area/mine/living_quarters) "uN" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/carpet,/area/mine/living_quarters) -"uO" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "miningdorm1"; name = "Room 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) +"uO" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "miningdorm1"; name = "Room 1"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) "uP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "uQ" = (/obj/structure/disposalpipe/trunk,/obj/structure/disposaloutlet{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/dangerous/explored) "uR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/light/small{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "uS" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/dangerous/explored) "uT" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/mine/living_quarters) "uU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/camera{c_tag = "Mining Outpost Bedrooms"; dir = 4; network = list("Mining Outpost")},/turf/simulated/floor/plasteel,/area/mine/living_quarters) -"uV" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) +"uV" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/living_quarters) "uW" = (/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/dangerous/explored) "uX" = (/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"; tag = ""},/area/mine/west_outpost) -"uY" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "miningdorm2"; name = "Room 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) +"uY" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "miningdorm2"; name = "Room 2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) "uZ" = (/turf/simulated/floor/plasteel/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/dangerous/explored) "va" = (/obj/structure/disposalpipe/segment,/turf/simulated/mineral/random,/area/mine/dangerous/unexplored) "vb" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) -"vc" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/mine/dangerous/explored) +"vc" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating/airless,/area/mine/dangerous/explored) "vd" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/west_outpost) "ve" = (/obj/machinery/camera{c_tag = "Mining Outpost West Outpost Mech Recharge Station"; dir = 1; network = list("Mining Outpost")},/turf/simulated/floor/mech_bay_recharge_floor/airless,/area/mine/west_outpost) "vf" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/west_outpost) "vg" = (/obj/structure/disposalpipe/segment,/obj/structure/sign/deathsposal,/turf/simulated/wall,/area/mine/living_quarters) -"vh" = (/obj/structure/grille,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/mine/dangerous/explored) +"vh" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/mine/dangerous/explored) "vi" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "outpost_west_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/turf/simulated/floor/plasteel/airless{tag = "icon-asteroidwarning (EAST)"; icon_state = "asteroidwarning"; dir = 4},/area/mine/dangerous/explored) "vj" = (/obj/machinery/light,/turf/simulated/floor/plating/airless/asteroid,/area/mine/dangerous/explored) "vk" = (/turf/simulated/wall,/area/mine/west_outpost) -"vl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) +"vl" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/west_outpost) "vm" = (/obj/structure/sign/xeno_warning_mining,/turf/simulated/wall,/area/mine/west_outpost) "vn" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters) "vo" = (/obj/machinery/vending/cigarette,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters) @@ -1127,13 +1127,13 @@ "vI" = (/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters) "vJ" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters) "vK" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters) -"vL" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "miningdorm3"; name = "Room 3"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) +"vL" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{id_tag = "miningdorm3"; name = "Room 3"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) "vM" = (/obj/structure/ore_box,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "vN" = (/obj/machinery/recharge_station,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "vO" = (/obj/structure/closet/secure_closet/miner,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "vP" = (/turf/simulated/wall/r_wall,/area/mine/eva) "vQ" = (/turf/simulated/wall,/area/mine/eva) -"vR" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) +"vR" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/eva) "vS" = (/obj/structure/table,/obj/item/weapon/shovel,/turf/simulated/floor/plasteel,/area/mine/west_outpost) "vT" = (/turf/simulated/floor/plasteel,/area/mine/west_outpost) "vU" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/plasteel,/area/mine/west_outpost) @@ -1155,7 +1155,7 @@ "wk" = (/obj/structure/rack,/obj/item/weapon/storage/backpack/satchel,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/belt/utility,/obj/machinery/light/small{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel,/area/mine/eva) "wl" = (/turf/simulated/floor/plasteel/airless{dir = 5; icon_state = "asteroidfloor"; tag = "icon-asteroidfloor"},/area/mine/dangerous/explored) "wm" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/item/clothing/glasses/meson,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel,/area/mine/west_outpost) -"wn" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Break Room"; req_access_txt = "54"},/turf/simulated/floor/plasteel,/area/mine/west_outpost) +"wn" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Break Room"; req_access_txt = "54"},/turf/simulated/floor/plasteel,/area/mine/west_outpost) "wo" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/mine/west_outpost) "wp" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "outpost_west_pump"; tag_exterior_door = "outpost_west_outer"; frequency = 1379; id_tag = "outpost_west_airlock"; tag_interior_door = "outpost_west_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_chamber_sensor = "outpost_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "outpost_west_pump"},/turf/simulated/floor/plasteel,/area/mine/west_outpost) "wq" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "outpost_west_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/camera{c_tag = "Mining Outpost West Outpost External Airlock"; dir = 1; network = list("Mining Outpost")},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/mine/west_outpost) @@ -1173,7 +1173,7 @@ "wC" = (/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "wD" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "wE" = (/turf/simulated/wall,/area/mine/lobby) -"wF" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/lobby) +"wF" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Mining Station Pod Bay"; req_access_txt = "54"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/lobby) "wG" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/camera{c_tag = "Mining Outpost EVA"; dir = 4; network = list("Mining Outpost")},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/mine/eva) "wH" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/mine/eva) "wI" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/mine/eva) @@ -1187,8 +1187,8 @@ "wQ" = (/obj/effect/decal/cleanable/fungus,/turf/simulated/wall,/area/mine/living_quarters) "wR" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/mine/living_quarters) "wS" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/mine/living_quarters) -"wT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass{name = "Crew Area"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) -"wU" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/mining{name = "Mining Station Storage"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) +"wT" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/mine/lobby) +"wU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Crew Area"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "wV" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/portable_atmospherics/scrubber,/obj/machinery/camera{c_tag = "Mining Outpost Starboard Connector"; network = list("Mining Outpost")},/turf/simulated/floor/plasteel,/area/mine/lobby) "wW" = (/turf/simulated/floor/plasteel,/area/mine/lobby) "wX" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/mine/eva) @@ -1211,10 +1211,10 @@ "xo" = (/obj/machinery/mineral/unloading_machine{input_dir = 4; output_dir = 8},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/west_outpost) "xp" = (/obj/machinery/conveyor{dir = 4; id = "mining_west"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/west_outpost) "xq" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/mine/west_outpost) -"xr" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) +"xr" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/mining{name = "Mining Station Storage"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "xs" = (/obj/structure/toilet{dir = 4},/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/mine/living_quarters) "xt" = (/obj/structure/sink{pixel_y = 30},/obj/machinery/light/small,/obj/structure/mirror{pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/mine/living_quarters) -"xu" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{name = "Toilet"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/mine/living_quarters) +"xu" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/lobby) "xv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "xw" = (/obj/machinery/computer/podtracker,/turf/simulated/floor/plasteel,/area/mine/podbay) "xx" = (/obj/machinery/camera{c_tag = "Mining Outpost Crew Area Hallway"; network = list("Mining Outpost")},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/turf/simulated/floor/plasteel,/area/mine/living_quarters) @@ -1227,7 +1227,7 @@ "xE" = (/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/mine/lobby) "xF" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/mine/podbay) "xG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/lobby) -"xH" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Mining Station EVA"; req_access_txt = "54"},/turf/simulated/floor/plasteel,/area/mine/eva) +"xH" = (/obj/effect/spawner/window/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/west_outpost) "xI" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/eva) "xJ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"},/turf/simulated/floor/plasteel,/area/mine/eva) "xK" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/mine/eva) @@ -1237,7 +1237,7 @@ "xO" = (/turf/simulated/floor/plasteel/airless{tag = "icon-asteroidwarning (EAST)"; icon_state = "asteroidwarning"; dir = 4},/area/mine/dangerous/explored) "xP" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/wall,/area/mine/west_outpost) "xQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/mine/west_outpost) -"xR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "54"},/turf/simulated/floor/plating,/area/mine/west_outpost) +"xR" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock{name = "Toilet"},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/mine/living_quarters) "xS" = (/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_west"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plasteel,/area/mine/west_outpost) "xT" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "xU" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/mine/living_quarters) @@ -1247,10 +1247,10 @@ "xY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "xZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "ya" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/mine/living_quarters) -"yb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) +"yb" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Mining Station EVA"; req_access_txt = "54"},/turf/simulated/floor/plasteel,/area/mine/eva) "yc" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "yd" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) -"ye" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/lobby) +"ye" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "54"},/turf/simulated/floor/plating,/area/mine/west_outpost) "yf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) "yg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/mine/lobby) "yh" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) @@ -1276,11 +1276,11 @@ "yB" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/light,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "yC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_west_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "yD" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/camera{c_tag = "Mining Outpost Port Connector"; dir = 1; network = list("Mining Outpost")},/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/mine/living_quarters) -"yE" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) +"yE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/living_quarters) "yF" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/space,/area/mine/living_quarters) "yG" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/space,/area/mine/lobby) "yH" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/light{dir = 4},/turf/space,/area/mine/lobby) -"yI" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/lobby) +"yI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/mine/lobby) "yJ" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/mine/lobby) "yK" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/mine/lobby) "yL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/turf/simulated/floor/plasteel,/area/mine/lobby) @@ -1293,9 +1293,9 @@ "yS" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/mine/west_outpost) "yT" = (/obj/machinery/power/terminal{dir = 4},/obj/machinery/light/small,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/mine/west_outpost) "yU" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable,/turf/simulated/floor/plating,/area/mine/west_outpost) -"yV" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Infirmary"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/mine/living_quarters) +"yV" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/living_quarters) "yW" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/mine/living_quarters) -"yX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "48"},/turf/simulated/floor/plating,/area/mine/living_quarters) +"yX" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; level = 1},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/lobby) "yY" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/wall,/area/mine/living_quarters) "yZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/living_quarters) "za" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) @@ -1363,16 +1363,16 @@ "Ak" = (/obj/machinery/mech_bay_recharge_port,/obj/machinery/light/small,/turf/simulated/floor/plating,/area/mine/production{name = "Mining Station Mech Bay"}) "Al" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/mine/dangerous/explored) "Am" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/mine/dangerous/explored) -"Ao" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/lobby) -"Ap" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor{dir = 2},/turf/simulated/floor/plating,/area/mine/lobby) +"An" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Infirmary"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/mine/living_quarters) +"Ao" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "48"},/turf/simulated/floor/plating,/area/mine/living_quarters) +"Ap" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/lobby) "Aq" = (/obj/machinery/computer/shuttle/mining,/turf/simulated/floor/plasteel,/area/mine/lobby) "Ar" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel,/area/mine/lobby) "As" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) "At" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel,/area/mine/lobby) "Au" = (/turf/simulated/wall,/area/mine/living_quarters{name = "Mining Station Break Room"}) "Av" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/mine/living_quarters{name = "Mining Station Break Room"}) -"Az" = (/obj/machinery/door/firedoor{dir = 2},/obj/machinery/door/airlock/glass_mining{name = "Mining Station Pod Bay"; req_access_txt = "54"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel,/area/mine/lobby) -"AA" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/firedoor{dir = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/mine/lobby) +"Aw" = (/obj/effect/spawner/window/reinforced,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/mine/lobby) "AB" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8},/turf/simulated/floor/plasteel,/area/mine/lobby) "AC" = (/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/mine/lobby) "AD" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Mining Shuttle Airlock"; dir = 8; network = list("Mining Outpost")},/turf/simulated/floor/plasteel,/area/mine/lobby) @@ -1493,19 +1493,19 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPbQbPaaaaaaaaaaacacacacacacacacacacacacacacacacacacacacacacbjacacacbjbjacbjbjbjacacbjbjbjbjbjbjbjbjbjbjbjbjacacacacaaaabRbBagagagagagafafafafblccbTbUbVbWbXbYbZcacbcdcwcebacfcgbJchcicjckclcmcncocpbNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqcrcqagaaaaaaacacacacacacacacacacacacbjbjbjbjbjbjacacacacacacacbjbjbjbjbjacacacbjbjbjbjbjcsbjbjbjbjbjbjbjbjacacacacaaaaaQaaaaaaaaaaaaafafafafblctcucvblcycxbWbWczcAcBcCcDcEcFcGcHcIcJbMcKcLcMcNcOcPbNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQcRcScTagaaaaacacacacacacacbjacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacaaaaaQaaaaaaaaaaaaafafafafblctcucUblcVbWcWcXcYcZdacZdbcZcZcZcZdcddbMdecLdfdgdhcpbNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadididjdkdlcqagaaaaacacacacbjbjbjacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacaaagaQaaaaaaaaaaaaafafafafblctdmdnbldodpdqdrdsdtdudvdwdxdydzcZdAdBbMdCdDdEdFbMbObNagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadididjdkdlcqagaaaaacacacacbjbjbjacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacaaagaQaaaaaaaaaaaaafafafafblctdmdnbldodpdqdrdsdtdudvdwdxdydzcZdBdAbMdCdDdEdFbMbObNagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadGdHdIdJdKdLdMagagacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacaaagaQaaagagagagagafaLaLaLaLaLdNdOaLbEbEdPdQdRcZdSdTdUdVdWdXcZdYdZeaebecedeebMefafagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaegdieheiejdlekacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacaaaaaQaaaaaaaaaaaaaaaLemenenepeqereseteuevewexcZeyezeoeBeAeDeEeFeGeHeHeHeIeJeKeMeLeLeNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagageOePeQekacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjacacacacacacaaaaaQaaaaaaaaaaaaaaaoeReSeSeUeVeWeXeYeZfafbfcfdfefffgfhfhfjfkflfmeHeCfieTfqeHfrafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagfsftfufvekacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacaaaaaaaaaQaaaaaaaaaaaaaaaofwenfxfyfzfAfBfCfDaLfEfFfGfHfIfJfKfLfMcZfNfOfPfQfQfRfSfTfVfUafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagfWfXfYekfZgaekekekekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaaaQaaaaaaaaaaaaaaaofwenfxfygbgcfBgdgeaLgfggcZghcZcZcZcZgicZgjgkeHglgmgngogpgqgraeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagfWfXfYekfZgaekekekekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaaaQaaaaaaaaaaaaaaaofwenfxfygbgcfBgdgeaLgggfcZghcZcZcZcZgicZgjgkeHglgmgngogpgqgraeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaggsgtgugvgwgxbPdLgyekgzgAekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaaaQaaaaaaelaaaaaaaLfwengBfygCfAfBgEgFaLgGgHgIgJgKgLgMcZgOgNgPgQgRgSgTfQgVgpefafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaggWgXgtgYgZhahbhcgyhdgAgAgzekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaahehfhfhfadhfhfhffnhihjbahkhlaLaLaLaLaLhmhnhogJhpgLhqcZhshrhthuhvhwhxgUhyhAhBhCaLhDbzaAaAaAaAaAaAaBhEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahFgWgXgWgugufZhGgZekfvhHekgAhIekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaahJhKhLhNhNhNhOhPhQhRhShThUhVhWhXfohZiaibicidieifigihcZiiijikileHeHimeHeHeHinioipiqirisisitisisisiubhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagiviwguixiygueQizhaiAiBiCekekekekekekbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacacacacacaaaaaaaaaaiDiEhNhNhNhNiFiGiHiIiJiKiLiMhWfpiOiPiQiRiSiTiUiViWiXiYiZiWjajbjcjdjejfjcjgjciWjhjijjjkjljmjnjojpisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagjqjrjsguiygAgYjtgZcrekjujvekjwgyjxjyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacacacacacacaaaaaaaaaajzjAhNhNjBhNjCjDjEjFjGjHjIjJhWjKjLjMjNjOjPjQjRjSjTjUjVjWjXjUjYjVjZjUjVkakbkckdkekfkgkhkikjkkkkklisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagagbjbjekgxkmkngzjskogZhajwbPdLkpekjwfvgyjyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacafafafafafafacacacacacacacaaaaaaaahfkqhNkrksktkukvkwkxkykzkAkBhWkCgDhhkFkFkFkFhYkHkIkJkHkKkLkMkKkNkOkPkNkNkQkRkSkTiskUkViskWkkkkkXisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagekekekekekekgwgZkYkmgZizkZjwjwhcgyjuekjweQlajyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacafafafaeaeaeaeafafafacacacaclblcaaaaaaiNlehfhfkDlflflflgkElibaljljhWlkkFkFkFkGlnlolpkHlqlrlskKltlulvkNlwlxlykNlzlAkSlBlCisisislDlElFjpisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaggWgXgtgYgZhahbhcgyhdgAgAgzekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaahehfhfhfadhfhfhffnhjhibahkhlaLaLaLaLaLhmhnhogJhpgLhqcZhshrhthuhvhwhxgUhyhAhBhCaLhDbzaAaAaAaAaAaAaBhEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahFgWgXgWgugufZhGgZekfvhHekgAhIekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacaaaaaaaaaaaahJhKhLhNhNhNhOhPhQhRhShThUhVhWhXfohZiaibicidieifigihcZiiijikhYeHeHileHeHeHinioipiqirisisimisisisiubhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagiviwguixiygueQizhaiAiBiCekekekekekekbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacacacacacaaaaaaaaaaitiEhNhNhNhNiFiDiHiIiJiGiLiMhWfpiOiPiKiRiSiQiUiViWiXiYiZiWjajbjcjdjejfjciTjciWjhjijjjkjljmjnjojpisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagjqjrjsguiygAgYjtgZcrekjujvekjwgyjxjyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacacacacacacaaaaaaaaaajgjAhNhNjBhNjCjDjEjFjGjHjIjJhWjKjLjMjNjOjPjzjRjSjTjUjVjWjXjUjYjVjZjUjVkajQkckdkekbkgkhkfkjkkkkklisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagagagbjbjekgxkmkngzjskogZhajwbPdLkpekjwfvgyjyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacafafafafafafacacacacacacacaaaaaaaahfkqhNkrksktkukvkwkxkykzkAkBhWkCgDhhkFkFkFkFkikHkIkJkHkKkLkMkKkNkOkPkNkNkEkRkSkQiskUkViskWkkkkkXisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagekekekekekekgwgZkYkmgZizkZjwjwhcgyjuekjweQlajyekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacafafafaeaeaeaeafafafacacacaclblcaaaaaaiNkThfhfkDlflflflglelibaljljhWlkkFkFkFkGlnlolpkHlqlrlskKltlulvkNlwlxlykNlzlAkSlBlCisisislDlElFjpisbxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaageklGdLhagwekjqlHjrekiAeklIlJlKekdLlLcrlMeQfucrekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjacacacafafaeaeaeaeaeaeaeaeafafacaclNlOaAaAajaAbAbBagagldlhlRlllTlUlVlWlmlYlZmalPmglQlSmfmgmhkHmimjmkkKmlmmmnkNmompmqkNmrmsmtmumvmwmxisisisisismybkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaceklGeQdLgYiAlLkmdLkmfudLdLmzgydLeQeQekcrmAeQdLekbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacafafaeaeaeaeaeaeaeaeaeaeafafmCmBmDacaaaaaaaaaaaaagldlXmFmbmHmImJmcljmdmMhWkFkFkFkFkFmgmPkHmQmRmSkKmTmUmVkNmWmXmYkNmZnanbncndndnelCmKaiaAaAngnhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaceklGnieQeQiAeQlafZeQnjfulakpcreQnkfvekkmcrlLdLekbjbjbjbjbjbjbjbjcsbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacafnfaeaeaeaeaeaeaeaeaeaeaenlafnnnmafafaaaaaaaaaaaaagldmenqnrmEnrntmGljljnvhWnononQnokFnAnBkHnCnDnEkKnFnGnHkNnInJnKkNnLnMlCnNnOnPnOlCnnnUafagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1619,19 +1619,19 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaccsacacacacaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacaaaaaaaaaaaaaaacacacbjbjacaaaaaaaaaeaevkvkvkvkvkvkvlvlvlvkvmvkvkvkaeaeaeafacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacafafaeaeaeaeaeafafafafafacacacacacacacbjbjbjbjuEuEuEuEvnvovpuEuIvquEvruEuEuEuVuVuVuEaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaafafafafaeaeaeaeoapSpUpTpApVphaeaeaeaeaeaeaeaeafafafafafoBoBoBoBoBoBoBoBoBoBafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacaaaaaaaaaaaaaaacacacacacaaaaafaeaeaevkvvvwvxvyvzvAvBvCvDvEvFvGvyrkaeaeafafafafacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacafafaeaeaeaeaeaeaeaeaeaeafafafafafacacacacbjbjbjuEvHvIvJvKvIvIuEuMuNvLuKuEvMvNvOvOvOuVaeaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaafafafaeaeaeaeqdqcqsqqwXvPvRvRvQvQaeaeaeaeaeaeafafafafoBoBoBoBoBoBoBoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaacacacaaaaacafaeaeaevkvSvTvUvyvTvVvTvTvWvXvYvGvZviaeaeaeaeaeafafafacacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjacacafafnfaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafacacacacacacuEwbvIwcwdwewfuEuEuEuEuKuEvMwgwgwgwhuVaeaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaaeaeaeaeaeaeaeqdxwzgxFwXwiwjwjwkvQaevjaeaeaenXnfafafafoBoBoBoBoBoBoBoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaaaaaaacafaeaeaevkwmvTvTwnvTvVwovTvTvywpwqvyrKaeaeaeaeaeaeaeafafafafacacacacacacbjbjbjbjbjbjbjbjbjacacafafaevbaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafacacacuEwrwswtvIwuwvwwwhwxwywzuEoTwgwBwCwDuVaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaeaezRzRAAAzwXwGwHwIwJvQvQvQvQaeaeaeaeafafafafoBoBoBoBoBoBoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacafafaeaevkwKvTwLvEwMwNwOvTvkvkvkvkvkvmrjrkaeaeaeaeaeaeaeaeafafafacacacacacbjbjbjbjbjbjbjacacacafaeaeaeaeaeaeaeaeaeaeaerjrkaeaeaeaeaeaeaeaeaeafafacacwPuEuEuEwQuEuEwRwSwTwRwSuEuEuEuEuEwUuEuEuVuVaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaewFwFwVAMABwYwZxaxaxbxcxdxexcrkaeaeaenlafafafoBoBoBoBoBoBoBafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaevkxfxgxhvyxixjxkxlxmxnxoxpxqxrtStTqJqJqJqJqJqFaeaeaeaeafafafacacacacacbjbjbjacacacacafafaeaetRqJqJqJqJqJqJqJqJtStTqJqJqJqJqFaeaeaeaeaeafacacacacacwQxsxtxuwgwDxvwhwDwwzJxxxywhwDwgxzxAuVuVuVxBxCxCxCxCxCxCxCxDxDxDxDxDxDxDwFwFwFxEwWBQxGxHxIxaxaxJxKxLxMxNvsaeaeaenlafafafoBoBoBoBoBoBafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaevkvkvkvkvkxPxQxRvkvkxSvkvkvkvkrCrKaeaeaeaeaepuaeaeaeaeafaeafafacacacacacacacacacacafafaeaeaepuaeaeaeaeaeaeaeaerCrKaeaeaeaepuaeaeaeaeaeafafnfafafacuEuEuEuEwgwDxTxUxVwyxWxXxXxYxYxZxXyaybxXybycycycycycycycycydydydydydydydyeyfyeygyfyhyiyjykylymynxcyoypxcrKaeaeaeaeafafafafoBoBoBoBoBafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafafaeaeaeaeaevkyqyrysytvknovtofaeaeaeaeaeqvaeaeaeqEqJqJqFaeaeaeaeafacacacacacacacacacacafaeaetRqJtQaeaeaeaeafaeaeqvaeaeaeaeaeaepuaeaeaeaeaeaeaevbaeafafafafafuEwgywyxyyyyyxyzyAyByyyyyCyxyDyEyEyEyFyFyFyFyFyFyFyFyGyGyGyGyGyGyHyIyIyIyJyKyLyMyNyOyPyOyOyOyOyOyOvuaeaeaeaenlafafafoBoBoBoBafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafafaeaeaeaevkyRySyTyUvkaeaeaeaeaeaeafafnfafaeaeaeaeaepuaeaeaeaeaeafacacacacacafafafafafaetRtQaeaeaeafafafafafafnfaeaeaeaeaeaepuaeaeaeaeaeaeaeaeaeaeaeafafuEuEwRyVwRuEuEyWyXyYuEuEuEyZwRuEuVaeaeaeaaaaaaaaagaaaaaaagaaaaaaaaaaagaawFwFwWzazbzczdzezfBRzhziyOuvwaaeaeaeaeaeafafafoBoBoBoBafafafoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacaaaaaaaaaaaaaaaaaaaaaaaaaaacafaeaeaevkwmvTvTwnvTvVwovTvTvywpwqvyrKaeaeaeaeaeaeaeafafafafacacacacacacbjbjbjbjbjbjbjbjbjacacafafaevbaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeafafafafacacacuEwrwswtvIwuwvwwwhwxwywzuEoTwgwBwCwDuVaeaeaeaeaeaeaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaeaezRzRwTwFwXwGwHwIwJvQvQvQvQaeaeaeaeafafafafoBoBoBoBoBoBoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacafafaeaevkwKvTwLvEwMwNwOvTvkvkvkvkvkvmrjrkaeaeaeaeaeaeaeaeafafafacacacacacbjbjbjbjbjbjbjacacacafaeaeaeaeaeaeaeaeaeaeaerjrkaeaeaeaeaeaeaeaeaeafafacacwPuEuEuEwQuEuEwRwSwUwRwSuEuEuEuEuExruEuEuVuVaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaexuxuwVAMABwYwZxaxaxbxcxdxexcrkaeaeaenlafafafoBoBoBoBoBoBoBafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaevkxfxgxhvyxixjxkxlxmxnxoxpxqxHtStTqJqJqJqJqJqFaeaeaeaeafafafacacacacacbjbjbjacacacacafafaeaetRqJqJqJqJqJqJqJqJtStTqJqJqJqJqFaeaeaeaeaeafacacacacacwQxsxtxRwgwDxvwhwDwwzJxxxywhwDwgxzxAuVuVuVxBxCxCxCxCxCxCxCxDxDxDxDxDxDxDxuxuxuxEwWBQxGybxIxaxaxJxKxLxMxNvsaeaeaenlafafafoBoBoBoBoBoBafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafaeaevkvkvkvkvkxPxQyevkvkxSvkvkvkvkrCrKaeaeaeaeaepuaeaeaeaeafaeafafacacacacacacacacacacafafaeaeaepuaeaeaeaeaeaeaeaerCrKaeaeaeaepuaeaeaeaeaeafafnfafafacuEuEuEuEwgwDxTxUxVwyxWxXxXxYxYxZxXyayExXyEycycycycycycycycydydydydydydydyIyfyIygyfyhyiyjykylymynxcyoypxcrKaeaeaeaeafafafafoBoBoBoBoBafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafafaeaeaeaeaevkyqyrysytvknovtofaeaeaeaeaeqvaeaeaeqEqJqJqFaeaeaeaeafacacacacacacacacacacafaeaetRqJtQaeaeaeaeafaeaeqvaeaeaeaeaeaepuaeaeaeaeaeaeaevbaeafafafafafuEwgywyxyyyyyxyzyAyByyyyyCyxyDyVyVyVyFyFyFyFyFyFyFyFyGyGyGyGyGyGyHyXyXyXyJyKyLyMyNyOyPyOyOyOyOyOyOvuaeaeaeaenlafafafoBoBoBoBafafafafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacafafaeaeaeaevkyRySyTyUvkaeaeaeaeaeaeafafnfafaeaeaeaeaepuaeaeaeaeaeafacacacacacafafafafafaetRtQaeaeaeafafafafafafnfaeaeaeaeaeaepuaeaeaeaeaeaeaeaeaeaeaeafafuEuEwRAnwRuEuEyWAoyYuEuEuEyZwRuEuVaeaeaeaaaaaaaaagaaaaaaagaaaaaaaaaaagaaxuxuwWzazbzczdzezfBRzhziyOuvwaaeaeaeaeaeafafafoBoBoBoBafafafoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafafaeaeaevkvkvkvkvkvkaeaeafafafafafacacafafaeaeaeaepuaeaeaeaeaeaeafafafafafafaeaeaeaeaepuaeaeafafafacacacacacafaeaeaeaeaeaepuaeaeaerjrkaeaeaeaeaeaeaeafuEzkwAzmzluEzozpzqzrzsuEztzuzvuEaeaeaeaeaeaeaaaaagaaaaaaagagagagagagagagagwEzwzxzyzzzAzAzBzCzCzDzEwluLaeaeaeaeaeafafafoBoBoBafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafaeaeaeaeaeaeaeaeaeaeaeafacacacacacacacafafaeaeaeqEqJqJqJqFaeaeaeaeaeaeaeaeaeaeaeaeaepuaeafafacacacacacacacafafaeaeaeaeaeqEqJqJqJtStTqJqJqJqFaeaeaeaeuEzHzGzIznuEzKzLzLzMzNuEzOzPzQuEaeaeaeaeaeaeagagagagagagagaaaaaaaaaaagaaaawEzSzTzUzVzWzXzWzCzCzDzEwluLaeaeaeaeafafafafoBoBafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafaeaeaeaeaeaeaeaeaeafafafacacacacacacacacafafafaeaeaeaeaeqEqFaeaerjrkaeaetRqJqJqJqJqJtQaeafacacacacbjbjbjacacafafafaeaeaeaeaeaeaerCrKaeaeaepuaeaeaeaewPuEuEuEuEuEzZAaAbAczNuEuEAdwRwPaeaeaeaeaeaeaaaaagaaaaaaagaaaaaaaaaaagaawFwFAeAfAgyOAhAiAjAkzhziyOuWuZaeaeaeaeafafafoBoBoBafafafafoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafafafafaeaeaeaeafafafacacacacacacacacacacacacafafafaeqvaeaeqEqJqJtStTqJqJtQaeaeaeaeaeaeaeafacacacbjbjbjbjbjacacacafafafafaeaeaeaeaeaeaeaeaeqEqJqJqFaeaeaeaeaeaewPuEuEuEuEuEwPwlyuxOyvaeaeaeaeaeaaaaaaagaaaaaaagaaaaaaaaaaAowFApAqArAsAtwEAuAvAuAuAuAuAuAutraeaeaeafafafafoBoBafafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafaeaeaeaeaeaeaeaeaeafafafacacacacacacacacafafafaeaeaeaeaeqEqFaeaerjrkaeaetRqJqJqJqJqJtQaeafacacacacbjbjbjacacafafafaeaeaeaeaeaeaerCrKaeaeaepuaeaeaeaewPuEuEuEuEuEzZAaAbAczNuEuEAdwRwPaeaeaeaeaeaeaaaaagaaaaaaagaaaaaaaaaaagaaxuxuAeAfAgyOAhAiAjAkzhziyOuWuZaeaeaeaeafafafoBoBoBafafafafoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacafafafafaeaeaeaeafafafacacacacacacacacacacacacafafafaeqvaeaeqEqJqJtStTqJqJtQaeaeaeaeaeaeaeafacacacbjbjbjbjbjacacacafafafafaeaeaeaeaeaeaeaeaeqEqJqJqFaeaeaeaeaeaewPuEuEuEuEuEwPwlyuxOyvaeaeaeaeaeaaaaaaagaaaaaaagaaaaaaaaaaApxuAwAqArAsAtwEAuAvAuAuAuAuAuAutraeaeaeafafafafoBoBafafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacafafafafafafacacacacacacacacacacacacacacacacafafnfafaeaeaeaerCrKaeaeaeaeqvaeafafafafafacacbjbjbjbjbjbjbjacacacacacafafafafafafafafaeaeaeaeaepuaeaeaeaeaeaeaeaerCyQzjzjzjzjzFrKaeaeaeaeaeaeagagagagagagagagaaaaaaaahMhgwWBSwWwWAsADwEAEAFAGAHAIAJAKALaeaeaeaeafafafafoBoBafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacacbjbjbjbjbjbjacacacacacacafafaeaeaeaeaeaeaeaeaenfafafacacacacacbjbjbjbjbjbjbjbjacacacacacacacacacacacacafafaeaeaeaepuaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaaaaaaaaaaaaagaaaaaaaaaawFwFwFACwWANAOAPAQARASATAUAVAVALaeaeaeqKnfafafafoBafafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacbjbjbjbjbjbjbjbjbjbjbjacacacacacacafafafaeaeaeafafafafafacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacafaeaeaeaeqEqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqFaeaeaeaeaeaeaaaaaaaaaaagaaaaaaaaaaagaawFwFwWAsAXAYAZBaAVAVBbBbBcAuaeaeaeaeafafafafafafafafoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacacbjbjbjbjbjbjacacacacacacafafaeaeaeaeaeaeaeaeaenfafafacacacacacbjbjbjbjbjbjbjbjacacacacacacacacacacacacafafaeaeaeaepuaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaaaaaaaaaaaaagaaaaaaaaaaxuxuxuACwWANAOAPAQARASATAUAVAVALaeaeaeqKnfafafafoBafafafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacbjbjbjbjbjbjbjbjbjbjbjacacacacacacafafafaeaeaeafafafafafacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacafaeaeaeaeqEqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqJqFaeaeaeaeaeaeaaaaaaaaaaagaaaaaaaaaaagaaxuxuwWAsAXAYAZBaAVAVBbBbBcAuaeaeaeaeafafafafafafafafoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacbjacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacafafafafafacacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaepuaerjrkaeaeaenfnfaaaaaaagaaaaaaaaaaagaaaawEBdAszUBeAVAVAVBfBgBgBhALaeaeaeaeafafafafafoBafafoBoBoBafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacafafafaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeqEqJtStTqJqJqJAmAlBkBkBkBkBkBkBkBkBkBkBkBkBlBmBnBowEBpBqBrAVBsBsAVALaeaeaeafafafafoBoBoBafoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacacacacbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjbjacacacacacacafafafaeaeaeaeaeaeaeafafaeaeaeaeaeaeaeaeaerCrKaeaeaenfnfagaaaaaaaaaaaaaaaaaaaaaaBtBtBuBvBtAuAuAuALALALALAuaeaeafafafafoBoBoBoBoBoBoBafafafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index 5a0231c9394..e46ac1ef210 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -140,7 +140,7 @@ "cJ" = (/obj/item/stack/cable_coil/cut,/turf/space,/area/space) "cK" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) "cL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating,/area/derelict/bridge/access) -"cM" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) +"cM" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) "cN" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel,/area/derelict/bridge/access) "cO" = (/turf/simulated/wall/r_wall,/area/derelict/singularity_engine) "cP" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/derelict/bridge/access) @@ -243,7 +243,7 @@ "eI" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/access) "eJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/access) "eK" = (/obj/structure/girder,/turf/simulated/floor/plating/airless,/area/space) -"eL" = (/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/derelict/singularity_engine) +"eL" = (/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "eM" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "eN" = (/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/access) "eO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/access) @@ -254,7 +254,7 @@ "eT" = (/obj/item/stack/cable_coil/cut,/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) "eU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) "eV" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/derelict/singularity_engine) -"eW" = (/obj/item/stack/rods,/turf/simulated/floor/plasteel/airless{icon_state = "circuit"},/area/derelict/singularity_engine) +"eW" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "eX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/access) "eY" = (/turf/simulated/floor/plating/airless,/area/derelict/bridge/access) "eZ" = (/obj/structure/table,/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) @@ -564,7 +564,6 @@ "kS" = (/turf/simulated/wall/r_wall,/area/derelict/bridge/ai_upload) "kT" = (/obj/machinery/door/airlock/command{name = "AI Upload"; req_access_txt = "16"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/ai_upload) "kU" = (/obj/machinery/door/airlock/external{name = "Escape Airlock"},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) -"kV" = (/obj/machinery/door/firedoor{dir = 4; name = "Firelock East"},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) "kW" = (/obj/structure/window/basic{dir = 4},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) "kX" = (/obj/structure/window/basic{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/hallway/secondary) "kY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel/airless,/area/derelict/bridge/ai_upload) @@ -620,7 +619,7 @@ "lW" = (/obj/machinery/power/apc/noalarm{dir = 0; name = "Worn-out APC"; pixel_y = -24},/turf/simulated/floor/plasteel/airless,/area/derelict/teleporter) "lX" = (/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot) "lY" = (/turf/simulated/mineral,/area/syndicate_depot) -"lZ" = (/obj/structure/lattice,/obj/machinery/gun_turret/exterior,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot) +"lZ" = (/obj/structure/lattice,/obj/machinery/porta_turret/syndicate/exterior,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot) "ma" = (/turf/simulated/mineral/random,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_depot) "mb" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_depot) "mc" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; icon_state = "window5"; name = "window"; opacity = 0},/area/syndicate_depot) @@ -633,16 +632,16 @@ "mj" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mk" = (/obj/structure/closet/crate{name = "foot locker"},/obj/item/ammo_box/magazine/smgm45{pixel_x = 3},/obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate{pixel_x = -3; pixel_y = -2},/obj/item/weapon/lighter/zippo/gonzofist,/obj/item/clothing/under/syndicate{pixel_x = 3; pixel_y = 3},/obj/item/clothing/suit/armor/vest/combat{pixel_x = -3; pixel_y = -3},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "ml" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/unsimulated/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; dir = 8; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; name = "window"; opacity = 0; tag = "icon-window5_end (WEST)"},/area/syndicate_depot) -"mm" = (/obj/machinery/gun_turret/interior,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"mm" = (/obj/machinery/porta_turret/syndicate/interior,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mn" = (/obj/item/device/radio/intercom/syndicate{pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mo" = (/obj/machinery/space_heater,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mp" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/unsimulated/wall{desc = "This window appears to be reinforced, it looks nearly impossible to break."; dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; name = "window"; opacity = 0; tag = "icon-window5 (EAST)"},/area/syndicate_depot) "mq" = (/turf/simulated/mineral,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_depot) "mr" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_depot) -"ms" = (/obj/machinery/gun_turret/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = -27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"ms" = (/obj/machinery/porta_turret/syndicate/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = -27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mt" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/syndicake,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mu" = (/obj/machinery/gun_turret/grenade,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mv" = (/obj/machinery/gun_turret/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"mu" = (/obj/machinery/porta_turret/syndicate/grenade,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"mv" = (/obj/machinery/porta_turret/syndicate/interior{density = 0; desc = "Syndicate interior defense turret chambered for .45 rounds and mounted on a wall. Designed to down intruders without damaging the hull."; name = "wall mounted machine gun turret (.45)"; pixel_y = 27},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "mw" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_depot) "mx" = (/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) "my" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/syndicate_depot) @@ -767,7 +766,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackcncncscncncnckcAcncBckcncnckaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaeaeavavaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackcCcCcDcEcFckckcncncAckckcGckaaababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaAaaaaaeavavavcHaeaeaeaaaAaeaeaaaaaaaaaaaaaaaaaaaaaaaaaaaackcncncscncnckckcAcncncncncnckaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaAcIaeaecIavavavavavcIaeaecIaAaeaeaeaaaaaaaaaaaaaacJcJaAaAaAckcKcncLcncncMcNcncncncncncnckababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaAcIaeaecIavavavavavcIaeaecIaAaeaeaeaaaaaaaaaaaaaacJcJaAaAaAckcKcncLcncncGcNcncncncncncnckababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeaecOcOcOcOavcHavavavcOcOcOcOaeaeaeaeaeaaaaaaaaaaaaaaaacJaAaAckcPcQcRcPcPckckckckckckckckckcSabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaecOcOcOcOcTcOcUcOcVcWcXcOcOcOcOcOcOaeaeaaaaaaaaaacJaaaaaaaAaAaAckcncncscncncYcZdadbdcdddedbdfdgabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOcOcOdhdidjdkdhcWdldldmdldhdjdhcOcOcOaeaaaaaaaaaaaaaacJaaaaaaaackcKcncLcncncYdndndodndndndndpdqabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -824,7 +823,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaektknknknkuknknknknknknkvkwkxkykzkAkBkCknknknknknknknknknknknkDkEkFktknknkkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaektktktknknknknknknknknkGkHkIkJkKkLkMkNknknknknknknknknknknknklknknknknknkkaaaaaaaaaakiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaekOkPkQkQkQjWkQkQkQkQkQjWkQkQkQkQkQjWkQkQkQkQkQjWkQkQkQkQjWklktktknknknkRhxhxhxaaaaaahoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababababababababababbBabababababdDdDdDabababaAababababkSkTkSktknknktkUkVkWkXktaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababababababababababbBabababababdDdDdDabababaAababababkSkTkSktknknktkUcMkWkXktaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaaakSkYkSkZkZjYlajYlajYikikikaaaaaakiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPavavkSlblcldkSlelejYlfjYlfjYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeavkSlgkSlhliljljjYlfjYlfjYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/debug/smoothing.dmm b/_maps/map_files/debug/smoothing.dmm index 1ee9773589c..b9c65716db5 100644 --- a/_maps/map_files/debug/smoothing.dmm +++ b/_maps/map_files/debug/smoothing.dmm @@ -1,6 +1,6 @@ "a" = (/turf/simulated/floor/plating,/area/centcom) "b" = (/turf/simulated/floor/plating,/area/start) -"c" = (/turf/simulated/floor,/area/centcom) +"c" = (/turf/simulated/floor/plasteel,/area/centcom) "d" = (/turf/simulated/wall/mineral/alien,/area/centcom) "e" = (/obj/structure/falsewall/alien,/turf/simulated/floor/plating,/area/centcom) "f" = (/turf/simulated/wall/mineral/diamond,/area/centcom) diff --git a/_maps/map_files/shuttles/emergency_narnar.dmm b/_maps/map_files/shuttles/emergency_narnar.dmm index 537d0f5ba82..f36caa90e27 100644 --- a/_maps/map_files/shuttles/emergency_narnar.dmm +++ b/_maps/map_files/shuttles/emergency_narnar.dmm @@ -37,15 +37,15 @@ "aK" = (/obj/effect/rune,/mob/living/simple_animal/hostile/construct/wraith,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aL" = (/mob/living/simple_animal/hostile/construct/armoured,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aM" = (/obj/effect/decal/cleanable/blood/innards,/obj/effect/decal/cleanable/blood/gibs/body,/turf/simulated/floor/engine/cult,/area/shuttle/escape) -"aN" = (/mob/living/simple_animal/construct/wraith,/mob/living/simple_animal/hostile/construct/builder,/turf/simulated/floor/engine/cult,/area/shuttle/escape) -"aO" = (/mob/living/simple_animal/construct/builder,/mob/living/simple_animal/hostile/construct/behemoth,/turf/simulated/floor/engine/cult,/area/shuttle/escape) +"aN" = (/mob/living/simple_animal/hostile/construct/builder,/turf/simulated/floor/engine/cult,/area/shuttle/escape) +"aO" = (/mob/living/simple_animal/hostile/construct/behemoth,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aP" = (/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/extinguisher,/obj/item/weapon/crowbar,/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aQ" = (/obj/effect/decal/cleanable/blood/writing,/obj/effect/decal/cleanable/blood/writing,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aR" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/obj/effect/spawner/window/reinforced{color = "red"},/turf/simulated/wall/cult,/area/shuttle/escape) "aS" = (/obj/machinery/status_display{pixel_y = -30},/obj/machinery/light/spot,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aT" = (/obj/machinery/door/airlock/cult/friendly,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape) "aU" = (/obj/effect/spawner/window/reinforced{color = "red"},/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"; dir = 2},/area/shuttle/escape) -"aV" = (/mob/living/simple_animal/construct/armoured,/mob/living/simple_animal/hostile/construct/harvester,/turf/simulated/floor/engine/cult,/area/shuttle/escape) +"aV" = (/mob/living/simple_animal/hostile/construct/harvester,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aW" = (/obj/structure/dresser,/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aX" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/turf/simulated/floor/engine/cult,/area/shuttle/escape) "aY" = (/obj/effect/decal/cleanable/blood/tracks/footprints,/turf/simulated/floor/engine/cult,/area/shuttle/escape) diff --git a/_maps/map_files/templates/medium_shuttle1.dmm b/_maps/map_files/templates/medium_shuttle1.dmm index ee0c3ef5876..a39a70dcc5a 100644 --- a/_maps/map_files/templates/medium_shuttle1.dmm +++ b/_maps/map_files/templates/medium_shuttle1.dmm @@ -6,41 +6,61 @@ "f" = (/turf/simulated/shuttle/wall,/turf/simulated/shuttle/wall{tag = "icon-wall3 (SOUTHEAST)"; icon_state = "wall3"; dir = 6},/area/ruin/powered{name = "Shuttle"}) "g" = (/turf/simulated/shuttle/wall,/area/ruin/powered{name = "Shuttle"}) "h" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) -"i" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"i" = (/obj/machinery/power/smes/magical{name = "super smes"},/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "j" = (/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "k" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) -"l" = (/obj/machinery/door/airlock/glass,/turf/space,/area/ruin/powered{name = "Shuttle"}) +"l" = (/obj/structure/computerframe,/obj/item/weapon/circuitboard/teleporter,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "m" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) -"n" = (/obj/machinery/sleeper{tag = "icon-sleeper (NORTH)"; icon_state = "sleeper"; dir = 1},/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) +"n" = (/obj/structure/table,/obj/item/clothing/head/helmet/space/eva,/obj/item/clothing/suit/space/eva,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "o" = (/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "p" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "q" = (/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) "r" = (/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) "s" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) "t" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) -"u" = (/obj/machinery/power/smes/magical,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) +"u" = (/obj/machinery/teleport/hub,/obj/item/weapon/hand_tele,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "v" = (/turf/simulated/floor/plating,/turf/simulated/shuttle/wall{tag = "icon-window1"; icon_state = "window1"},/area/ruin/powered{name = "Shuttle"}) -"w" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/ruin/powered{name = "Shuttle"}) +"w" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "x" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/ruin/powered{name = "Shuttle"}) "y" = (/turf/simulated/shuttle/wall{tag = "icon-wall"; icon_state = "wall"},/area/ruin/powered{name = "Shuttle"}) "z" = (/obj/structure/shuttle/engine/propulsion/burst/right{tag = "icon-burst_r (EAST)"; icon_state = "burst_r"; dir = 4},/turf/space,/area/ruin/powered{name = "Shuttle"}) "A" = (/turf/simulated/shuttle/wall,/turf/simulated/shuttle/wall{tag = "icon-wall3 (NORTHEAST)"; icon_state = "wall3"; dir = 5},/area/ruin/powered{name = "Shuttle"}) "B" = (/turf/space,/turf/simulated/shuttle{tag = "icon-wall3 (SOUTHEAST)"; icon_state = "wall3"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"C" = (/obj/machinery/light{dir = 1},/obj/machinery/teleport/station,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"D" = (/obj/machinery/light,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"E" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"F" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"G" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"H" = (/obj/machinery/sleeper,/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) +"I" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/purple,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"J" = (/obj/machinery/vending/medical,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"K" = (/obj/machinery/light{dir = 4},/obj/machinery/vending/engivend,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"L" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) +"M" = (/obj/machinery/computer,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) +"N" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/electrical,/obj/item/clothing/gloves/color/yellow,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"O" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) +"P" = (/obj/machinery/light,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) +"Q" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility/full/multitool,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"R" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"S" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"T" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/space) +"U" = (/obj/structure/table/reinforced,/obj/machinery/recharger,/obj/item/weapon/gun/energy/laser/retro,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) (1,1,1) = {" aaabcdddeaaaaaaaaaaaaaa aaabcddddeaaaaaaaaaaaaa -aaabcfgggghhgiaaaaaaaaa -aaggggjjjgjjggiaaaaaaaa -aagjjkjjjglggggggggiaaa -ggggkggkggjjgmngjjggggi -hopoogjjjljjlqqljjlrrst -gogougjjjgvvgvvggggrrst -hopoogjjjljjljjljjlrrst -ggggkggkggjjgjjgjjggggw -aagjjkjjjglggggggggxaaa -aaygggjjjgjjggwaaaaaaaa -aaazcAgggghhgwaaaaaaaaa +aaabcfgggghhgTaaaaaaaaa +aagggglCugjjggGaaaaaaaa +aagNjkjSjgkggggggggGaaa +ggggkggkggjEgmHgJKggggG +hopOognjjkjjkqqkjjkrrUt +gogoignjwgvvgvvggggrLMt +hopPognjjkjjkjjkjjkrrst +ggggpggkggjFgIIgjwggggx +aagQjkjjRgkggggggggxaaa +aaygggjDjgjjggxaaaaaaaa +aaazcAgggghhgxaaaaaaaaa aaazcdddBaaaaaaaaaaaaaa aaazcddBaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/templates/medium_shuttle2.dmm b/_maps/map_files/templates/medium_shuttle2.dmm index 3aafdccbed8..b355e8e939b 100644 --- a/_maps/map_files/templates/medium_shuttle2.dmm +++ b/_maps/map_files/templates/medium_shuttle2.dmm @@ -6,13 +6,13 @@ "f" = (/obj/structure/shuttle/engine/propulsion/burst/right{tag = "icon-burst_r (EAST)"; icon_state = "burst_r"; dir = 4},/turf/space,/area/ruin/powered{name = "Shuttle"}) "g" = (/turf/simulated/shuttle/wall,/turf/simulated/shuttle{tag = "icon-wall3 (SOUTHEAST)"; icon_state = "wall3"; dir = 6},/area/ruin/powered{name = "Shuttle"}) "h" = (/turf/simulated/shuttle/wall,/area/ruin/powered{name = "Shuttle"}) -"i" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/space) +"i" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "j" = (/turf/space,/turf/simulated/shuttle{tag = "icon-wall3 (NORTHWEST)"; icon_state = "wall3"; dir = 9},/area/ruin/powered{name = "Shuttle"}) "k" = (/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "l" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "m" = (/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "n" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) -"o" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"o" = (/obj/machinery/light,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "p" = (/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) "q" = (/obj/machinery/door/airlock/glass,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "r" = (/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) @@ -23,26 +23,47 @@ "w" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) "x" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) "y" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) -"z" = (/obj/machinery/power/smes/magical,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) +"z" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plasteel,/area/ruin/powered{name = "Shuttle"}) "A" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) "B" = (/obj/structure/stool/bed/chair/comfy{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) "C" = (/turf/simulated/shuttle/wall,/turf/simulated/shuttle{tag = "icon-wall3 (NORTHEAST)"; icon_state = "wall3"; dir = 5},/area/ruin/powered{name = "Shuttle"}) -"D" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/ruin/powered{name = "Shuttle"}) -"E" = (/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/space) +"D" = (/obj/structure/computerframe,/obj/item/weapon/circuitboard/teleporter,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"E" = (/obj/machinery/teleport/hub,/obj/item/weapon/hand_tele,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) "F" = (/turf/space,/turf/simulated/shuttle{tag = "icon-wall3 (SOUTHEAST)"; icon_state = "wall3"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"G" = (/obj/item/device/radio/beacon,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"H" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"I" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/space) +"J" = (/obj/machinery/light{dir = 1},/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"K" = (/obj/machinery/light,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"L" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/space) +"M" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/purple,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"N" = (/obj/structure/table,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"O" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility/full/multitool,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"P" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/electrical,/obj/item/clothing/gloves/color/yellow,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"Q" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (SOUTHEAST)"; icon_state = "diagonalWall"; dir = 6},/area/ruin/powered{name = "Shuttle"}) +"R" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-diagonalWall (NORTHWEST)"; icon_state = "diagonalWall"; dir = 9},/area/ruin/powered{name = "Shuttle"}) +"S" = (/obj/structure/table/reinforced,/obj/machinery/recharger,/obj/item/weapon/gun/energy/laser/retro,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) +"T" = (/obj/structure/table,/obj/item/clothing/head/helmet/space/eva,/obj/item/clothing/suit/space/eva,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"U" = (/obj/machinery/teleport/station,/turf/simulated/floor/plasteel{tag = "icon-dark"; icon_state = "dark"},/area/ruin/powered{name = "Shuttle"}) +"V" = (/obj/machinery/power/smes/magical{name = "super smes"},/turf/simulated/floor/plating,/area/ruin/powered{name = "Shuttle"}) +"W" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-bluefull"; icon_state = "bluefull"},/area/ruin/powered{name = "Shuttle"}) +"X" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) +"Y" = (/obj/machinery/light,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) +"Z" = (/obj/machinery/computer,/turf/simulated/floor/plasteel{tag = "icon-whiteyellowfull"; icon_state = "whiteyellowfull"},/area/ruin/powered{name = "Shuttle"}) (1,1,1) = {" aaabcddddeaaaaaaaaaaaaaaaaaa -aaafcddghhhiaaaaaaaaaaaaaaaa -aaajdghhkkhhhhlhiaaaaaaaaaaa -bcdddhmnkknkkhkhhhhhhhhhhhoa -fcddghmhhhhkknknknppnkkqrrhh -aaashtmhhhhnhhhhkhuvhkkhrwxa -aaaaymmzhhhkhhhhkhAAhAAhBwxa -aaajhtmhhhhnhhhhkhkkhkkhrwxa -bcddChmhhhhkknknknkknkkqrrhh -fcdddhmnkknkkhkhhhhhhhhhhhDa -aaasdChhkkhhhhlhEaaaaaaaaaaa -aaabcddChhhEaaaaaaaaaaaaaaaa +aaafcddghhhIaaaaaaaaaaaaaaaa +aaajdghhTThhhhlhIaaaaaaaaaaa +bcdddhinkkhJHhkhhhhhhhhhhhQa +fcddghmhkknkknknknWpnkkqXrhh +aaashzmhDkhhhhhhkhuvhNNhrSxa +aaaaymmhUknkVhhhkhAAhAAhBZxa +aaajhtmhEGhhhhhhkhMMhPOhrwxa +bcddChmhkknkknknknKknkkqYrhh +fcdddhonkkhKkhkhhhhhhhhhhhRa +aaasdChhNNhhhhlhLaaaaaaaaaaa +aaabcddChhhLaaaaaaaaaaaaaaaa aaafcddddFaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/templates/small_shuttle_1.dmm b/_maps/map_files/templates/small_shuttle_1.dmm index ffb52eea1d0..98f9e53f4e2 100644 --- a/_maps/map_files/templates/small_shuttle_1.dmm +++ b/_maps/map_files/templates/small_shuttle_1.dmm @@ -1,33 +1,38 @@ -"a" = (/turf/space,/area/space) -"b" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"},/area/space) -"c" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/floor/plating/airless,/area/space) -"d" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"},/area/space) -"e" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"},/area/space) -"f" = (/turf/simulated/shuttle/floor,/area/space) -"g" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/space) -"h" = (/turf/simulated/shuttle/wall{tag = "icon-swall13"; icon_state = "swall13"},/area/space) -"i" = (/turf/simulated/shuttle/wall{tag = "icon-swall8"; icon_state = "swall8"},/area/space) -"j" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor,/area/space) -"k" = (/turf/simulated/shuttle/wall{tag = "icon-swall4"; icon_state = "swall4"},/area/space) -"l" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/space) -"m" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/space) -"n" = (/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plating/airless,/area/space) -"o" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"},/area/space) -"p" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"},/turf/simulated/floor/plating/airless,/area/space) -"q" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/floor/plating/airless,/area/space) -"r" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"},/turf/simulated/floor/plating/airless,/area/space) -"s" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"},/area/space) +"a" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"},/area/ruin/powered) +"b" = (/turf/space,/area/ruin/powered) +"c" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"},/area/ruin/powered) +"d" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor,/area/ruin/powered) +"e" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"},/area/ruin/powered) +"f" = (/turf/simulated/shuttle/wall{tag = "icon-swall8"; icon_state = "swall8"},/area/ruin/powered) +"g" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/floor/plating/airless,/area/ruin/powered) +"h" = (/turf/simulated/shuttle/floor,/area/ruin/powered) +"i" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/ruin/powered) +"j" = (/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plating/airless,/area/ruin/powered) +"k" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/floor/plating/airless,/area/ruin/powered) +"l" = (/turf/simulated/shuttle/wall{tag = "icon-swall13"; icon_state = "swall13"},/area/ruin/powered) +"m" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/ruin/powered) +"n" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor,/area/ruin/powered) +"o" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"},/turf/simulated/floor/plating/airless,/area/ruin/powered) +"p" = (/turf/simulated/shuttle/wall{tag = "icon-swall4"; icon_state = "swall4"},/area/ruin/powered) +"q" = (/obj/machinery/computer,/turf/simulated/shuttle/floor,/area/ruin/powered) +"r" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/ruin/powered) +"s" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"},/area/ruin/powered) +"t" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"},/area/ruin/powered) +"u" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/ruin/powered) +"v" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/shuttle/floor,/area/ruin/powered) +"w" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"},/turf/simulated/floor/plating/airless,/area/ruin/powered) (1,1,1) = {" -abcccda -aefgfea -aefffea -bhijkhd -elfffme -elfffme -jfffffj -jfffffj -efffffe -ennnnne -opqqqrs +bagggsb +bchrqcb +bcihicb +alfdpls +cmhhhuc +cmhhhuc +dhhhhhd +dhhhhhd +cnhhhvc +cjjjjjc +eokkkwt "} + diff --git a/_maps/map_files/templates/spacehotel/n_02.dmm b/_maps/map_files/templates/spacehotel/n_02.dmm index 9555b7a80e5..cda6eb42b4e 100644 --- a/_maps/map_files/templates/spacehotel/n_02.dmm +++ b/_maps/map_files/templates/spacehotel/n_02.dmm @@ -1,12 +1,12 @@ "a" = (/turf/template_noop,/area/template_noop) "b" = (/obj/effect/decal/cleanable/flour{desc = "Probably."},/obj/effect/decal/cleanable/pie_smudge,/turf/template_noop,/area/template_noop) -"c" = (/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/obj/item/weapon/bananapeel{layer = 2.6},/turf/template_noop,/area/template_noop) +"c" = (/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/obj/item/weapon/grown/bananapeel{layer = 2.6},/turf/template_noop,/area/template_noop) "d" = (/obj/structure/sign/poster{dir = 8; pixel_x = -32},/turf/unsimulated/floor/carpet,/area/template_noop) "e" = (/turf/unsimulated/floor/carpet,/area/template_noop) "f" = (/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/turf/unsimulated/floor/carpet,/area/template_noop) "g" = (/obj/structure/dresser,/turf/unsimulated/floor/carpet,/area/template_noop) -"h" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/obj/item/weapon/bananapeel/clownfish,/turf/unsimulated/floor/carpet,/area/template_noop) -"i" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/flour{desc = "Rather caked in there."},/obj/effect/decal/cleanable/pie_smudge,/obj/item/weapon/bananapeel/clownfish,/turf/unsimulated/floor/carpet,/area/template_noop) +"h" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/obj/item/weapon/grown/bananapeel/clownfish,/turf/unsimulated/floor/carpet,/area/template_noop) +"i" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/flour{desc = "Rather caked in there."},/obj/effect/decal/cleanable/pie_smudge,/obj/item/weapon/grown/bananapeel/clownfish,/turf/unsimulated/floor/carpet,/area/template_noop) "j" = (/obj/structure/window/reinforced/polarized{id = "room_n"},/turf/unsimulated/floor/carpet,/area/template_noop) "k" = (/obj/machinery/door/window/southright,/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/turf/unsimulated/floor/carpet,/area/template_noop) "l" = (/obj/effect/decal/cleanable/pie_smudge,/obj/effect/decal/cleanable/flour,/obj/structure/window/reinforced/polarized{id = "room_n"},/turf/unsimulated/floor/carpet,/area/template_noop) @@ -28,3 +28,4 @@ anopqra aaaaaaa aaaaaaa "} + diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index b6c5d55e5a9..a0f563669c1 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -7,29 +7,30 @@ icon_state = "circ1-off" var/side = CIRC_LEFT - + var/global/const/CIRC_LEFT = WEST var/global/const/CIRC_RIGHT = EAST var/last_pressure_delta = 0 - + var/obj/machinery/power/generator/generator layer = 2.45 // Just above wires - + anchored = 1 density = 1 - + can_unwrench = 1 - -// Creating a custom circulator pipe subtype to be delivered through cargo + var/side_inverted = 0 + +// Creating a custom circulator pipe subtype to be delivered through cargo /obj/item/pipe/circulator name = "circulator/heat exchanger fitting" /obj/item/pipe/circulator/New(loc) var/obj/machinery/atmospherics/binary/circulator/C = new /obj/machinery/atmospherics/binary/circulator(null) - ..(loc, make_from = C) - + ..(loc, make_from = C) + /obj/machinery/atmospherics/binary/circulator/Destroy() if(generator && generator.cold_circ == src) generator.cold_circ = null @@ -38,8 +39,10 @@ return ..() /obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air() - var/output_starting_pressure = air1.return_pressure() - var/input_starting_pressure = air2.return_pressure() + var/datum/gas_mixture/inlet = get_inlet_air() + var/datum/gas_mixture/outlet = get_outlet_air() + var/output_starting_pressure = outlet.return_pressure() + var/input_starting_pressure = inlet.return_pressure() if(output_starting_pressure >= input_starting_pressure - 10) //Need at least 10 KPa difference to overcome friction in the mechanism @@ -47,17 +50,17 @@ return null //Calculate necessary moles to transfer using PV = nRT - if(air2.temperature > 0) + if(inlet.temperature > 0) var/pressure_delta = (input_starting_pressure - output_starting_pressure) / 2 - var/transfer_moles = pressure_delta * air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) + var/transfer_moles = pressure_delta * outlet.volume/(inlet.temperature * R_IDEAL_GAS_EQUATION) last_pressure_delta = pressure_delta //log_debug("pressure_delta = [pressure_delta]; transfer_moles = [transfer_moles];") //Actually transfer the gas - var/datum/gas_mixture/removed = air2.remove(transfer_moles) + var/datum/gas_mixture/removed = inlet.remove(transfer_moles) parent1.update = 1 parent2.update = 1 @@ -71,6 +74,43 @@ ..() update_icon() +/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_air() + if(side_inverted==0) + return air2 + else + return air1 + +/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_air() + if(side_inverted==0) + return air1 + else + return air2 + +/obj/machinery/atmospherics/binary/circulator/proc/get_inlet_side() + if(dir==SOUTH||dir==NORTH) + if(side_inverted==0) + return "South" + else + return "North" + +/obj/machinery/atmospherics/binary/circulator/proc/get_outlet_side() + if(dir==SOUTH||dir==NORTH) + if(side_inverted==0) + return "North" + else + return "South" + +/obj/machinery/atmospherics/binary/circulator/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(ismultitool(W)) + if(side_inverted == 0) + side_inverted = 1 + else + side_inverted = 0 + to_chat(user, "You reverse the circulator's valve settings. The inlet of the circulator is now on the [get_inlet_side(dir)] side.") + desc = "A gas circulator pump and heat exchanger. Its input port is on the [get_inlet_side(dir)] side, and its output port is on the [get_outlet_side(dir)] side." + else + ..() + /obj/machinery/atmospherics/binary/circulator/update_icon() if(stat & (BROKEN|NOPOWER)) icon_state = "circ[side]-p" diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 6f8da094151..74293d6a807 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -10,6 +10,8 @@ name = "dual-port air vent" desc = "Has a valve and pump attached to it. There are two ports." + can_unwrench = 1 + level = 1 connect_types = list(1,2,3) //connects to regular, supply and scrubbers pipes diff --git a/code/__DEFINES/clothing.dm b/code/__DEFINES/clothing.dm index ec9ad2f2128..6e1934a77ae 100644 --- a/code/__DEFINES/clothing.dm +++ b/code/__DEFINES/clothing.dm @@ -32,7 +32,8 @@ #define slot_r_ear 20 #define slot_wear_pda 21 #define slot_tie 22 -#define slots_amt 22 +#define slot_collar 23 +#define slots_amt 23 //Cant seem to find a mob bitflags area other than the powers one diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 39074c65664..0bd2b82b42a 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -24,6 +24,7 @@ #define FIRELOSS 2 #define TOXLOSS 4 #define OXYLOSS 8 +#define SHAME 16 //Bitflags defining which status effects could be or are inflicted on a mob #define CANSTUN 1 diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 61bc32d378e..a4d9ca87384 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -24,8 +24,8 @@ #define BLOCK_GAS_SMOKE_EFFECT 8192 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! #define THICKMATERIAL 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with BLOCK_GAS_SMOKE_EFFECT) - -#define NOREACT 16384 //Reagents dont' react inside this container. +//Reagent flags +#define REAGENT_NOREACT 1 //Species flags. @@ -39,10 +39,10 @@ #define IS_PLANT 128 #define CAN_BE_FAT 256 #define NO_INTORGANS 512 -#define NO_POISON 1024 -#define RADIMMUNE 2048 -#define ALL_RPARTS 4096 -#define NOGUNS 8192 +#define RADIMMUNE 1024 +#define ALL_RPARTS 2048 +#define NOGUNS 4096 +#define NOTRANSSTING 8192 //Species clothing flags #define HAS_UNDERWEAR 1 diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index 11393957fc1..8e7be007d12 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -12,6 +12,7 @@ #define DISABILITY_FLAG_DEAF 8 #define DISABILITY_FLAG_BLIND 16 #define DISABILITY_FLAG_MUTE 32 +#define DISABILITY_FLAG_COLOURBLIND 64 /////////////////////////////////////// // MUTATIONS @@ -84,8 +85,9 @@ #define TOURETTES 8 #define NERVOUS 16 #define BLIND 32 -#define MUTE 64 -#define DEAF 128 +#define COLOURBLIND 64 +#define MUTE 128 +#define DEAF 256 //Nutrition levels for humans. No idea where else to put it #define NUTRITION_LEVEL_FAT 600 @@ -113,4 +115,4 @@ #define GENETIC_DAMAGE_STAGE_3 35 #define CLONER_FRESH_CLONE "fresh" -#define CLONER_MATURE_CLONE "mature" \ No newline at end of file +#define CLONER_MATURE_CLONE "mature" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 1d89eea87a1..6771d8062fc 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -25,6 +25,7 @@ #define PLANT_TOXIN_HUD "20"// Toxin level #define PLANT_PEST_HUD "21"// Pest level #define PLANT_WEED_HUD "22"// Weed level +#define DIAG_TRACK_HUD "23"// Mech tracking beacon //data HUD (medhud, sechud) defines //Don't forget to update human/New() if you change these! @@ -47,3 +48,8 @@ #define ANTAG_HUD_CHANGELING 15 #define ANTAG_HUD_VAMPIRE 16 #define ANTAG_HUD_ABDUCTOR 17 //For Fox + +// Notification action types +#define NOTIFY_JUMP "jump" +#define NOTIFY_ATTACK "attack" +#define NOTIFY_FOLLOW "orbit" \ No newline at end of file diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm new file mode 100644 index 00000000000..83db83c329c --- /dev/null +++ b/code/__DEFINES/inventory.dm @@ -0,0 +1,7 @@ +//ITEM INVENTORY WEIGHT, FOR w_class +#define WEIGHT_CLASS_TINY 1 //Usually items smaller then a human hand, ex: Playing Cards, Lighter, Scalpel, Coins/Money +#define WEIGHT_CLASS_SMALL 2 //Pockets can hold small and tiny items, ex: Flashlight, Multitool, Grenades, GPS Device +#define WEIGHT_CLASS_NORMAL 3 //Standard backpacks can carry tiny, small & normal items, ex: Fire extinguisher, Stunbaton, Gas Mask, Metal Sheets +#define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in an inventory, ex: Defibrillator, Backpack, Space Suits +#define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons +#define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe \ No newline at end of file diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 8e27f9315c3..a27e3f8e96a 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -1,5 +1,27 @@ +// Atoms #define isatom(A) istype(A, /atom) #define ismovableatom(A) istype(A, /atom/movable) -#define isclient(A) istype(A, /client) -#define isradio(A) istype(A, /obj/item/device/radio) \ No newline at end of file +// Mobs +#define ismegafauna(A) istype(A, /mob/living/simple_animal/hostile/megafauna) + +//Turfs +#define issimulatedturf(A) istype(A, /turf/simulated) + +#define isspaceturf(A) istype(A, /turf/space) + +#define isfloorturf(A) istype(A, /turf/simulated/floor) + +#define isunsimulatedturf(A) istype(A, /turf/unsimulated) + +#define iswallturf(A) istype(A, /turf/simulated/wall) + +#define isreinforcedwallturf(A) istype(A, /turf/simulated/wall/r_wall) + +#define ismineralturf(A) istype(A, /turf/simulated/mineral) + +// Misc +#define isclient(A) istype(A, /client) +#define isradio(A) istype(A, /obj/item/device/radio) +#define ispill(A) istype(A, /obj/item/weapon/reagent_containers/food/pill) + diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm new file mode 100644 index 00000000000..08a267322db --- /dev/null +++ b/code/__DEFINES/layers.dm @@ -0,0 +1,63 @@ +//Defines for atom layers and planes +//KEEP THESE IN A NICE ACSCENDING ORDER, PLEASE + +#define CLICKCATCHER_PLANE -99 + +#define PLANE_SPACE -95 +#define PLANE_SPACE_PARALLAX -90 + +#define GAME_PLANE 0 +//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define +#define MID_TURF_LAYER 2.02 +#define HIGH_TURF_LAYER 2.03 +#define ABOVE_OPEN_TURF_LAYER 2.04 +#define CLOSED_TURF_LAYER 2.05 +#define ABOVE_NORMAL_TURF_LAYER 2.08 +#define LATTICE_LAYER 2.2 +#define DISPOSAL_PIPE_LAYER 2.3 +#define GAS_PIPE_LAYER 2.35 +#define WIRE_LAYER 2.4 +#define WIRE_TERMINAL_LAYER 2.45 +#define LOW_OBJ_LAYER 2.5 + +#define BELOW_OPEN_DOOR_LAYER 2.6 +#define OPEN_DOOR_LAYER 2.7 +#define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible +#define TABLE_LAYER 2.8 +#define BELOW_OBJ_LAYER 2.9 +#define LOW_ITEM_LAYER 2.95 +//#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define +#define CLOSED_DOOR_LAYER 3.1 +#define CLOSED_FIREDOOR_LAYER 3.11 +#define ABOVE_OBJ_LAYER 3.2 +#define ABOVE_WINDOW_LAYER 3.3 +#define SIGN_LAYER 3.4 +#define NOT_HIGH_OBJ_LAYER 3.5 +#define HIGH_OBJ_LAYER 3.6 + +#define BELOW_MOB_LAYER 3.7 +#define LYING_MOB_LAYER 3.8 +//#define MOB_LAYER 4 //For easy recordkeeping; this is a byond define +#define ABOVE_MOB_LAYER 4.1 +#define WALL_OBJ_LAYER 4.25 +#define EDGED_TURF_LAYER 4.3 +#define ON_EDGED_TURF_LAYER 4.35 +#define LARGE_MOB_LAYER 4.4 +#define ABOVE_ALL_MOB_LAYER 4.5 + +#define SPACEVINE_LAYER 4.8 +#define SPACEVINE_MOB_LAYER 4.9 +//#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define +#define RIPPLE_LAYER 5.1 + +#define GHOST_LAYER 6 +#define AREA_LAYER 10 +#define MASSIVE_OBJ_LAYER 11 +#define POINT_LAYER 12 + +#define LIGHTING_PLANE 15 +#define LIGHTING_LAYER 15 + +//HUD layer defines +#define HUD_LAYER 19 +#define HUD_PLANE 90 \ No newline at end of file diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 7fbec83455a..c18fb516f4b 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -1,10 +1,43 @@ -#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process - #define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square #define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources #define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone #define LIGHTING_LAYER 10 // drawing layer for lighting overlays -#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects +#define LIGHTING_ICON 'icons/effects/lighting_overlay.png' // icon used for lighting shading effects #define LIGHTING_ROUND_VALUE (1 / 128) //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. + +#define LIGHTING_SOFT_THRESHOLD 0.05 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. + +// If I were you I'd leave this alone. +#define LIGHTING_BASE_MATRIX \ + list \ + ( \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + 0, 0, 0, 1 \ + ) \ + +// Helpers so we can (more easily) control the colour matrices. +#define CL_MATRIX_RR 1 +#define CL_MATRIX_RG 2 +#define CL_MATRIX_RB 3 +#define CL_MATRIX_RA 4 +#define CL_MATRIX_GR 5 +#define CL_MATRIX_GG 6 +#define CL_MATRIX_GB 7 +#define CL_MATRIX_GA 8 +#define CL_MATRIX_BR 9 +#define CL_MATRIX_BG 10 +#define CL_MATRIX_BB 11 +#define CL_MATRIX_BA 12 +#define CL_MATRIX_AR 13 +#define CL_MATRIX_AG 14 +#define CL_MATRIX_AB 15 +#define CL_MATRIX_AA 16 +#define CL_MATRIX_CR 17 +#define CL_MATRIX_CG 18 +#define CL_MATRIX_CB 19 +#define CL_MATRIX_CA 20 \ No newline at end of file diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 3153c180817..c95c3bb5b55 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -17,12 +17,13 @@ #define MINERAL_MATERIAL_AMOUNT 2000 //The amount of materials you get from a sheet of mineral like iron/diamond/glass etc -#define IMPRINTER 1 //For circuits. Uses glass/chemicals. -#define PROTOLATHE 2 //New stuff. Uses glass/metal/chemicals -#define AUTOLATHE 4 //Uses glass/metal only. -#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually. -#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars. -#define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab +#define IMPRINTER 1 //For circuits. Uses glass/chemicals. +#define PROTOLATHE 2 //New stuff. Uses glass/metal/chemicals +#define AUTOLATHE 4 //Uses glass/metal only. +#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually. +#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars. +#define PODFAB 32 //Used by the spacepod part fabricator. Same idea as the mechfab +#define BIOGENERATOR 64 //Uses biomass //Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable. #define HYDRO_SPEED_MULTIPLIER 1 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 5e9815b7758..b9f32e9b49a 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -17,6 +17,8 @@ #define CLICK_CD_TKSTRANGLE 10 #define CLICK_CD_POINT 10 #define CLICK_CD_RESIST 20 +#define CLICK_CD_CLICK_ABILITY 6 +#define CLICK_CD_RAPID 2 //Sizes of mobs, used by mob/living/var/mob_size #define MOB_SIZE_TINY 0 @@ -160,6 +162,7 @@ #define MAT_PLASMA "$plasma" #define MAT_BANANIUM "$bananium" #define MAT_TRANQUILLITE "$tranquillite" +#define MAT_BIOMASS "$biomass" #define MAX_STACK_SIZE 50 @@ -250,16 +253,19 @@ #define MAP_MAXZ 6 //Matricies -#define MATRIX_DEFAULT list(1, 0, 0, 0,\ - 0, 1, 0, 0,\ - 0, 0, 1, 0,\ - 0, 0, 0, 1) +#define MATRIX_GREYSCALE list(0.33, 0.33, 0.33,\ + 0.33, 0.33, 0.33,\ + 0.33, 0.33, 0.33) + +#define MATRIX_VULP_CBLIND list(0.5,0.4,0.1,\ + 0.5,0.4,0.1,\ + 0.0,0.2,0.8) + +#define MATRIX_TAJ_CBLIND list(0.4,0.2,0.4,\ + 0.4,0.6,0.0,\ + 0.2,0.2,0.6) + -#define MATRIX_GREYSCALE list(0.33, 0.33, 0.33, 0,\ - 0.33, 0.33, 0.33, 0,\ - 0.33, 0.33, 0.33, 0,\ - 0.00, 0.00, 0.00, 1,\ - 0.00, 0.00, 0.00, 0) //Gun trigger guards #define TRIGGER_GUARD_ALLOW_ALL -1 #define TRIGGER_GUARD_NONE 0 @@ -285,7 +291,6 @@ #define SOUND_MINIMUM_PRESSURE 10 #define FALLOFF_SOUNDS 0.5 - // Bluespace shelter deploy checks #define SHELTER_DEPLOY_ALLOWED "allowed" #define SHELTER_DEPLOY_BAD_TURFS "bad turfs" @@ -299,3 +304,16 @@ // The cooldown on OOC messages such as OOC, LOOC, praying and adminhelps #define OOC_COOLDOWN 5 + +// Medal names +#define BOSS_KILL_MEDAL "Killer" +#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type + +// Score names +#define LEGION_SCORE "Legion Killed" +#define COLOSSUS_SCORE "Colossus Killed" +#define BUBBLEGUM_SCORE "Bubblegum Killed" +#define DRAKE_SCORE "Drakes Killed" +#define BIRD_SCORE "Hierophants Killed" +#define BOSS_SCORE "Bosses Killed" +#define TENDRIL_CLEAR_SCORE "Tendrils Killed" \ No newline at end of file diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm index b623ce72158..492918be671 100644 --- a/code/__DEFINES/qdel.dm +++ b/code/__DEFINES/qdel.dm @@ -4,8 +4,7 @@ #define QDEL_HINT_LETMELIVE 1 //qdel should let the object live after calling destory. #define QDEL_HINT_IWILLGC 2 //functionally the same as the above. qdel should assume the object will gc on its own, and not check it. #define QDEL_HINT_HARDDEL_NOW 4 //qdel should assume this object won't gc, and hard del it post haste. -#define QDEL_HINT_PUTINPOOL 5 //qdel will put this object in the atom pool. -#define QDEL_HINT_FINDREFERENCE 6 //functionally identical to QDEL_HINT_QUEUE if TESTING is not enabled in _compiler_options.dm. +#define QDEL_HINT_FINDREFERENCE 5 //functionally identical to QDEL_HINT_QUEUE if TESTING is not enabled in _compiler_options.dm. //if TESTING is enabled, qdel will call this object's find_references() verb. // A convenient wrapper around checking for qdeletion/non-existence diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm new file mode 100644 index 00000000000..3e81a67b1b2 --- /dev/null +++ b/code/__DEFINES/reagents.dm @@ -0,0 +1,3 @@ +#define SOLID 1 +#define LIQUID 2 +#define GAS 3 \ No newline at end of file diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 1c99c8d970c..667c7152e85 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -37,6 +37,7 @@ #define ROLE_MORPH "morph" #define ROLE_ERT "emergency response team" #define ROLE_NYMPH "Dionaea" +#define ROLE_GSPIDER "giant spider" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. @@ -69,4 +70,5 @@ var/global/list/special_roles = list( ROLE_GUARDIAN, ROLE_MORPH, ROLE_TRADER, + ROLE_GSPIDER, ) diff --git a/code/__DEFINES/rolebans.dm b/code/__DEFINES/rolebans.dm index dba57111150..b2eb79e26be 100644 --- a/code/__DEFINES/rolebans.dm +++ b/code/__DEFINES/rolebans.dm @@ -17,6 +17,7 @@ var/global/list/antag_roles = list( ROLE_REVENANT, ROLE_GUARDIAN, ROLE_MORPH, + ROLE_GSPIDER, ) // Bannable other roles @@ -26,4 +27,4 @@ var/global/list/other_roles = list( ROLE_ERT, "AntagHUD", "Records" -) \ No newline at end of file +) diff --git a/code/__HELPERS/AnimationLibrary.dm b/code/__HELPERS/AnimationLibrary.dm index fcabe2e0a78..fd79fe197f2 100644 --- a/code/__HELPERS/AnimationLibrary.dm +++ b/code/__HELPERS/AnimationLibrary.dm @@ -7,7 +7,7 @@ /proc/animate_fade_grayscale(var/atom/A, var/time = 5) if(!istype(A) && !istype(A, /client)) return - A.color = MATRIX_DEFAULT + A.color = null animate(A, color = MATRIX_GREYSCALE, time = time, easing = SINE_EASING) /proc/animate_melt_pixel(var/atom/A) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index d22e70d4fc4..c6f0e9bf1c9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -151,7 +151,7 @@ // The old system would loop through lists for a total of 5000 per function call, in an empty server. // This new system will loop at around 1000 in an empty server. -/proc/get_mobs_in_view(var/R, var/atom/source) +/proc/get_mobs_in_view(var/R, var/atom/source, var/include_clientless = FALSE) // Returns a list of mobs in range of R from source. Used in radio and say code. var/turf/T = get_turf(source) @@ -165,7 +165,7 @@ for(var/atom/A in range) if(ismob(A)) var/mob/M = A - if(M.client) + if(M.client || include_clientless) hear += M //log_to_dd("Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])") else if(istype(A, /obj/item/device/radio)) @@ -412,13 +412,30 @@ return 0 return 1 + +/proc/GetRedPart(const/hexa) + return hex2num(copytext(hexa, 2, 4)) + +/proc/GetGreenPart(const/hexa) + return hex2num(copytext(hexa, 4, 6)) + +/proc/GetBluePart(const/hexa) + return hex2num(copytext(hexa, 6, 8)) + +/proc/GetHexColors(const/hexa) + return list( + GetRedPart(hexa), + GetGreenPart(hexa), + GetBluePart(hexa), + ) + /proc/MinutesToTicks(var/minutes as num) return minutes * 60 * 10 /proc/SecondsToTicks(var/seconds) return seconds * 10 -proc/pollCandidates(var/Question, var/be_special_type, var/antag_age_check = 0, var/poll_time = 300, var/ignore_respawnability = 0) +proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE) var/roletext = be_special_type ? get_roletext(be_special_type) : null var/list/mob/dead/observer/candidates = list() var/time_passed = world.time @@ -437,11 +454,15 @@ proc/pollCandidates(var/Question, var/be_special_type, var/antag_age_check = 0, if(roletext) if(jobban_isbanned(G, roletext) || jobban_isbanned(G, "Syndicate")) continue + if(min_hours) + if(G.client.get_exp_living_num() < min_hours * 60) + continue if(G.has_enabled_antagHUD) continue spawn(0) G << 'sound/misc/notice2.ogg'//Alerting them to their consideration - + if(flashwindow) + window_flash(G.client) switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Not This Round")) if("Yes") to_chat(G, "Choice registered: Yes.") @@ -468,3 +489,12 @@ proc/pollCandidates(var/Question, var/be_special_type, var/antag_age_check = 0, candidates.Remove(G) return candidates + +/proc/window_flash(client/C) + if(ismob(C)) + var/mob/M = C + if(M.client) + C = M.client + if(!C || !C.prefs.windowflashing) + return + winset(C, "mainwindow", "flash=5") \ No newline at end of file diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 5d5307cd50d..cfe37505e1c 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -884,3 +884,9 @@ proc/sort_atoms_by_layer(var/list/atoms) icon = J return J return 0 + +//Hook, override to run code on- wait this is images +//Images have dir without being an atom, so they get their own definition. +//Lame. +/image/proc/setDir(newdir) + dir = newdir diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index f54726c4161..9fa27c93356 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -72,6 +72,14 @@ return 0 return L[A.type] +//returns a new list with only atoms that are in typecache L +/proc/typecache_filter_list(list/atoms, list/typecache) + . = list() + for (var/thing in atoms) + var/atom/A = thing + if(typecache[A.type]) + . += A + //Like typesof() or subtypesof(), but returns a typecache instead of a list /proc/typecacheof(path, ignore_root_path) if(ispath(path)) diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 986cbac0bd3..b0312d44134 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -56,6 +56,16 @@ var/const/Sqrt2 = 1.41421356 var/t = Floor((val - min) / d) return val - (t * d) +//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher). +//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions. +/proc/TransformUsingVariable(input, inputmaximum, scaling_modifier = 0) + + var/inputToDegrees = (input/inputmaximum)*180 //Converting from a 0 -> 100 scale to a 0 -> 180 scale. The 0 -> 180 scale corresponds to degrees + var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1 + + return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5 + //world<< "Transform multiplier of [src] is [size_factor + scaling_modifer]" + /proc/RaiseToPower(num, power) if(!power) return 1 return (power-- > 1 ? num * RaiseToPower(num, power) : num) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index a2e8542b825..40cc0edbbd5 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -249,20 +249,23 @@ Proc for attack log creation, because really why not 6 is whether the attack should be logged to the log file and shown to admins */ -proc/add_logs(mob/user, mob/target, what_done, var/object=null, var/addition=null, var/admin=1) - var/list/ignore=list("shaked","CPRed","grabbed","punched") +proc/add_logs(mob/user, mob/target, what_done, var/object=null, var/addition=null, var/admin=1, var/print_attack_log = 1)//print_attack_log notifies admins with attack logs on + var/list/ignore=list("shaked", "CPRed", "grabbed", "punched", "disarmed") if(!user) return if(ismob(user)) - user.attack_log += text("\[[time_stamp()]\] Has [what_done] [key_name(target)][object ? " with [object]" : " "][addition]") + user.create_attack_log("Has [what_done] [key_name(target)][object ? " with [object]" : " "][addition]") if(ismob(target)) - target.attack_log += text("\[[time_stamp()]\] Has been [what_done] by [key_name(user)][object ? " with [object]" : " "][addition]") + target.create_attack_log("Has been [what_done] by [key_name(user)][object ? " with [object]" : " "][addition]") if(admin) log_attack("[key_name(user)] [what_done] [key_name(target)][object ? " with [object]" : " "][addition]") - if(istype(target) && (target.client || target.player_logged)) - if(what_done in ignore) return - if(target == user)return - if(!admin) return + if(istype(target) && (target.key)) + if(what_done in ignore) + return + if(target == user) + return + if(!print_attack_log) + return msg_admin_attack("[key_name_admin(user)] [what_done] [key_name_admin(target)][object ? " with [object]" : " "][addition]") /proc/do_mob(var/mob/user, var/mob/target, var/time = 30, var/uninterruptible = 0, progress = 1) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index d5b75eb4c7c..4c6abbd7d0b 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -431,3 +431,17 @@ proc/checkhtml(var/t) text = copytext(text, 1, index) + repl_chars[char] + copytext(text, index+keylength) index = findtext(text, char) return text + +//Checks if any of a given list of needles is in the haystack +/proc/text_in_list(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtext(haystack, needle, start, end)) + return 1 + return 0 + +//Like above, but case sensitive +/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtextEx(haystack, needle, start, end)) + return 1 + return 0 diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9f0319c84af..930e8244eb6 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1,4 +1,3 @@ - //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 /* @@ -326,7 +325,7 @@ Turf and target are seperate in case you want to teleport some distance from a t var/mob/M = old_list[named] if(issilicon(M)) AI_list |= M - else if(isobserver(M) || M.stat == 2) + else if(isobserver(M) || M.stat == DEAD) Dead_list |= M else if(M.key && M.client) keyclient_list |= M @@ -360,7 +359,7 @@ Turf and target are seperate in case you want to teleport some distance from a t namecounts[name] = 1 if(M.real_name && M.real_name != M.name) name += " \[[M.real_name]\]" - if(M.stat == 2) + if(M.stat == DEAD) if(istype(M, /mob/dead/observer/)) name += " \[ghost\]" else @@ -550,15 +549,21 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl /proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. var/turf/current = get_turf(source) var/turf/target_turf = get_turf(target) - var/steps = 0 - - while(current != target_turf) - if(steps > length) return 0 - if(current.opacity) return 0 - for(var/atom/A in current) - if(A.opacity) return 0 - current = get_step_towards(current, target_turf) - steps++ + var/steps = 1 + + if(current != target_turf) + current = get_step_towards(current, target_turf) + while(current != target_turf) + if(steps > length) + return 0 + if(current.opacity) + return 0 + for(var/thing in current) + var/atom/A = thing + if(A.opacity) + return 0 + current = get_step_towards(current, target_turf) + steps++ return 1 @@ -1009,7 +1014,7 @@ proc/get_mob_with_client_list() else if(zone == "l_foot") return "left foot" else if(zone == "r_foot") return "right foot" else return zone - + /* Gets the turf this atom's *ICON* appears to inhabit @@ -1222,7 +1227,7 @@ var/global/list/common_tools = list( //check if mob is lying down on something we can operate him on. /proc/can_operate(mob/living/carbon/M) - return (locate(/obj/machinery/optable, M.loc) && M.resting) || \ + return (locate(/obj/machinery/optable, M.loc) && (M.lying || M.resting)) || \ (locate(/obj/structure/stool/bed/roller, M.loc) && \ (M.buckled || M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) && prob(75) || \ (locate(/obj/structure/table/, M.loc) && \ @@ -1558,7 +1563,7 @@ var/mob/dview/dview_mob = new //pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts //lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts) -/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE) +/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE, forceMove = FALSE) if(!istype(A)) return @@ -1590,7 +1595,10 @@ var/mob/dview/dview_mob = new var/targetloc = get_turf(A) if(!lockinorbit && loc != lastloc && loc != targetloc) break - loc = targetloc + if(forceMove) + forceMove(targetloc) + else + loc = targetloc lastloc = loc sleep(0.6) @@ -1812,6 +1820,70 @@ var/global/list/g_fancy_list_of_types = null //you might be thinking of adding more steps to this, or making it use a loop and a counter var // not worth it. +// This proc gets a list of all "points of interest" (poi's) that can be used by admins to track valuable mobs or atoms (such as the nuke disk). +/proc/getpois(mobs_only=0,skip_mindless=0) + var/list/mobs = sortmobs() + var/list/names = list() + var/list/pois = list() + var/list/namecounts = list() + + for(var/mob/M in mobs) + if(skip_mindless && (!M.mind && !M.ckey)) + if(!isbot(M) && !istype(M, /mob/camera/)) + continue + if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins + continue + var/name = M.name + if(name in names) + namecounts[name]++ + name = "[name] ([namecounts[name]])" + else + names.Add(name) + namecounts[name] = 1 + if(M.real_name && M.real_name != M.name) + name += " \[[M.real_name]\]" + if(M.stat == DEAD) + if(istype(M, /mob/dead/observer/)) + name += " \[ghost\]" + else + name += " \[dead\]" + pois[name] = M + + if(!mobs_only) + for(var/atom/A in poi_list) + if(!A || !A.loc) + continue + var/name = A.name + if(names.Find(name)) + namecounts[name]++ + name = "[name] ([namecounts[name]])" + else + names.Add(name) + namecounts[name] = 1 + pois[name] = A + + return pois + +/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20) + var/client/C + if(istype(mob_or_client, /mob)) + var/mob/M = mob_or_client + if(M.client) + C = M.client + else + return + else if(istype(mob_or_client, /client)) + C = mob_or_client + + if(!istype(C)) + return + + C.color = flash_color + spawn(0) + animate(C, color = initial(C.color), time = flash_time) + +#define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255))) + /proc/make_bit_triplet() var/list/num_sample = list(1, 2, 3, 4, 5, 6, 7, 8, 9) var/result = 0 @@ -1819,4 +1891,4 @@ var/global/list/g_fancy_list_of_types = null var/num = pick(num_sample) num_sample -= num result += (1 << num) - return result \ No newline at end of file + return result diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 5b41171d557..3e2d7d995d6 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -36,3 +36,8 @@ var/eventchance = 10 //% per 5 mins var/event = 0 var/hadevent = 0 var/blobevent = 0 + +//Medals hub related variables +var/global/medal_hub = null +var/global/medal_pass = " " +var/global/medals_enabled = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. \ No newline at end of file diff --git a/code/_globalvars/genetics.dm b/code/_globalvars/genetics.dm index 73b2b7304f6..116aa0797cb 100644 --- a/code/_globalvars/genetics.dm +++ b/code/_globalvars/genetics.dm @@ -1,5 +1,6 @@ /////////// var/BLINDBLOCK = 0 +var/COLOURBLINDBLOCK = 0 var/DEAFBLOCK = 0 var/HULKBLOCK = 0 var/TELEBLOCK = 0 diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm index 4cdc0bef33d..eb5c500573b 100644 --- a/code/_globalvars/lists/misc.dm +++ b/code/_globalvars/lists/misc.dm @@ -19,3 +19,5 @@ var/list/restricted_camera_networks = list( //Those networks can only be accesse ) var/list/mineral_turfs = list() + +var/list/ruin_landmarks = list() \ No newline at end of file diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index e85ba6a12cf..be703845fb3 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -8,6 +8,7 @@ var/list/first_names_male = file2list("config/names/first_male.txt") var/list/first_names_female = file2list("config/names/first_female.txt") var/list/last_names = file2list("config/names/last.txt") var/list/clown_names = file2list("config/names/clown.txt") +var/list/mime_names = file2list("config/names/mime.txt") var/list/diona_names = file2list ("config/names/diona.txt") var/list/verbs = file2list("config/names/verbs.txt") diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 091ecd40dbb..6733f43b050 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -34,4 +34,9 @@ var/global/list/shuttle_caller_list = list() //list of all communication cons var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once. var/global/list/abductor_equipment = list() //list of all abductor equipment -var/global/list/global_intercoms = list() //list of all intercomms, across all z-levels \ No newline at end of file + + +var/global/list/global_intercoms = list() //list of all intercomms, across all z-levels +var/global/list/global_radios = list() //list of all radios, across all z-levels + +var/global/list/poi_list = list() //list of points of interest for observe/follow \ No newline at end of file diff --git a/code/_globalvars/mapping.dm b/code/_globalvars/mapping.dm index dfecea02531..841fbced3f7 100644 --- a/code/_globalvars/mapping.dm +++ b/code/_globalvars/mapping.dm @@ -49,6 +49,6 @@ var/list/datum/map_template/map_templates = list() var/list/datum/map_template/ruins_templates = list() var/list/datum/map_template/space_ruins_templates = list() -//var/list/datum/map_template/lava_ruins_templates = list() +var/list/datum/map_template/lava_ruins_templates = list() var/list/datum/map_template/shelter_templates = list() var/list/datum/map_template/shuttle_templates = list() \ No newline at end of file diff --git a/code/_globalvars/unused.dm b/code/_globalvars/unused.dm index e55794c3dc9..3925ea1237e 100644 --- a/code/_globalvars/unused.dm +++ b/code/_globalvars/unused.dm @@ -7,7 +7,7 @@ var/datum/debug/debugobj var/list/liftable_structures = list(\ /obj/machinery/autolathe, \ /obj/machinery/constructable_frame, \ - /obj/machinery/portable_atmospherics/hydroponics, \ + /obj/machinery/hydroponics, \ /obj/machinery/computer, \ /obj/machinery/optable, \ /obj/structure/dispenser, \ diff --git a/code/_onclick/_defines.dm b/code/_onclick/_defines.dm deleted file mode 100644 index a02a1f43590..00000000000 --- a/code/_onclick/_defines.dm +++ /dev/null @@ -1,3 +0,0 @@ -#define CLICKCATCHER_PLANE -99 - -#define HUD_PLANE 90 \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 66377ec3fcd..58928da83e0 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -95,9 +95,9 @@ update_inv_r_hand(0) return - // operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src) + // operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper) var/sdepth = A.storage_depth(src) - if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1)) + if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 2)) // No adjacency needed if(W) var/resolved = A.attackby(W,src) @@ -323,16 +323,6 @@ // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(var/atom/A) - -/* // Snowflake for space vines. //Are you fucking kidding me? - var/is_buckled = 0 - if(buckled) - if(istype(buckled)) - if(!buckled.movable) - is_buckled = 1 - else - is_buckled = 0*/ - if( stat || buckled || !A || !x || !y || !A.x || !A.y ) return var/dx = A.x - x var/dy = A.y - y @@ -345,11 +335,7 @@ else if(dx > 0) direction = EAST else direction = WEST - usr.dir = direction - -/* if(buckled && buckled.movable) - buckled.dir = direction - buckled.handle_rotation()*/ + dir = direction /obj/screen/click_catcher icon = 'icons/mob/screen_full.dmi' diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 57224a5b4a3..a20efc98a06 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -143,6 +143,21 @@ The box in your backpack has an oxygen tank and gas mask in it." desc = "You ate too much food, lardass. Run around the station and lose some weight." icon_state = "fat" +/obj/screen/alert/full + name = "Full" + desc = "You feel full and satisfied, but you shouldn't eat much more." + icon_state = "full" + +/obj/screen/alert/well_fed + name = "Well Fed" + desc = "You feel quite satisfied, but you may be able to eat a bit more." + icon_state = "well_fed" + +/obj/screen/alert/fed + name = "Fed" + desc = "You feel moderately satisfied, but a bit more food may not hurt." + icon_state = "fed" + /obj/screen/alert/hungry name = "Hungry" desc = "Some food would be good right about now." @@ -182,6 +197,16 @@ The box in your backpack has an oxygen tank and gas mask in it." name = "High Pressure" desc = "The air around you is hazardously thick. A fire suit would protect you." icon_state = "highpressure" + +/obj/screen/alert/lightexposure + name = "Light Exposure" + desc = "You're exposed to light." + icon_state = "lightexposure" + +/obj/screen/alert/nolight + name = "No Light" + desc = "You're not exposed to any light." + icon_state = "nolight" /obj/screen/alert/blind name = "Blind" @@ -334,25 +359,28 @@ so as to remain in compliance with the most up-to-date laws." var/mob/dead/observer/G = usr G.reenter_corpse() -/obj/screen/alert/notify_jump +/obj/screen/alert/notify_action name = "Body created" desc = "A body was created. You can enter it." icon_state = "template" timeout = 300 - var/atom/jump_target = null - var/attack_not_jump = null + var/atom/target = null + var/action = NOTIFY_JUMP -/obj/screen/alert/notify_jump/Click() +/obj/screen/alert/notify_action/Click() if(!usr || !usr.client) return - if(!jump_target) return + if(!target) return var/mob/dead/observer/G = usr if(!istype(G)) return - if(attack_not_jump) - jump_target.attack_ghost(G) - else - var/turf/T = get_turf(jump_target) - if(T && isturf(T)) - G.loc = T + switch(action) + if(NOTIFY_ATTACK) + target.attack_ghost(G) + if(NOTIFY_JUMP) + var/turf/T = get_turf(target) + if(T && isturf(T)) + G.loc = T + if(NOTIFY_FOLLOW) + G.ManualFollow(target) //OBJECT-BASED diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1077e2fde8a..46368def984 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -65,8 +65,7 @@ ///////////////////////// user.lastattacked = M M.lastattacker = user - - add_logs(user, M, "attacked", name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])") + add_logs(user, M, "attacked", name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])", print_attack_log = (force > 0))//print it if stuff deals damage if(!iscarbon(user)) M.LAssailant = null @@ -75,7 +74,9 @@ ///////////////////////// - if(istype(M, /mob/living/simple_animal)) + if(isanimal(M)) + var/mob/living/simple_animal/S = M + S.attacked_by(src, user) return 0 // No sanic-speed double-attacks for you - simple mobs will handle being attacked on their own var/power = force diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 1b294b38ae8..ea9de45f295 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -4,16 +4,16 @@ Otherwise pretty standard. */ -/mob/living/carbon/human/UnarmedAttack(var/atom/A, var/proximity) - var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines - +/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) // Special glove functions: // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. - if(proximity && istype(G) && G.Touch(A,1)) + var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines + if(proximity && istype(G) && G.Touch(A, 1)) return A.attack_hand(src) + /atom/proc/attack_hand(mob/user as mob) return diff --git a/code/controllers/Processes/lighting.dm b/code/controllers/Processes/lighting.dm index 7d463abbd7f..15b134ecf44 100644 --- a/code/controllers/Processes/lighting.dm +++ b/code/controllers/Processes/lighting.dm @@ -1,18 +1,91 @@ -var/global/datum/controller/process/lighting/lighting_controller +// Solves problems with lighting updates lagging shit +// Max constraints on number of updates per doWork(): +#define MAX_LIGHT_UPDATES_PER_WORK 100 +#define MAX_CORNER_UPDATES_PER_WORK 1000 +#define MAX_OVERLAY_UPDATES_PER_WORK 2000 +/var/lighting_overlays_initialised = FALSE + +/var/list/lighting_update_lights = list() // List of lighting sources queued for update. +/var/list/lighting_update_corners = list() // List of lighting corners queued for update. +/var/list/lighting_update_overlays = list() // List of lighting overlays queued for update. + +/var/list/lighting_update_lights_old = list() // List of lighting sources currently being updated. +/var/list/lighting_update_corners_old = list() // List of lighting corners currently being updated. +/var/list/lighting_update_overlays_old = list() // List of lighting overlays currently being updated. + + +/datum/controller/process/lighting /datum/controller/process/lighting/setup() name = "lighting" - schedule_interval = LIGHTING_INTERVAL - start_delay = 1 - lighting_controller = src - create_lighting_overlays() + schedule_interval = world.tick_lag // run as fast as you possibly can + create_all_lighting_overlays() + lighting_overlays_initialised = TRUE + // Pre-process lighting once before the round starts. Wait 30 seconds so the away mission has time to load. spawn(300) - doWork() + doWork(1) -/datum/controller/process/lighting/statProcess() - ..() - stat(null, "[last_light_count] lights, [last_overlay_count] overlays") +/datum/controller/process/lighting/doWork(roundstart) + // Counters + var/light_updates = 0 + var/corner_updates = 0 + var/overlay_updates = 0 -// Lighting process code located in modules\lighting\lighting_process.dm \ No newline at end of file + lighting_update_lights_old = lighting_update_lights //We use a different list so any additions to the update lists during a delay from scheck() don't cause things to be cut from the list without being updated. + lighting_update_lights = list() + for(var/datum/light_source/L in lighting_update_lights_old) + if(light_updates >= MAX_LIGHT_UPDATES_PER_WORK && !roundstart) + lighting_update_lights += L + continue // DON'T break, we're adding stuff back into the update queue. + + if(L.check() || L.destroyed || L.force_update) + L.remove_lum() + if(!L.destroyed) + L.apply_lum() + + else if(L.vis_update) //We smartly update only tiles that became (in) visible to use. + L.smart_vis_update() + + L.vis_update = FALSE + L.force_update = FALSE + L.needs_update = FALSE + + light_updates++ + + SCHECK + + lighting_update_corners_old = lighting_update_corners //Same as above. + lighting_update_corners = list() + for(var/A in lighting_update_corners_old) + if(corner_updates >= MAX_CORNER_UPDATES_PER_WORK && !roundstart) + lighting_update_corners += A + continue // DON'T break, we're adding stuff back into the update queue. + + var/datum/lighting_corner/C = A + + C.update_overlays() + + C.needs_update = FALSE + + corner_updates++ + + SCHECK + + lighting_update_overlays_old = lighting_update_overlays //Same as above. + lighting_update_overlays = list() + + for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old) + if(overlay_updates >= MAX_OVERLAY_UPDATES_PER_WORK && !roundstart) + lighting_update_overlays += O + continue // DON'T break, we're adding stuff back into the update queue. + + O.update_overlay() + O.needs_update = 0 + overlay_updates++ + SCHECK + +#undef MAX_LIGHT_UPDATES_PER_WORK +#undef MAX_CORNER_UPDATES_PER_WORK +#undef MAX_OVERLAY_UPDATES_PER_WORK diff --git a/code/controllers/Processes/shuttles.dm b/code/controllers/Processes/shuttles.dm index e1b29abb76d..9c01974a1a9 100644 --- a/code/controllers/Processes/shuttles.dm +++ b/code/controllers/Processes/shuttles.dm @@ -229,10 +229,4 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12 for(var/obj/docking_port/mobile/M in mobile) if(!M.roundstart_move) continue - for(var/obj/docking_port/stationary/S in stationary) - if(!is_station_level(S.z) && findtext(S.id, M.id)) - S.width = M.width - S.height = M.height - S.dwidth = M.dwidth - S.dheight = M.dheight - moveShuttle(M.id, "[M.roundstart_move]", 0) + M.dockRoundstart() diff --git a/code/controllers/Processes/weather.dm b/code/controllers/Processes/weather.dm index 6cdcce750b6..d2149371649 100644 --- a/code/controllers/Processes/weather.dm +++ b/code/controllers/Processes/weather.dm @@ -33,7 +33,7 @@ var/global/datum/controller/process/weather/weather_master var/list/possible_weather_for_this_z = list() for(var/V in existing_weather) var/datum/weather/WE = V - if(WE.target_level == Z && WE.probability) //Another check so that it doesn't run extra weather + if(WE.target_z == Z && WE.probability) //Another check so that it doesn't run extra weather possible_weather_for_this_z[WE] = WE.probability var/datum/weather/W = pickweight(possible_weather_for_this_z) run_weather(W.name) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 763a9c7b08c..5e1701aacb8 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -187,6 +187,8 @@ var/max_loadout_points = 5 // How many points can be spent on extra items in character setup + var/disable_ooc_emoji = 0 // prevents people from using emoji in OOC + /datum/configuration/New() var/list/L = subtypesof(/datum/game_mode) for(var/T in L) @@ -573,6 +575,15 @@ if("round_abandon_penalty_period") config.round_abandon_penalty_period = MinutesToTicks(text2num(value)) + + if("medal_hub_address") + global.medal_hub = value + + if("medal_hub_password") + global.medal_pass = value + + if("disable_ooc_emoji") + config.disable_ooc_emoji = 1 else diary << "Unknown setting in configuration: '[name]'" diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index a7678e1d261..fe8d1cbb133 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -17,8 +17,7 @@ message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") return - -/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano","Vote","Mob Hunt Server")) +/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Jobs","Sun","Radio","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler","Nano","Vote","Diseases","Fires","Mob","NPC AI","Shuttle","Timer","Weather","Space","Mob Hunt Server")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -37,9 +36,6 @@ if("Air") debug_variables(air_master) feedback_add_details("admin_verb","DAir") - if("Lighting") - debug_variables(lighting_controller) - feedback_add_details("admin_verb","DLighting") if("Jobs") debug_variables(job_master) feedback_add_details("admin_verb","DJobs") @@ -76,6 +72,30 @@ if("Vote") debug_variables(vote) feedback_add_details("admin_verb","DVote") + if("Diseases") + debug_variables(disease_master) + feedback_add_details("admin_verb","DDiseases") + if("Fires") + debug_variables(fire_master) + feedback_add_details("admin_verb","DFires") + if("Mob") + debug_variables(mob_master) + feedback_add_details("admin_verb","DMob") + if("NPC AI") + debug_variables(npcai_master) + feedback_add_details("admin_verb","DNPCAI") + if("Shuttle") + debug_variables(shuttle_master) + feedback_add_details("admin_verb","DShuttle") + if("Timer") + debug_variables(timer_master) + feedback_add_details("admin_verb","DTimer") + if("Weather") + debug_variables(weather_master) + feedback_add_details("admin_verb","DWeather") + if("Space") + debug_variables(space_manager) + feedback_add_details("admin_verb","DSpace") if("Mob Hunt Server") debug_variables(mob_hunt_server) feedback_add_details("admin_verb","DMobHuntServer") diff --git a/code/datums/action.dm b/code/datums/action.dm index 446b50243ae..f1826c334c5 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -187,6 +187,40 @@ /datum/action/item_action/toggle_hardsuit_mode name = "Toggle Hardsuit Mode" + +/datum/action/item_action/toggle_unfriendly_fire + name = "Toggle Friendly Fire \[ON\]" + desc = "Toggles if the staff causes friendly fire." + button_icon_state = "vortex_ff_on" + +/datum/action/item_action/toggle_unfriendly_fire/Trigger() + if(..()) + UpdateButtonIcon() + +/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon() + if(istype(target, /obj/item/weapon/hierophant_staff)) + var/obj/item/weapon/hierophant_staff/H = target + if(H.friendly_fire_check) + button_icon_state = "vortex_ff_off" + name = "Toggle Friendly Fire \[OFF\]" + button.name = name + else + button_icon_state = "vortex_ff_on" + name = "Toggle Friendly Fire \[ON\]" + button.name = name + ..() + +/datum/action/item_action/vortex_recall + name = "Vortex Recall" + desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.
If no such rune exists, will produce a rune at your location." + button_icon_state = "vortex_recall" + +/datum/action/item_action/vortex_recall/IsAvailable() + if(istype(target, /obj/item/weapon/hierophant_staff)) + var/obj/item/weapon/hierophant_staff/H = target + if(H.teleporting) + return 0 + return ..() /datum/action/item_action/toggle @@ -323,6 +357,11 @@ ..() name = "Toggle [target.name]" button.name = name + +/datum/action/item_action/organ_action/use/New(Target) + ..() + name = "Use [target.name]" + button.name = name // for clothing accessories like holsters /datum/action/item_action/accessory diff --git a/code/datums/cargoprofile.dm b/code/datums/cargoprofile.dm index ada85c38611..becb3ccee56 100644 --- a/code/datums/cargoprofile.dm +++ b/code/datums/cargoprofile.dm @@ -245,8 +245,8 @@ id = "trash" //Note that this filters out blueprints because they are a paper item. Do NOT throw out the station blueprints unless you be trollin'. blacklist = null - whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/weapon/reagent_containers/food/snacks/ectoplasm,/obj/item/weapon/bananapeel,/obj/item/weapon/broken_bottle,/obj/item/weapon/bikehorn, - /obj/item/weapon/cigbutt,/obj/item/weapon/contraband,/obj/item/weapon/corncob,/obj/item/weapon/paper,/obj/item/weapon/shard, + whitelist = list(/obj/item/trash,/obj/item/toy,/obj/item/weapon/reagent_containers/food/snacks/ectoplasm,/obj/item/weapon/grown/bananapeel,/obj/item/weapon/broken_bottle,/obj/item/weapon/bikehorn, + /obj/item/weapon/cigbutt,/obj/item/weapon/contraband,/obj/item/weapon/grown/corncob,/obj/item/weapon/paper,/obj/item/weapon/shard, /obj/item/weapon/sord,/obj/item/weapon/photo,/obj/item/weapon/folder, /obj/item/areaeditor/blueprints,/obj/item/weapon/contraband,/obj/item/weapon/kitchen,/obj/item/weapon/book,/obj/item/clothing/mask/facehugger) @@ -267,9 +267,9 @@ whitelist = list(/obj/item/device,/obj/item/weapon/card,/obj/item/weapon/cartridge,/obj/item/weapon/cautery,/obj/item/weapon/stock_parts/cell,/obj/item/weapon/circuitboard, /obj/item/weapon/aiModule,/obj/item/weapon/airalarm_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/circular_saw, /obj/item/weapon/crowbar,/obj/item/weapon/disk,/obj/item/weapon/firealarm_electronics,/obj/item/weapon/hand_tele, - /obj/item/weapon/hand_labeler,/obj/item/weapon/hemostat,/obj/item/weapon/mop,/obj/item/weapon/locator,/obj/item/weapon/minihoe, + /obj/item/weapon/hand_labeler,/obj/item/weapon/hemostat,/obj/item/weapon/mop,/obj/item/weapon/locator,/obj/item/weapon/cultivator, /obj/item/stack/packageWrap,/obj/item/weapon/pen,/obj/item/weapon/pickaxe,/obj/item/weapon/pinpointer, - /obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/retractor,/obj/item/weapon/rsf,/obj/item/weapon/rsp,/obj/item/weapon/scalpel, + /obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/retractor,/obj/item/weapon/rsf,/obj/item/weapon/scalpel, /obj/item/weapon/screwdriver,/obj/item/weapon/shovel,/obj/item/weapon/soap,/obj/item/weapon/stamp,/obj/item/weapon/storage/bag/tray,/obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters,/obj/item/weapon/wrench,/obj/item/weapon/extinguisher) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 53a927386bd..9b3d413e94d 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,12 +1,18 @@ // reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) +/datum + var/var_edited = 0 //Warrenty void if seal is broken + +/datum/proc/on_varedit(modified_var) //called whenever a var is edited + var_edited = 1 + /client/proc/debug_variables(datum/D in world) set category = "Debug" set name = "View Variables" //set src in world - if(!usr.client || !usr.client.holder) + if(!is_admin(usr)) to_chat(usr, "You need to be an administrator to access this.") return @@ -212,6 +218,14 @@ if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) body += "
Marked Object" + if(D.var_edited) + body += "
Var Edited" + + if(istype(D, /atom)) + var/atom/A = D + if(A.admin_spawned) + body += "
Admin Spawned" + body += "" body += "" @@ -616,8 +630,9 @@ body return to_chat(M, "Control of your mob has been offered to dead players.") log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.") - message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts") - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name]?", poll_time = 100) + var/minhours = input(usr, "Minimum hours required to play [M]?", "Set Min Hrs", 10) as num + message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts with [minhours] hrs playtime") + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name]?", poll_time = 100, min_hours = minhours) var/mob/dead/observer/theghost = null if(candidates.len) diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index 894e88e3a08..0252977dcf4 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -77,8 +77,8 @@ if(prob(15/D.permeability_mod)) return -/* if(satiety>0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease. - return*/ + if(satiety > 0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease. + return var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4) diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index d38c65beb8c..c55a42e397c 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -102,7 +102,7 @@ var/list/diseases = subtypesof(/datum/disease) return if(affected_mob) - if(affected_mob.reagents.has_reagent("spaceacillin")) + if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10))) return var/spread_range = 1 diff --git a/code/datums/material_container.dm b/code/datums/material_container.dm index 499bb8e188e..4ea22aca590 100644 --- a/code/datums/material_container.dm +++ b/code/datums/material_container.dm @@ -132,6 +132,8 @@ //For spawning mineral sheets; internal use only /datum/material_container/proc/retrieve(sheet_amt, datum/material/M) + if(!M.sheet_type) + return 0 if(sheet_amt > 0) if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT)) sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT) @@ -271,4 +273,10 @@ /datum/material/tranquillite/New() ..() material_type = MAT_TRANQUILLITE - sheet_type = /obj/item/stack/sheet/mineral/tranquillite \ No newline at end of file + sheet_type = /obj/item/stack/sheet/mineral/tranquillite + +/datum/material/biomass + +/datum/material/biomass/New() + ..() + material_type = MAT_BIOMASS \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index fcf1ded97cc..41fdf4a2ad0 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -56,6 +56,7 @@ var/miming = 0 // Mime's vow of silence var/datum/faction/faction //associated faction var/datum/changeling/changeling //changeling holder + var/linglink var/datum/vampire/vampire //vampire holder var/datum/nations/nation //nation holder var/datum/abductor/abductor //abductor holder @@ -104,11 +105,13 @@ /datum/mind/proc/wipe_memory() memory = null -/datum/mind/proc/show_memory(mob/recipient) - var/output = "[current.real_name]'s Memory
" +/datum/mind/proc/show_memory(mob/recipient, window=1) + if(!recipient) + recipient = current + var/output = "[current.real_name]'s Memories:
" output += memory - if(objectives.len>0) + if(objectives.len) output += "
Objectives:" var/obj_count = 1 @@ -116,7 +119,7 @@ output += "Objective #[obj_count]: [objective.explanation_text]" obj_count++ - if(job_objectives.len>0) + if(job_objectives.len) output += "
Job Objectives:" - - recipient << browse(output,"window=memory") + if(window) + recipient << browse(output,"window=memory") + else + to_chat(recipient, "[output]") /datum/mind/proc/edit_memory() if(!ticker || !ticker.mode) @@ -149,7 +154,7 @@ ) var/text = "" var/mob/living/carbon/human/H = current - if(istype(current, /mob/living/carbon/human)) + if(ishuman(current)) /** Impanted**/ if(isloyal(H)) text = "Mindshield Implant:Remove|Implanted
" @@ -369,7 +374,7 @@ /** SILICON ***/ - if(istype(current, /mob/living/silicon)) + if(issilicon(current)) text = "silicon" var/mob/living/silicon/robot/robot = current if(istype(robot) && robot.emagged) @@ -409,7 +414,7 @@ if(((src in ticker.mode.head_revolutionaries) || \ (src in ticker.mode.traitors) || \ (src in ticker.mode.syndicates)) && \ - istype(current,/mob/living/carbon/human) ) + ishuman(current) ) text = "Uplink: give" var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink() @@ -445,18 +450,21 @@ usr << browse(out, "window=edit_memory[src];size=400x500") /datum/mind/Topic(href, href_list) - if(!check_rights(R_ADMIN)) return + if(!check_rights(R_ADMIN)) + return if(href_list["role_edit"]) var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist - if(!new_role) return + if(!new_role) + return assigned_role = new_role log_admin("[key_name(usr)] has changed [key_name(current)]'s assigned role to [assigned_role]") message_admins("[key_name_admin(usr)] has changed [key_name_admin(current)]'s assigned role to [assigned_role]") else if(href_list["memory_edit"]) var/new_memo = copytext(input("Write new memory", "Memory", memory) as null|message,1,MAX_MESSAGE_LEN) - if(isnull(new_memo)) return + if(isnull(new_memo)) + return memory = new_memo log_admin("[key_name(usr)] has edited [key_name(current)]'s memory") message_admins("[key_name_admin(usr)] has edited [key_name_admin(current)]'s memory") @@ -468,7 +476,8 @@ if(href_list["obj_edit"]) objective = locate(href_list["obj_edit"]) - if(!objective) return + if(!objective) + return objective_pos = objectives.Find(objective) //Text strings are easy to manipulate. Revised for simplicity. @@ -478,7 +487,8 @@ def_value = "custom" var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "blood", "debrain", "protect", "prevent", "brig", "hijack", "escape", "survive", "steal", "download", "nuclear", "capture", "absorb", "destroy", "maroon", "identity theft", "custom") - if(!new_obj_type) return + if(!new_obj_type) + return var/datum/objective/new_objective = null @@ -500,7 +510,8 @@ def_target = objective:target.current var/new_target = input("Select target:", "Objective target", def_target) as null|anything in possible_targets - if(!new_target) return + if(!new_target) + return var/objective_path = text2path("/datum/objective/[new_obj_type]") if(new_target == "Free objective") @@ -588,7 +599,7 @@ if("identity theft") var/list/possible_targets = list("Free objective") for(var/datum/mind/possible_target in ticker.minds) - if((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human)) + if((possible_target != src) && ishuman(possible_target.current)) possible_targets += possible_target var/new_target = input("Select target:", "Objective target") as null|anything in possible_targets @@ -604,12 +615,14 @@ new_objective.explanation_text = "Escape on the shuttle or an escape pod with the identity of [targ.current.real_name], the [targ.assigned_role] while wearing their identification card." if("custom") var/expl = sanitize(copytext(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null,1,MAX_MESSAGE_LEN)) - if(!expl) return + if(!expl) + return new_objective = new /datum/objective new_objective.owner = src new_objective.explanation_text = expl - if(!new_objective) return + if(!new_objective) + return if(objective) objectives -= objective @@ -622,7 +635,8 @@ else if(href_list["obj_delete"]) var/datum/objective/objective = locate(href_list["obj_delete"]) - if(!istype(objective)) return + if(!istype(objective)) + return objectives -= objective log_admin("[key_name(usr)] has removed one of [key_name(current)]'s objectives: [objective]") @@ -630,7 +644,8 @@ else if(href_list["obj_completed"]) var/datum/objective/objective = locate(href_list["obj_completed"]) - if(!istype(objective)) return + if(!istype(objective)) + return objective.completed = !objective.completed log_admin("[key_name(usr)] has toggled the completion of one of [key_name(current)]'s objectives") @@ -893,7 +908,7 @@ message_admins("[key_name_admin(usr)] has automatically forged objectives for [key_name_admin(current)]") if("initialdna") - if( !changeling || !changeling.absorbed_dna.len ) + if(!changeling || !changeling.absorbed_dna.len) to_chat(usr, "\red Resetting DNA failed!") else current.dna = changeling.absorbed_dna[1] @@ -924,7 +939,7 @@ ticker.mode.update_vampire_icons_added(src) var/datum/mindslaves/slaved = new() slaved.masters += src - src.som = slaved //we MIGT want to mindslave someone + som = slaved //we MIGT want to mindslave someone special_role = SPECIAL_ROLE_VAMPIRE to_chat(current, "Your powers are awoken. Your lust for blood grows... You are a Vampire!") log_admin("[key_name(usr)] has vampired [key_name(current)]") @@ -1033,7 +1048,7 @@ ticker.mode.traitors += src var/datum/mindslaves/slaved = new() slaved.masters += src - src.som = slaved //we MIGT want to mindslave someone + som = slaved //we MIGT want to mindslave someone special_role = SPECIAL_ROLE_TRAITOR to_chat(current, "You are a traitor!") log_admin("[key_name(usr)] has traitored [key_name(current)]") @@ -1130,7 +1145,7 @@ message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]") if("unemagcyborgs") - if(istype(current, /mob/living/silicon/ai)) + if(isAI(current)) var/mob/living/silicon/ai/ai = current for(var/mob/living/silicon/robot/R in ai.connected_robots) R.emagged = 0 @@ -1324,7 +1339,7 @@ var/explanation = "Summon [ticker.mode.cultdat.entity_name] via the use of the appropriate rune. It will only work if nine cultists stand on and around it." to_chat(current, "Objective #1: [explanation]") current.memory += "Objective #1: [explanation]
" - + var/mob/living/carbon/human/H = current if(istype(H)) @@ -1453,13 +1468,13 @@ qdel(S) spell_list -= S -/datum/mind/proc/transfer_actions(var/mob/living/new_character) +/datum/mind/proc/transfer_actions(mob/living/new_character) if(current && current.actions) for(var/datum/action/A in current.actions) A.Grant(new_character) transfer_mindbound_actions(new_character) -/datum/mind/proc/transfer_mindbound_actions(var/mob/living/new_character) +/datum/mind/proc/transfer_mindbound_actions(mob/living/new_character) for(var/X in spell_list) var/obj/effect/proc_holder/spell/S = X S.action.Grant(new_character) @@ -1553,13 +1568,15 @@ ticker.minds += mind else error("mind_initialize(): No ticker ready yet! Please inform Carn") - if(!mind.name) mind.name = real_name + if(!mind.name) + mind.name = real_name mind.current = src //HUMAN /mob/living/carbon/human/mind_initialize() ..() - if(!mind.assigned_role) mind.assigned_role = "Civilian" //defualt + if(!mind.assigned_role) + mind.assigned_role = "Civilian" //defualt /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index 2e953f3ec91..e379de25209 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -34,14 +34,12 @@ * */ /datum/recipe - var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice - var/list/items // example: = list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo - var/list/fruit // example: = list("fruit" = 3) - var/result // example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal - var/time = 100 // 1/10 part of second + var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice + var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo + var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut + var/time = 100 // 1/10 part of second var/byproduct // example: = /obj/item/weapon/kitchen/mould // byproduct to return, such as a mould or trash - /datum/recipe/proc/check_reagents(datum/reagents/avail_reagents) //1=precisely, 0=insufficiently, -1=superfluous . = 1 for(var/r_r in reagents) @@ -55,44 +53,25 @@ return -1 return . -/datum/recipe/proc/check_fruit(obj/container) +/datum/recipe/proc/check_items(obj/container) //1=precisely, 0=insufficiently, -1=superfluous + if(!items) + if(locate(/obj/) in container) + return -1 + else + return 1 . = 1 - if(fruit && fruit.len) - var/list/checklist = list() - // You should trust Copy(). - checklist = fruit.Copy() - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) - if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) - continue - checklist[G.seed.kitchen_tag]-- - for(var/ktag in checklist) - if(!isnull(checklist[ktag])) - if(checklist[ktag] < 0) - . = 0 - else if(checklist[ktag] > 0) - . = -1 - break - return . - -/datum/recipe/proc/check_items(obj/container) - . = 1 - if(items && items.len) - var/list/checklist = list() - checklist = items.Copy() // You should really trust Copy - for(var/obj/O in container) - if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) - continue // Fruit is handled in check_fruit(). - var/found = 0 - for(var/i = 1; i < checklist.len+1; i++) - var/item_type = checklist[i] - if(istype(O,item_type)) - checklist.Cut(i, i+1) - found = 1 - break - if(!found) - . = 0 - if(checklist.len) + var/list/checklist = items.Copy() + for(var/obj/O in container) + var/found = 0 + for(var/type in checklist) + if(istype(O,type)) + checklist-=type + found = 1 + break + if(!found) . = -1 + if(checklist.len) + return 0 return . //general version @@ -102,7 +81,6 @@ O.reagents.trans_to(result_obj, O.reagents.total_volume) qdel(O) container.reagents.clear_reagents() - score_meals++ return result_obj // food-related @@ -115,27 +93,29 @@ O.reagents.trans_to(result_obj, O.reagents.total_volume) qdel(O) container.reagents.clear_reagents() - score_meals++ return result_obj -/proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj, exact = 1) +/proc/select_recipe(list/datum/recipe/avaiable_recipes, obj/obj, exact = 1 as num) if(!exact) exact = -1 var/list/datum/recipe/possible_recipes = new for(var/datum/recipe/recipe in avaiable_recipes) - if(recipe.check_reagents(obj.reagents)==exact && recipe.check_items(obj)==exact && recipe.check_fruit(obj)==exact) + if(recipe.check_reagents(obj.reagents)==exact && recipe.check_items(obj)==exact) possible_recipes+=recipe if(possible_recipes.len==0) return null else if(possible_recipes.len==1) return possible_recipes[1] else //okay, let's select the most complicated recipe - var/highest_count = 0 + var/r_count = 0 + var/i_count = 0 . = possible_recipes[1] for(var/datum/recipe/recipe in possible_recipes) - var/count = ((recipe.items)?(recipe.items.len):0) + ((recipe.reagents)?(recipe.reagents.len):0) + ((recipe.fruit)?(recipe.fruit.len):0) - if(count >= highest_count) - highest_count = count + var/N_i = (recipe.items)?(recipe.items.len):0 + var/N_r = (recipe.reagents)?(recipe.reagents.len):0 + if(N_i > i_count || (N_i== i_count && N_r > r_count )) + r_count = N_r + i_count = N_i . = recipe return . @@ -149,7 +129,4 @@ var/count = 0 if(items && items.len) count += items.len - if(fruit && fruit.len) - for(var/ktag in fruit) - count += fruit[ktag] - return count + return count \ No newline at end of file diff --git a/code/datums/spell.dm b/code/datums/spell.dm index 332d96779e6..f48f6ca3fc7 100644 --- a/code/datums/spell.dm +++ b/code/datums/spell.dm @@ -3,9 +3,53 @@ /obj/effect/proc_holder var/panel = "Debug"//What panel the proc holder needs to go on. + var/active = FALSE //Used by toggle based abilities. + var/ranged_mousepointer var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin verb for now +/obj/effect/proc_holder/proc/InterceptClickOn(mob/living/user, params, atom/A) + if(user.ranged_ability != src) + to_chat(user, "[user.ranged_ability.name] has been disabled.") + user.ranged_ability.remove_ranged_ability(user) + return TRUE //TRUE for failed, FALSE for passed. + user.next_click = world.time + CLICK_CD_CLICK_ABILITY + user.face_atom(A) + return FALSE + +/obj/effect/proc_holder/proc/add_ranged_ability(mob/living/user, var/msg) + if(!user || !user.client) + return + if(user.ranged_ability && user.ranged_ability != src) + to_chat(user, "[user.ranged_ability.name] has been replaced by [name].") + user.ranged_ability.remove_ranged_ability(user) + user.ranged_ability = src + user.client.click_intercept = user.ranged_ability + add_mousepointer(user.client) + active = TRUE + if(msg) + to_chat(user, msg) + update_icon() + +/obj/effect/proc_holder/proc/add_mousepointer(client/C) + if(C && ranged_mousepointer && C.mouse_pointer_icon == initial(C.mouse_pointer_icon)) + C.mouse_pointer_icon = ranged_mousepointer + +/obj/effect/proc_holder/proc/remove_mousepointer(client/C) + if(C && ranged_mousepointer && C.mouse_pointer_icon == ranged_mousepointer) + C.mouse_pointer_icon = initial(C.mouse_pointer_icon) + +/obj/effect/proc_holder/proc/remove_ranged_ability(mob/living/user, var/msg) + if(!user || !user.client || (user.ranged_ability && user.ranged_ability != src)) //To avoid removing the wrong ability + return + user.ranged_ability = null + user.client.click_intercept = null + remove_mousepointer(user.client) + active = FALSE + if(msg) + to_chat(user, msg) + update_icon() + /obj/effect/proc_holder/spell name = "Spell" desc = "A wizard spell" @@ -26,6 +70,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/ghost = 0 // Skip life check. var/clothes_req = 1 //see if it requires clothes + var/human_req = 0 //spell can only be cast by humans + var/nonabstract_req = 0 //spell can only be cast by mobs that are physical entities var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell var/invocation_emote_self = null @@ -54,13 +100,15 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin var/action_icon = 'icons/mob/actions.dmi' var/action_icon_state = "spell_default" var/action_background_icon_state = "bg_spell" + + var/sound = null //The sound the spell makes when it is cast /obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0, mob/living/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell - if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list)) to_chat(user, "You shouldn't have this spell! Something's wrong.") return 0 - if(istype(user, /mob/living/carbon/human)) + + if(ishuman(user)) var/mob/living/carbon/human/caster = user if(caster.remoteview_target) caster.remoteview_target = null @@ -83,26 +131,31 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin if(!ghost) if(user.stat && !stat_allowed) - to_chat(user, "Not when you're incapacitated.") + to_chat(user, "You can't cast this spell while incapacitated.") return 0 - if(ishuman(user) && (invocation_type == "whisper" || invocation_type == "shout") && user.is_muzzled()) to_chat(user, "Mmmf mrrfff!") return 0 - var/obj/effect/proc_holder/spell/noclothes/spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list())) - if(clothes_req && !(spell && istype(spell)))//clothes check - if(!istype(user, /mob/living/carbon/human)) - to_chat(user, "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans.") + + var/obj/effect/proc_holder/spell/noclothes/clothes_spell = locate() in (user.mob_spell_list | (user.mind ? user.mind.spell_list : list())) + if((ishuman(user) && clothes_req) && !istype(clothes_spell))//clothes check + var/mob/living/carbon/human/H = user + if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(H.wear_suit, /obj/item/clothing/suit/space/rig/wizard)) + to_chat(user, "I don't feel strong enough without my robe.") return 0 - if(!istype(user:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/rig/wizard)) - to_chat(user, "I don't feel strong enough without my robe.") + if(!istype(H.shoes, /obj/item/clothing/shoes/sandal)) + to_chat(user, "I don't feel strong enough without my sandals.") return 0 - if(!istype(user:shoes, /obj/item/clothing/shoes/sandal)) - to_chat(user, "I don't feel strong enough without my sandals.") - return 0 - if(!istype(user:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/rig/wizard)) + if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/rig/wizard)) to_chat(user, "I don't feel strong enough without my hat.") return 0 + else if(!ishuman(user)) + if(clothes_req || human_req) + to_chat(user, "This spell can only be cast by humans!") + return 0 + if(nonabstract_req && (isbrain(user) || ispAI(user))) + to_chat(user, "This spell can only be cast by physical beings!") + return 0 if(!skipcharge) switch(charge_type) @@ -130,6 +183,9 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin if("emote") user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm +/obj/effect/proc_holder/spell/proc/playMagSound() + playsound(get_turf(usr), sound,50,1) + /obj/effect/proc_holder/spell/New() ..() action = new(src) @@ -162,14 +218,19 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin /obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr) //if recharge is started is important for the trigger spells before_cast(targets) invocation() - user.attack_log += text("\[[time_stamp()]\] [user.real_name] ([user.ckey]) cast the spell [name].") + if(user && user.ckey) + user.create_attack_log("[user.real_name] ([user.ckey]) cast the spell [name].") spawn(0) if(charge_type == "recharge" && recharge) start_recharge() + + if(sound) + playMagSound() + if(prob(critfailchance)) critfail(targets) else - cast(targets) + cast(targets, user = user) after_cast(targets) /obj/effect/proc_holder/spell/proc/before_cast(list/targets) @@ -215,7 +276,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin smoke.set_up(smoke_amt, 0, location) // same here smoke.start() -/obj/effect/proc_holder/spell/proc/cast(list/targets) +/obj/effect/proc_holder/spell/proc/cast(list/targets, mob/user = usr) return /obj/effect/proc_holder/spell/proc/critfail(list/targets) @@ -269,9 +330,6 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin switch(max_targets) if(0) //unlimited for(var/mob/living/target in view_or_range(range, user, selection_type)) - for(var/F in user.faction) - if(F in target.faction) - continue targets += target if(1) //single target can be picked if(range < 0) @@ -325,7 +383,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin revert_cast(user) return - perform(targets) + perform(targets, user=user) return @@ -340,7 +398,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin revert_cast() return - perform(targets) + perform(targets, user=user) return @@ -376,7 +434,6 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin return 0 if(ishuman(user)) - var/mob/living/carbon/human/H = user if((invocation_type == "whisper" || invocation_type == "shout") && H.is_muzzled()) @@ -392,8 +449,8 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin if(!istype(H.head, /obj/item/clothing/head/wizard) && !istype(H.head, /obj/item/clothing/head/helmet/space/rig/wizard)) return 0 else - if(clothes_req) + if(clothes_req || human_req) return 0 - if(isbrain(user) || ispAI(user)) + if(nonabstract_req && (isbrain(user) || ispAI(user))) return 0 return 1 diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index ad0b6fa61de..46def2b5a9c 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -1,10 +1,15 @@ /obj/effect/proc_holder/spell/targeted/area_teleport name = "Area teleport" desc = "This spell teleports you to a type of area of your selection." - + nonabstract_req = 1 + var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list var/invocation_area = 1 //if the invocation appends the selected area -/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1) + + var/sound1 = 'sound/weapons/ZapBang.ogg' + var/sound2 = 'sound/weapons/ZapBang.ogg' + +/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1, mob/living/user = usr) var/thearea = before_cast(targets) if(!thearea || !cast_check(1)) revert_cast() @@ -32,7 +37,8 @@ return thearea -/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) +/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea,mob/living/user = usr) + playsound(get_turf(user), sound1, 50,1) for(var/mob/living/target in targets) var/list/L = list() for(var/turf/T in get_area_turfs(thearea.type)) @@ -64,7 +70,8 @@ break if(!success) - target.loc = pick(L) + target.forceMove(pick(L)) + playsound(get_turf(user), sound2, 50,1) return diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm index 7f6f4d4fb2a..0b23b12b9f2 100644 --- a/code/datums/spells/bloodcrawl.dm +++ b/code/datums/spells/bloodcrawl.dm @@ -14,8 +14,8 @@ /obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr) for(var/obj/effect/decal/cleanable/target in range(range, get_turf(user))) - if(istype(target,/obj/effect/decal/cleanable/blood) && !(istype(target,/obj/effect/decal/cleanable/blood/oil) || istype(target,/obj/effect/decal/cleanable/blood/gibs/robot))) - perform(target) + if(target.can_bloodcrawl_in()) + perform(target, user = user) return revert_cast() to_chat(user, "There must be a nearby source of blood!") diff --git a/code/datums/spells/conjure.dm b/code/datums/spells/conjure.dm index bdd15eb34fe..fe0ffd9c1c0 100644 --- a/code/datums/spells/conjure.dm +++ b/code/datums/spells/conjure.dm @@ -13,15 +13,17 @@ var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet //should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example var/delay = 1//Go Go Gadget Inheritance + + var/cast_sound = 'sound/items/welder.ogg' -/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets) - +/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets,mob/living/user = usr) + playsound(get_turf(user), cast_sound, 50,1) for(var/turf/T in targets) if(T.density && !summon_ignore_density) targets -= T - playsound(get_turf(src), 'sound/items/welder.ogg', 50, 1) + playsound(get_turf(src), cast_sound, 50, 1) - if(do_after(usr,delay, target = usr)) + if(do_after(user,delay, target = user)) for(var/i=0,iYou are somehow too bound to your current location to abandon it.") diff --git a/code/datums/spells/explosion.dm b/code/datums/spells/explosion.dm index 7bb7195c2dd..4beeae1206a 100644 --- a/code/datums/spells/explosion.dm +++ b/code/datums/spells/explosion.dm @@ -7,7 +7,7 @@ var/ex_light = 3 var/ex_flash = 4 -/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) diff --git a/code/datums/spells/genetic.dm b/code/datums/spells/genetic.dm index e61819dc183..697337d85e0 100644 --- a/code/datums/spells/genetic.dm +++ b/code/datums/spells/genetic.dm @@ -15,7 +15,7 @@ 6th bit - ? */ -/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) for(var/x in mutations) diff --git a/code/datums/spells/horsemask.dm b/code/datums/spells/horsemask.dm index 3d2ab9d4718..b3ca73fe367 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/datums/spells/horsemask.dm @@ -14,6 +14,7 @@ selection_type = "range" action_icon_state = "barn" + sound = 'sound/magic/HorseHead_curse.ogg' /obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) if(!targets.len) diff --git a/code/datums/spells/inflict_handler.dm b/code/datums/spells/inflict_handler.dm index 1eed65bbed4..cfda930afd2 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/datums/spells/inflict_handler.dm @@ -19,7 +19,7 @@ var/summon_type = null //this will put an obj at the target's location -/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) switch(destroys) diff --git a/code/datums/spells/knock.dm b/code/datums/spells/knock.dm index e2be52fb7db..1d296c26d41 100644 --- a/code/datums/spells/knock.dm +++ b/code/datums/spells/knock.dm @@ -11,8 +11,9 @@ cooldown_min = 20 //20 deciseconds reduction per rank action_icon_state = "knock" + sound = 'sound/magic/Knock.ogg' -/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets) +/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets, mob/user = usr) for(var/turf/T in targets) for(var/obj/machinery/door/door in T.contents) spawn(1) diff --git a/code/datums/spells/lightning.dm b/code/datums/spells/lightning.dm index 00c04e5a792..bb2bb133d71 100644 --- a/code/datums/spells/lightning.dm +++ b/code/datums/spells/lightning.dm @@ -14,6 +14,7 @@ var/ready = 0 var/image/halo = null action_icon_state = "lightning" + var/sound/Snd // so far only way i can think of to stop a sound, thank MSO for the idea. /obj/effect/proc_holder/spell/targeted/lightning/lightnian clothes_req = 0 @@ -31,8 +32,10 @@ /obj/effect/proc_holder/spell/targeted/lightning/proc/StartChargeup(mob/user = usr) ready = 1 to_chat(user, "You start gathering the power.") + Snd = new/sound('sound/magic/lightning_chargeup.ogg',channel = 7) halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER) user.overlays.Add(halo) + playsound(get_turf(user), Snd, 50, 0) start_time = world.time if(do_mob(user,user,100,uninterruptible=1)) if(ready) @@ -59,11 +62,14 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) /obj/effect/proc_holder/spell/targeted/lightning/cast(list/targets, mob/user = usr) ready = 0 var/mob/living/carbon/target = targets[1] + Snd=sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck? + playsound(get_turf(user),Snd,50,0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way. if(get_dist(user,target)>range) to_chat(user, "They are too far away!") Reset(user) return + playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, 1) user.Beam(target,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) var/energy = min(world.time - start_time,100) @@ -75,10 +81,10 @@ obj/effect/proc_holder/spell/targeted/lightning/proc/Reset(mob/user = usr) var/mob/living/carbon/current = target if(bounces < 1) current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1) - playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1) else current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1) - playsound(get_turf(current), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(get_turf(current), 'sound/magic/LightningShock.ogg', 50, 1, -1) var/list/possible_targets = new for(var/mob/living/M in view_or_range(range,target,"view")) if(user == M || target == M && los_check(current,M)) // || origin == M ? Not sure double shockings is good or not diff --git a/code/datums/spells/mime.dm b/code/datums/spells/mime.dm index fb996bc84ee..296521405a0 100644 --- a/code/datums/spells/mime.dm +++ b/code/datums/spells/mime.dm @@ -10,7 +10,9 @@ charge_max = 300 clothes_req = 0 range = 0 - + cast_sound = null + human_req = 1 + action_icon_state = "mime" action_background_icon_state = "bg_mime" @@ -34,6 +36,7 @@ charge_max = 3000 range = -1 include_user = 1 + human_req = 1 action_icon_state = "mime" action_background_icon_state = "bg_mime" diff --git a/code/datums/spells/projectile.dm b/code/datums/spells/projectile.dm index 611c45b1595..258925653d8 100644 --- a/code/datums/spells/projectile.dm +++ b/code/datums/spells/projectile.dm @@ -37,7 +37,7 @@ projectile.dir = get_dir(target,projectile) projectile.name = proj_name - var/current_loc = usr.loc + var/current_loc = user.loc projectile.loc = current_loc @@ -75,7 +75,7 @@ qdel(trail) if(projectile.loc in range(target.loc,proj_trigger_range)) - projectile.perform(list(target)) + projectile.perform(list(target), user = user) break current_loc = projectile.loc diff --git a/code/datums/spells/shapeshift.dm b/code/datums/spells/shapeshift.dm new file mode 100644 index 00000000000..a814c84fa59 --- /dev/null +++ b/code/datums/spells/shapeshift.dm @@ -0,0 +1,82 @@ +/obj/effect/proc_holder/spell/targeted/shapeshift + name = "Shapechange" + desc = "Take on the shape of another for a time to use their natural abilities. Once you've made your choice it cannot be changed." + clothes_req = 0 + human_req = 0 + charge_max = 200 + cooldown_min = 50 + range = -1 + include_user = 1 + invocation = "RAC'WA NO!" + invocation_type = "shout" + action_icon_state = "shapeshift" + + var/shapeshift_type + var/list/current_shapes = list() + var/list/current_casters = list() + var/list/possible_shapes = list(/mob/living/simple_animal/mouse, + /mob/living/simple_animal/pet/corgi, + /mob/living/simple_animal/bot/ed209, + /mob/living/simple_animal/hostile/construct/armoured) + +/obj/effect/proc_holder/spell/targeted/shapeshift/cast(list/targets, mob/user = usr) + for(var/mob/living/M in targets) + if(!shapeshift_type) + var/list/animal_list = list() + for(var/path in possible_shapes) + var/mob/living/simple_animal/A = path + animal_list[initial(A.name)] = path + shapeshift_type = input(M, "Choose Your Animal Form!", "It's Morphing Time!", null) as anything in animal_list + if(!shapeshift_type) //If you aren't gonna decide I am! + shapeshift_type = pick(animal_list) + shapeshift_type = animal_list[shapeshift_type] + if(M in current_shapes) + Restore(M) + else + Shapeshift(M) + +/obj/effect/proc_holder/spell/targeted/shapeshift/proc/Shapeshift(mob/living/caster) + for(var/mob/living/M in caster) + if(M.status_flags & GODMODE) + to_chat(caster, "You're already shapeshifted!") + return + + var/mob/living/shape = new shapeshift_type(caster.loc) + caster.loc = shape + caster.status_flags |= GODMODE + + current_shapes |= shape + current_casters |= caster + clothes_req = 0 + human_req = 0 + + caster.mind.transfer_to(shape) + +/obj/effect/proc_holder/spell/targeted/shapeshift/proc/Restore(mob/living/shape) + var/mob/living/caster + for(var/mob/living/M in shape) + if(M in current_casters) + caster = M + break + if(!caster) + return + caster.loc = shape.loc + caster.status_flags &= ~GODMODE + + clothes_req = initial(clothes_req) + human_req = initial(human_req) + current_casters.Remove(caster) + current_shapes.Remove(shape) + + shape.mind.transfer_to(caster) + qdel(shape) //Gib it maybe ? + +/obj/effect/proc_holder/spell/targeted/shapeshift/dragon + name = "Dragon Form" + desc = "Take on the shape a lesser ash drake." + invocation = "RAAAAAAAAWR!" + + shapeshift_type = /mob/living/simple_animal/hostile/megafauna/dragon/lesser + list/current_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser) + list/current_casters = list() + list/possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser) \ No newline at end of file diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm index ce68e7370dd..7872c3978cb 100644 --- a/code/datums/spells/summonitem.dm +++ b/code/datums/spells/summonitem.dm @@ -15,9 +15,9 @@ action_icon_state = "summons" -/obj/effect/proc_holder/spell/targeted/summonitem/cast(list/targets) - for(var/mob/living/user in targets) - var/list/hand_items = list(user.get_active_hand(),user.get_inactive_hand()) +/obj/effect/proc_holder/spell/targeted/summonitem/cast(list/targets, mob/user = usr) + for(var/mob/living/target in targets) + var/list/hand_items = list(target.get_active_hand(),target.get_inactive_hand()) var/butterfingers = 0 var/message @@ -26,6 +26,10 @@ for(var/obj/item in hand_items) if(istype(item, /obj/item/organ/internal/brain)) //Yeah, sadly this doesn't work due to the organ system. break + if(ABSTRACT in item.flags) + continue + if(NODROP in item.flags) + message += "This feels very redundant, but you go through with it anyway.
" marked_item = item message += "You mark [item] for recall.
" name = "Recall [item]" @@ -36,6 +40,7 @@ message = "You aren't holding anything that can be marked for recall." else message = "You must hold the desired item in your hands to mark it for recall." + else if(marked_item && marked_item in hand_items) //unlinking item to the spell message = "You remove the mark on [marked_item] to use elsewhere." name = "Instant Summons" @@ -56,7 +61,7 @@ if(issilicon(M)) //Items in silicons warp the whole silicon M.loc.visible_message("[M] suddenly disappears!") - M.loc = user.loc + M.loc = target.loc M.loc.visible_message("[M] suddenly appears!") item_to_retrive = null break @@ -68,10 +73,10 @@ /*if(C.internal_organs_by_name && item_to_retrive in C.internal_organs_by_name ) //This won't work, as we use organ datums instead of objects. --DZD C.internal_organs_by_name -= item_to_retrive if(istype(marked_item, /obj/item/brain)) //If this code ever runs I will be happy - var/obj/item/brain/B = new /obj/item/brain(user.loc) + var/obj/item/brain/B = new /obj/item/brain(target.loc) B.transfer_identity(C) C.death() - add_logs(user, C, "magically debrained", addition="INTENT: [uppertext(user.a_intent)]")*/ + add_logs(target, C, "magically debrained", addition="INTENT: [uppertext(target.a_intent)]")*/ if(C.stomach_contents && item_to_retrive in C.stomach_contents) C.stomach_contents -= item_to_retrive @@ -91,19 +96,21 @@ item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly disappears!") - if(user.hand) //left active hand - if(!user.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1)) - if(!user.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1)) + if(target.hand) //left active hand + if(!target.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1)) + if(!target.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1)) butterfingers = 1 else //right active hand - if(!user.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1)) - if(!user.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1)) + if(!target.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1)) + if(!target.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1)) butterfingers = 1 if(butterfingers) - item_to_retrive.loc = user.loc + item_to_retrive.loc = target.loc item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly appears!") + playsound(get_turf(target),'sound/magic/SummonItems_generic.ogg',50,1) else - item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly appears in [user]'s hand!") + item_to_retrive.loc.visible_message("The [item_to_retrive.name] suddenly appears in [target]'s hand!") + playsound(get_turf(target),'sound/magic/SummonItems_generic.ogg',50,1) if(message) - to_chat(user, message) + to_chat(target, message) diff --git a/code/datums/spells/touch_attacks.dm b/code/datums/spells/touch_attacks.dm index 6f659e5e98d..44993cb69b2 100644 --- a/code/datums/spells/touch_attacks.dm +++ b/code/datums/spells/touch_attacks.dm @@ -14,10 +14,10 @@ return 0 ..() -/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets) - for(var/mob/living/carbon/user in targets) +/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets, mob/user = usr) + for(var/mob/living/carbon/target in targets) if(!attached_hand) - if(!ChargeHand(user)) + if(!ChargeHand(target)) return 0 while(attached_hand) //hibernate untill the spell is actually used charge_counter = 0 diff --git a/code/datums/spells/trigger.dm b/code/datums/spells/trigger.dm index 0db9ae7d9a0..bba1f22cb1a 100644 --- a/code/datums/spells/trigger.dm +++ b/code/datums/spells/trigger.dm @@ -19,11 +19,11 @@ starting_spells = null return ..() -/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) for(var/obj/effect/proc_holder/spell/spell in contents) - spell.perform(list(target),0) + spell.perform(list(target), 0, user = user) for(var/obj/effect/proc_holder/spell/spell in linked_spells) - spell.perform(list(target),0) + spell.perform(list(target), 0, user = user) return \ No newline at end of file diff --git a/code/datums/spells/turf_teleport.dm b/code/datums/spells/turf_teleport.dm index 02dd5f71b49..8d4562aa1dc 100644 --- a/code/datums/spells/turf_teleport.dm +++ b/code/datums/spells/turf_teleport.dm @@ -1,14 +1,19 @@ /obj/effect/proc_holder/spell/targeted/turf_teleport name = "Turf Teleport" desc = "This spell teleports the target to the turf in range." + nonabstract_req = 1 var/inner_tele_radius = 1 var/outer_tele_radius = 2 var/include_space = 0 //whether it includes space tiles in possible teleport locations var/include_dense = 0 //whether it includes dense tiles in possible teleport locations + + var/sound1 = 'sound/weapons/ZapBang.ogg' + var/sound2 = 'sound/weapons/ZapBang.ogg' -/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets,mob/living/user = usr) + playsound(get_turf(user), sound1, 50,1) for(var/mob/living/target in targets) var/list/turfs = new/list() for(var/turf/T in range(target,outer_tele_radius)) @@ -31,4 +36,5 @@ if(!picked || !isturf(picked)) return - target.loc = picked + target.forceMove(picked) + playsound(get_turf(user), sound2, 50,1) diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 33cc6b8d574..e3892baac2f 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -25,9 +25,12 @@ proj_trail_icon_state = "magicmd" action_icon_state = "magicm" + + sound = 'sound/magic/MAGIC_MISSILE.ogg' /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile amt_weakened = 3 + sound = 'sound/magic/MM_Hit.ogg' /obj/effect/proc_holder/spell/noclothes name = "No Clothes" @@ -52,8 +55,9 @@ cooldown_min = 300 //25 deciseconds reduction per rank action_icon_state = "mutate" + sound = 'sound/magic/Mutate.ogg' -/obj/effect/proc_holder/spell/targeted/genetic/mutate/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/genetic/mutate/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) target.dna.SetSEState(HULKBLOCK, 1) genemutcheck(target, HULKBLOCK, null, MUTCHK_FORCED) @@ -93,6 +97,8 @@ emp_heavy = 6 emp_light = 10 + + sound = 'sound/magic/Disable_Tech.ogg' /obj/effect/proc_holder/spell/targeted/turf_teleport/blink name = "Blink" @@ -117,6 +123,9 @@ centcom_cancast = 0 //prevent people from getting to centcom action_icon_state = "blink" + + sound1 = 'sound/magic/blink.ogg' + sound2 = 'sound/magic/blink.ogg' /obj/effect/proc_holder/spell/targeted/area_teleport/teleport name = "Teleport" @@ -135,6 +144,9 @@ smoke_amt = 5 action_icon_state = "spell_teleport" + + sound1 = 'sound/magic/Teleport_diss.ogg' + sound2 = 'sound/magic/Teleport_app.ogg' /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall name = "Forcewall" @@ -152,6 +164,7 @@ summon_lifespan = 300 action_icon_state = "shield" + cast_sound = 'sound/magic/ForceWall.ogg' /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop name = "Stop Time" @@ -180,7 +193,8 @@ summon_type = list(/mob/living/simple_animal/hostile/carp) - + cast_sound = 'sound/magic/Summon_Karp.ogg' + /obj/effect/proc_holder/spell/aoe_turf/conjure/construct name = "Artificer" desc = "This spell conjures a construct which may be controlled by Shades" @@ -195,6 +209,7 @@ summon_type = list(/obj/structure/constructshell) action_icon_state = "artificer" + cast_sound = 'sound/magic/SummonItems_generic.ogg' /obj/effect/proc_holder/spell/aoe_turf/conjure/creature name = "Summon Creature Swarm" @@ -209,6 +224,7 @@ range = 3 summon_type = list(/mob/living/simple_animal/hostile/creature) + cast_sound = 'sound/magic/SummonItems_generic.ogg' /obj/effect/proc_holder/spell/targeted/trigger/blind name = "Blind" @@ -229,12 +245,14 @@ /obj/effect/proc_holder/spell/targeted/inflict_handler/blind amt_eye_blind = 10 amt_eye_blurry = 20 + sound = 'sound/magic/Blind.ogg' /obj/effect/proc_holder/spell/targeted/genetic/blind disabilities = BLIND duration = 300 + sound = 'sound/magic/Blind.ogg' -/obj/effect/proc_holder/spell/dumbfire/fireball +/obj/effect/proc_holder/spell/fireball name = "Fireball" desc = "This spell fires a fireball at a target and does not require wizard garb." @@ -245,29 +263,65 @@ invocation_type = "shout" range = 20 cooldown_min = 20 //10 deciseconds reduction per rank + var/fireball_type = /obj/item/projectile/magic/fireball + action_icon_state = "fireball0" + sound = 'sound/magic/Fireball.ogg' - proj_icon_state = "fireball" - proj_name = "a fireball" - proj_type = "/obj/effect/proc_holder/spell/turf/fireball" + active = FALSE - proj_lifespan = 200 - proj_step_delay = 1 +/obj/effect/proc_holder/spell/fireball/Click() + var/mob/living/user = usr + if(!istype(user)) + return - action_icon_state = "fireball" + var/msg -/obj/effect/proc_holder/spell/turf/fireball/cast(var/turf/T) - explosion(T, -1, 0, 2, 3, 0, flame_range = 2) + if(!can_cast(user)) + msg = "You can no longer cast Fireball." + remove_ranged_ability(user, msg) + return + if(active) + msg = "You extinguish your fireball...for now." + remove_ranged_ability(user, msg) + else + msg = "Your prepare to cast your fireball spell! Left-click to cast at a target!" + add_ranged_ability(user, msg) -/obj/effect/proc_holder/spell/targeted/inflict_handler/fireball - amt_dam_brute = 20 - amt_dam_fire = 25 +/obj/effect/proc_holder/spell/fireball/update_icon() + if(!action) + return + action.button_icon_state = "fireball[active]" + action.UpdateButtonIcon() -/obj/effect/proc_holder/spell/targeted/explosion/fireball - ex_severe = -1 - ex_heavy = -1 - ex_light = 2 - ex_flash = 5 +/obj/effect/proc_holder/spell/fireball/InterceptClickOn(mob/living/user, params, atom/target) + if(..()) + return FALSE + + if(!cast_check(0, user)) + remove_ranged_ability(user) + return FALSE + + var/list/targets = list(target) + perform(targets, user = user) + + return TRUE + +/obj/effect/proc_holder/spell/fireball/cast(list/targets, mob/living/user = usr) + var/target = targets[1] //There is only ever one target for fireball + var/turf/T = user.loc + var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction + if(!isturf(U) || !isturf(T)) + return 0 + + var/obj/item/projectile/magic/fireball/FB = new fireball_type(user.loc) + FB.current = get_turf(user) + FB.preparePixelProjectile(target, get_turf(target), user) + FB.fire() + user.newtonian_move(get_dir(U, T)) + remove_ranged_ability(user) + + return 1 /obj/effect/proc_holder/spell/aoe_turf/repulse name = "Repulse" @@ -282,12 +336,13 @@ var/maxthrow = 5 action_icon_state = "repulse" + sound = 'sound/magic/Repulse.ogg' -/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets) - var/mob/user = usr +/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets, mob/user = usr) var/list/thrownatoms = list() var/atom/throwtarget var/distfromcaster + playMagSound() for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously. for(var/atom/movable/AM in T) thrownatoms += AM @@ -314,3 +369,24 @@ M.Weaken(2) to_chat(M, "You're thrown back by a mystical force!") spawn(0) AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time. + +/obj/effect/proc_holder/spell/targeted/sacred_flame + name = "Sacred Flame" + desc = "Makes everyone around you more flammable, and lights yourself on fire." + charge_max = 60 + clothes_req = 0 + invocation = "FI'RAN DADISKO" + invocation_type = "shout" + max_targets = 0 + range = 6 + include_user = 1 + selection_type = "view" + action_icon_state = "sacredflame" + sound = 'sound/magic/Fireball.ogg' + +/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr) + for(var/mob/living/L in targets) + L.adjust_fire_stacks(20) + if(isliving(user)) + var/mob/living/U = user + U.IgniteMob() \ No newline at end of file diff --git a/code/datums/statclick.dm b/code/datums/statclick.dm index 51018fae9cb..e10a63b8356 100644 --- a/code/datums/statclick.dm +++ b/code/datums/statclick.dm @@ -31,7 +31,7 @@ // This bit is called when clicked in the stat panel /obj/effect/statclick/debug/Click() - if(!usr.client.holder) + if(!is_admin(usr)) return usr.client.debug_variables(target) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 7a8f05e08fc..d1159671875 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -429,6 +429,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine name = "HEADER" group = supply_engineer announce_beacons = list("Engineering" = list("Engineering", "Chief Engineer's Desk")) + containertype = /obj/structure/closet/crate/engineering /datum/supply_packs/engineering/fueltank @@ -456,6 +457,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/clothing/gloves/color/yellow) cost = 20 //Made of pure-grade bullshittinium containername = "insulated gloves crate" + containertype = /obj/structure/closet/crate/engineering/electrical /datum/supply_packs/engineering/power name = "Power Cell Crate" @@ -464,6 +466,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/stock_parts/cell/high) cost = 10 containername = "electrical maintenance crate" + containertype = /obj/structure/closet/crate/engineering/electrical /datum/supply_packs/engineering/engiequipment name = "Engineering Gear Crate" @@ -510,6 +513,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/paper/solar) cost = 20 containername = "solar pack crate" + containertype = /obj/structure/closet/crate/engineering/electrical /datum/supply_packs/engineering/engine name = "Emitter Crate" @@ -519,6 +523,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine containertype = /obj/structure/closet/crate/secure containername = "emitter crate" access = access_ce + containertype = /obj/structure/closet/crate/secure/engineering /datum/supply_packs/engineering/engine/field_gen name = "Field Generator Crate" @@ -781,6 +786,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine name = "HEADER" group = supply_science announce_beacons = list("Research Division" = list("Science", "Research Director's Desk")) + containertype = /obj/structure/closet/crate/sci /datum/supply_packs/science/robotics name = "Robotics Assembly Crate" @@ -792,7 +798,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/stock_parts/cell/high, /obj/item/weapon/stock_parts/cell/high) cost = 10 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/scisec containername = "robotics assembly crate" access = access_robotics announce_beacons = list("Research Division" = list("Robotics", "Research Director's Desk")) @@ -804,18 +810,14 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer cost = 30 - containertype = /obj/structure/closet/crate/secure containername = "\improper APLU \"Ripley\" circuit crate" - announce_beacons = list("Research Division" = list("Robotics", "Research Director's Desk")) /datum/supply_packs/science/robotics/mecha_odysseus name = "Circuit Crate (Odysseus)" contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer cost = 25 - containertype = /obj/structure/closet/crate/secure containername = "\improper \"Odysseus\" circuit crate" - announce_beacons = list("Research Division" = list("Robotics", "Research Director's Desk")) /datum/supply_packs/science/plasma name = "Plasma Assembly Crate" @@ -844,7 +846,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/machinery/shieldwallgen, /obj/machinery/shieldwallgen) cost = 20 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/scisec containername = "shield generators crate" access = access_teleporter @@ -854,7 +856,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine contains = list(/obj/item/device/transfer_valve, /obj/item/device/transfer_valve) cost = 60 - containertype = /obj/structure/closet/crate/secure + containertype = /obj/structure/closet/crate/secure/scisec containername = "tank transfer valves crate" access = access_rd @@ -905,28 +907,28 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/farwa name = "Farwa Crate" - contains = list (/obj/item/weapon/storage/box/farwacubes) - cost = 30 + contains = list (/obj/item/weapon/storage/box/monkeycubes/farwacubes) + cost = 20 containername = "farwa crate" /datum/supply_packs/organic/wolpin name = "Wolpin Crate" - contains = list (/obj/item/weapon/storage/box/wolpincubes) - cost = 30 + contains = list (/obj/item/weapon/storage/box/monkeycubes/wolpincubes) + cost = 20 containername = "wolpin crate" /datum/supply_packs/organic/skrell name = "Neaera Crate" - contains = list (/obj/item/weapon/storage/box/neaeracubes) - cost = 30 + contains = list (/obj/item/weapon/storage/box/monkeycubes/neaeracubes) + cost = 20 containername = "neaera crate" /datum/supply_packs/organic/stok name = "Stok Crate" - contains = list (/obj/item/weapon/storage/box/stokcubes) - cost = 30 + contains = list (/obj/item/weapon/storage/box/monkeycubes/stokcubes) + cost = 20 containername = "stok crate" /datum/supply_packs/organic/party @@ -1022,8 +1024,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/reagent_containers/glass/bottle/ammonia, /obj/item/weapon/reagent_containers/glass/bottle/ammonia, /obj/item/weapon/hatchet, - /obj/item/weapon/minihoe, - /obj/item/device/analyzer/plant_analyzer, + /obj/item/weapon/cultivator, + /obj/item/device/plant_analyzer, /obj/item/clothing/gloves/botanic_leather, /obj/item/clothing/suit/apron) // Updated with new things cost = 15 @@ -1042,35 +1044,39 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/organic/hydroponics/seeds name = "Seeds Crate" - contains = list(/obj/item/seeds/chiliseed, - /obj/item/seeds/berryseed, - /obj/item/seeds/cornseed, - /obj/item/seeds/eggplantseed, - /obj/item/seeds/tomatoseed, - /obj/item/seeds/soyaseed, - /obj/item/seeds/wheatseed, - /obj/item/seeds/carrotseed, - /obj/item/seeds/sunflowerseed, - /obj/item/seeds/chantermycelium, - /obj/item/seeds/potatoseed, - /obj/item/seeds/sugarcaneseed) + contains = list(/obj/item/seeds/chili, + /obj/item/seeds/berry, + /obj/item/seeds/corn, + /obj/item/seeds/eggplant, + /obj/item/seeds/tomato, + /obj/item/seeds/soya, + /obj/item/seeds/wheat, + /obj/item/seeds/wheat/rice, + /obj/item/seeds/carrot, + /obj/item/seeds/sunflower, + /obj/item/seeds/chanter, + /obj/item/seeds/potato, + /obj/item/seeds/sugarcane) cost = 10 containername = "seeds crate" /datum/supply_packs/organic/hydroponics/exoticseeds name = "Exotic Seeds Crate" - contains = list(/obj/item/seeds/nettleseed, + contains = list(/obj/item/seeds/nettle, /obj/item/seeds/replicapod, /obj/item/seeds/replicapod, /obj/item/seeds/replicapod, - /obj/item/seeds/plumpmycelium, - /obj/item/seeds/libertymycelium, - /obj/item/seeds/amanitamycelium, - /obj/item/seeds/reishimycelium, - /obj/item/seeds/bananaseed, + /obj/item/seeds/nymph, + /obj/item/seeds/nymph, + /obj/item/seeds/nymph, + /obj/item/seeds/plump, + /obj/item/seeds/liberty, + /obj/item/seeds/amanita, + /obj/item/seeds/reishi, + /obj/item/seeds/banana, + /obj/item/seeds/eggplant/eggy, /obj/item/seeds/random, - /obj/item/seeds/random, - ) + /obj/item/seeds/random) cost = 15 containername = "exotic seeds crate" @@ -1181,10 +1187,17 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/misc/watertank name = "Water Tank Crate" contains = list(/obj/structure/reagent_dispensers/watertank) - cost = 8 + cost = 6 containertype = /obj/structure/largecrate containername = "water tank crate" +/datum/supply_packs/misc/hightank + name = "High-Capacity Water Tank Crate" + contains = list(/obj/structure/reagent_dispensers/watertank/high) + cost = 12 + containertype = /obj/structure/largecrate + containername = "high-capacity water tank crate" + /datum/supply_packs/misc/lasertag name = "Laser Tag Crate" contains = list(/obj/item/weapon/gun/energy/laser/redtag, @@ -1571,6 +1584,14 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine cost = 15 containername = "snacks supply crate" +/datum/supply_packs/vending/chinese + name = "Chinese Supply Crate" + contains = list(/obj/item/weapon/vending_refill/chinese, + /obj/item/weapon/vending_refill/chinese, + /obj/item/weapon/vending_refill/chinese) + cost = 15 + containername = "chinese supply crate" + /datum/supply_packs/vending/cola name = "Softdrinks Supply Crate" contains = list(/obj/item/weapon/vending_refill/cola, diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 2c5b9375918..d54311921fd 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -305,7 +305,7 @@ var/list/uplink_items = list() name = "Ambrosia Cruciatus Seeds" desc = "Part of the notorious Ambrosia family, this species is nearly indistinguishable from Ambrosia Vulgaris- but its' branches contain a revolting toxin. Eight units are enough to drive victims insane." reference = "BRO" - item = /obj/item/seeds/ambrosiavulgarisseed/cruciatus + item = /obj/item/seeds/ambrosia/cruciatus cost = 2 job = list("Botanist") diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index 7002f92061b..c87b2b455e7 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -20,6 +20,7 @@ var/weather_duration_upper = 1500 //See above - this is the highest possible duration var/weather_sound var/weather_overlay + var/weather_color = null var/end_message = "The wind relents its assault." //Displayed once the wather is over var/end_duration = 300 //In deciseconds, how long the "wind-down" graphic will appear before vanishing entirely @@ -28,8 +29,9 @@ var/area_type = /area/space //Types of area to affect var/list/impacted_areas = list() //Areas to be affected by the weather, calculated when the weather begins - var/target_level = MAIN_STATION //The z-level to affect - + var/target_z = MAIN_STATION //The z-level to affect + var/list/protected_areas = list()//Areas that are protected and excluded from the affected areas. + var/overlay_layer = 10 //Since it's above everything else, this is the layer used by default. 2 is below mobs and walls if you need to use that. var/aesthetic = FALSE //If the weather has no purpose other than looks var/immunity_type = "storm" //Used by mobs to prevent them from being affected by the weather @@ -50,15 +52,20 @@ if(stage == STARTUP_STAGE) return stage = STARTUP_STAGE + var/list/affectareas = list() for(var/V in get_areas(area_type)) + affectareas += V + for(var/V in protected_areas) + affectareas -= get_areas(V) + for(var/V in affectareas) var/area/A = V - if(is_on_level_name(A,target_level)) + if(is_on_level_name(A,target_z)) impacted_areas |= A weather_duration = rand(weather_duration_lower, weather_duration_upper) update_areas() for(var/V in player_list) var/mob/M = V - if(is_on_level_name(M,target_level)) + if(is_on_level_name(M,target_z)) if(telegraph_message) to_chat(M, telegraph_message) if(telegraph_sound) @@ -72,7 +79,7 @@ update_areas() for(var/V in player_list) var/mob/M = V - if(is_on_level_name(M,target_level)) + if(is_on_level_name(M,target_z)) if(weather_message) to_chat(M, weather_message) if(weather_sound) @@ -87,7 +94,7 @@ update_areas() for(var/V in player_list) var/mob/M = V - if(is_on_level_name(M,target_level)) + if(is_on_level_name(M,target_z)) if(end_message) to_chat(M, end_message) if(end_sound) @@ -102,7 +109,7 @@ update_areas() /datum/weather/proc/can_impact(mob/living/L) //Can this weather impact a mob? - if(!is_on_level_name(L,target_level)) + if(!is_on_level_name(L,target_z)) return if(immunity_type in L.weather_immunities) return @@ -119,6 +126,7 @@ N.layer = overlay_layer N.icon = 'icons/effects/weather_effects.dmi' N.invisibility = 0 + N.color = weather_color switch(stage) if(STARTUP_STAGE) N.icon_state = telegraph_overlay @@ -127,6 +135,7 @@ if(WIND_DOWN_STAGE) N.icon_state = end_overlay if(END_STAGE) + N.color = null N.icon_state = initial(N.icon_state) N.icon = 'icons/turf/areas.dmi' N.layer = 10 //Just default back to normal area stuff since I assume setting a var is faster than initial diff --git a/code/datums/weather/weather_types.dm b/code/datums/weather/weather_types.dm index 90615896e6d..1581938bd96 100644 --- a/code/datums/weather/weather_types.dm +++ b/code/datums/weather/weather_types.dm @@ -16,7 +16,7 @@ end_duration = 0 area_type = /area - target_level = MAIN_STATION + target_z = MAIN_STATION overlay_layer = 2 //Covers floors only immunity_type = "lava" @@ -50,7 +50,7 @@ end_duration = 0 area_type = /area - target_level = MAIN_STATION + target_z = MAIN_STATION /datum/weather/advanced_darkness/update_areas() for(var/V in impacted_areas) @@ -87,7 +87,7 @@ end_overlay = "light_ash" area_type = /area/mine/dangerous - target_level = MINING + target_z = MINING immunity_type = "ash" diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm index c05819995ec..fb9bc232e12 100644 --- a/code/defines/procs/admin.dm +++ b/code/defines/procs/admin.dm @@ -45,7 +45,7 @@ return . /proc/key_name_admin(var/whom, var/include_name = 1) - var/message = "[key_name(whom, 1, include_name)](?)[isAntag(whom) ? "(A)" : ""][isLivingSSD(whom) ? "(SSD!)" : ""] ([admin_jump_link(whom)])" + var/message = "[key_name(whom, 1, include_name)](?)[isAntag(whom) ? "(A)" : ""][isLivingSSD(whom) ? "(SSD!)" : ""] ([admin_jump_link(whom)])" return message /proc/log_and_message_admins(var/message as text) diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 6c9387644b0..ab447e0fc6b 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -1,7 +1,8 @@ /var/datum/announcement/minor/minor_announcement = new() /var/datum/announcement/priority/priority_announcement = new(do_log = 0) -/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1) -/var/datum/announcement/priority/enemy/communications_announcement = new(do_log = 0, do_newscast = 1) +/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 0) +/var/datum/announcement/priority/command/event/event_announcement = new(do_log = 0, do_newscast = 0) +/var/datum/announcement/priority/enemy/communications_announcement = new(do_log = 0, do_newscast = 0) /datum/announcement @@ -12,7 +13,8 @@ var/newscast = 0 var/channel_name = "Station Announcements" var/announcement_type = "Announcement" - var/disable_newscasts = 1 // Bay also adds announcements to their newscaster system - set this to 0 to also use that system + var/admin_announcement = 0 // Admin announcements are received regardless of being in range of a radio, unless you're in the lobby to prevent metagaming + var/language = "Galactic Common" /datum/announcement/New(var/do_log = 0, var/new_sound = null, var/do_newscast = 0) sound = new_sound @@ -31,11 +33,17 @@ /datum/announcement/priority/command/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) ..(do_log, new_sound, do_newscast) + admin_announcement = 1 title = "[command_name()] Update" announcement_type = "[command_name()] Update" + +/datum/announcement/priority/command/event/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0) + ..(do_log, new_sound, do_newscast) + admin_announcement = 0 /datum/announcement/priority/enemy/New(var/do_log = 1, var/new_sound = sound('sound/AI/intercept2.ogg'), var/do_newscast = 0) ..(do_log, new_sound, do_newscast) + admin_announcement = 1 title = "[command_name()] Update" announcement_type = "Enemy Communications" @@ -44,72 +52,122 @@ title = "Security Announcement" announcement_type = "Security Announcement" -/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from) +/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from, var/msg_language) if(!message) return + var/tmp/message_title = new_title ? new_title : title var/tmp/message_sound = new_sound ? sound(new_sound) : sound if(!msg_sanitized) message = trim_strip_html_properly(message, allow_lines = 1) message_title = html_encode(message_title) - - Message(message, message_title, from) + + var/message_announcer = null + if(announcer) + message_announcer = html_encode(announcer) + + var/datum/language/message_language = all_languages[msg_language ? msg_language : language] + + var/list/combined_receivers = Get_Receivers(message_language) + var/list/receivers = combined_receivers[1] + var/list/garbled_receivers = combined_receivers[2] + + var/formatted_message = Format_Message(message, message_title, message_announcer, from) + var/garbled_formatted_message = Format_Message(message_language.scramble(message), message_language.scramble(message_title), message_language.scramble(message_announcer), message_language.scramble(from)) + + Message(formatted_message, garbled_formatted_message, receivers, garbled_receivers) + if(do_newscast) NewsCast(message, message_title) - Sound(message_sound) + + Sound(message_sound, combined_receivers[1] + combined_receivers[2]) Log(message, message_title) + +/datum/announcement/proc/Get_Receivers(var/datum/language/message_language) + var/list/receivers = list() + var/list/garbled_receivers = list() + + if(admin_announcement) + for(var/mob/M in player_list) + if(!isnewplayer(M) && M.client) + receivers |= M + else + for(var/obj/item/device/radio/R in global_radios) + receivers |= R.send_announcement() + for(var/mob/M in receivers) + if(!istype(M) || !M.client || M.stat || !M.can_hear()) + receivers -= M + continue + if(!M.say_understands(null, message_language)) + receivers -= M + garbled_receivers |= M + for(var/mob/M in dead_mob_list) + if(M.client && M.stat == DEAD) + receivers |= M -/datum/announcement/proc/Message(message as text, message_title as text) - for(var/mob/M in player_list) - if(M.can_hear()) - to_chat(M, "

[title]

") - to_chat(M, "[message]") - if(announcer) - to_chat(M, " -[html_encode(announcer)]") + return list(receivers, garbled_receivers) -/datum/announcement/minor/Message(message as text, message_title as text) - to_chat(world, "[message_title]") - to_chat(world, "[message]") +/datum/announcement/proc/Message(message, garbled_message, receivers, garbled_receivers) + for(var/mob/M in receivers) + to_chat(M, message) + for(var/mob/M in garbled_receivers) + to_chat(M, garbled_message) + +/datum/announcement/proc/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "

[message_title]

" + formatted_message += "
[message]" + if(message_announcer) + formatted_message += "
-[message_announcer]" + + return formatted_message -/datum/announcement/priority/Message(message as text, message_title as text) - to_chat(world, "

[message_title]

") - to_chat(world, "[message]") - if(announcer) - to_chat(world, " -[html_encode(announcer)]") - to_chat(world, "
") +/datum/announcement/minor/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "[message_title]" + formatted_message += "
[message]" + + return formatted_message -/datum/announcement/priority/command/Message(message as text, message_title as text) - var/command - command += "

[command_name()] Update

" +/datum/announcement/priority/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "

[message_title]

" + formatted_message += "
[message]" + if(message_announcer) + formatted_message += "
-[message_announcer]" + formatted_message += "
" + + return formatted_message + +/datum/announcement/priority/command/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "

[title]

" if(message_title) - command += "

[message_title]

" + formatted_message += "

[message_title]

" + formatted_message += "
[message]
" + formatted_message += "
" + + return formatted_message - command += "
[message]
" - command += "
" - for(var/mob/M in player_list) - if(M.can_hear()) - to_chat(M, command) - -/datum/announcement/priority/enemy/Message(message as text, message_title as text, from as text) - var/command - command += "

[from]

" +/datum/announcement/priority/enemy/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "

[from]

" if(message_title) - command += "

[message_title]

" + formatted_message += "

[message_title]

" + formatted_message += "
[message]
" + formatted_message += "
" - command += "
[message]
" - command += "
" - for(var/mob/M in player_list) - if(M.can_hear()) - to_chat(M, command) + return formatted_message -/datum/announcement/priority/security/Message(message as text, message_title as text) - to_chat(world, "[message_title]") - to_chat(world, "[message]") +/datum/announcement/priority/security/Format_Message(message, message_title, message_announcer, from) + var/formatted_message + formatted_message += "[message_title]" + formatted_message += "
[message]" + + return formatted_message /datum/announcement/proc/NewsCast(message as text, message_title as text) - if(disable_newscasts) - return if(!newscast) return @@ -121,28 +179,17 @@ news.can_be_redacted = 0 announce_newscaster_news(news) -/datum/announcement/proc/PlaySound(var/message_sound) +/datum/announcement/proc/Sound(var/message_sound, var/receivers) if(!message_sound) return - for(var/mob/M in player_list) - if(M.can_hear()) - M << message_sound - -/datum/announcement/proc/Sound(var/message_sound) - PlaySound(message_sound) - -/datum/announcement/priority/Sound(var/message_sound) - if(sound) - world << sound - -/datum/announcement/priority/command/Sound(var/message_sound) - PlaySound(message_sound) + for(var/mob/M in receivers) + M << message_sound /datum/announcement/proc/Log(message as text, message_title as text) if(log) log_say("[key_name(usr)] has made \a [announcement_type]: [message_title] - [message] - [announcer]") message_admins("[key_name_admin(usr)] has made \a [announcement_type].", 1) - + /proc/GetNameAndAssignmentFromId(var/obj/item/weapon/card/id/I) // Format currently matches that of newscaster feeds: Registered Name (Assigned Rank) - return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name \ No newline at end of file + return I.assignment ? "[I.registered_name] ([I.assignment])" : I.registered_name diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 1bcc5bad5ef..8ec413450b0 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -53,11 +53,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station var/list/apc = list() var/no_air = null // var/list/lights // list of all lights on this area - var/list/all_doors = list() //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area var/air_doors_activated = 0 var/tele_proof = 0 var/no_teleportlocs = 0 + + var/outdoors = 0 //For space, the asteroid, lavaland, etc. Used with blueprints to determine if we are adding a new area (vs editing a station room) /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ @@ -105,14 +106,14 @@ var/list/ghostteleportlocs = list() name = "\improper Admin Room" icon_state = "start" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/adminconstruction name = "\improper Admin Testing Area" icon_state = "start" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/space icon_state = "space" @@ -121,6 +122,7 @@ var/list/ghostteleportlocs = list() power_light = 0 power_equip = 0 power_environ = 0 + outdoors = 1 ambientsounds = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/traitor.ogg') /area/space/atmosalert() @@ -464,7 +466,7 @@ var/list/ghostteleportlocs = list() icon_state = "start" requires_power = 0 luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 has_gravity = 1 // === end remove @@ -480,7 +482,7 @@ var/list/ghostteleportlocs = list() name = "\improper Centcom" icon_state = "centcom" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/centcom/control name = "\improper Centcom Control" @@ -551,6 +553,7 @@ var/list/ghostteleportlocs = list() name = "\improper Asteroid - Underground" icon_state = "cave" requires_power = 0 + outdoors = 1 /area/asteroid/artifactroom name = "\improper Asteroid - Artifact" @@ -560,7 +563,7 @@ var/list/ghostteleportlocs = list() name = "\improper Thunderdome" icon_state = "thunder" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/tdome/arena_source @@ -645,7 +648,7 @@ var/list/ghostteleportlocs = list() icon_state = "yellow" requires_power = 0 has_gravity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/wizard_station name = "\improper Wizard's Den" @@ -668,7 +671,7 @@ var/list/ghostteleportlocs = list() name = "\improper Vox Base" icon_state = "yellow" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 no_teleportlocs = 1 /area/vox_station/transit @@ -1225,7 +1228,7 @@ var/list/ghostteleportlocs = list() /area/holodeck name = "\improper Holodeck" icon_state = "Holodeck" - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/holodeck/alphadeck name = "\improper Holodeck Alpha" @@ -1362,7 +1365,7 @@ var/list/ghostteleportlocs = list() /area/solar requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 auxport name = "\improper Fore Port Solar Array" @@ -2277,25 +2280,25 @@ area/security/podbay name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/turret_protected/AIsatextFS name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/turret_protected/AIsatextAS name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/turret_protected/AIsatextAP name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/turret_protected/NewAIMain name = "\improper AI Main New" @@ -2472,7 +2475,7 @@ area/security/podbay name = "Beach" icon_state = "beach" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 requires_power = 0 ambientsounds = list('sound/ambience/shore.ogg', 'sound/ambience/seag1.ogg','sound/ambience/seag2.ogg','sound/ambience/seag2.ogg') diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 7caaf090914..ec70d50c504 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -29,7 +29,7 @@ if(type == /area) // override defaults for space. TODO: make space areas of type /area/space rather than /area requires_power = 1 always_unpowered = 1 - lighting_use_dynamic = 1 + dynamic_lighting = 1 power_light = 0 power_equip = 0 power_environ = 0 @@ -80,26 +80,26 @@ return 0 /area/proc/air_doors_close() - if(!src.air_doors_activated) - src.air_doors_activated = 1 - for(var/obj/machinery/door/firedoor/E in src.all_doors) - if(!E.blocked) - if(E.operating) - E.nextstate = CLOSED - else if(!E.density) + if(!air_doors_activated) + air_doors_activated = 1 + for(var/obj/machinery/door/firedoor/D in src) + if(!D.welded) + if(D.operating) + D.nextstate = CLOSED + else if(!D.density) spawn(0) - E.close() + D.close() /area/proc/air_doors_open() - if(src.air_doors_activated) - src.air_doors_activated = 0 - for(var/obj/machinery/door/firedoor/E in src.all_doors) - if(!E.blocked) - if(E.operating) - E.nextstate = OPEN - else if(E.density) + if(air_doors_activated) + air_doors_activated = 0 + for(var/obj/machinery/door/firedoor/D in src) + if(!D.welded) + if(D.operating) + D.nextstate = OPEN + else if(D.density) spawn(0) - E.open() + D.open() /area/proc/fire_alert() @@ -145,46 +145,33 @@ if(!eject) eject = 1 updateicon() - return /area/proc/readyreset() if(eject) eject = 0 updateicon() - return /area/proc/radiation_alert() if(!radalert) radalert = 1 updateicon() - return /area/proc/reset_radiation_alert() if(radalert) radalert = 0 updateicon() - return /area/proc/partyalert() - if(!( party )) + if(!party) party = 1 updateicon() mouse_opacity = 0 - return /area/proc/partyreset() if(party) party = 0 mouse_opacity = 0 updateicon() - for(var/obj/machinery/door/firedoor/D in src) - if(!D.blocked) - if(D.operating) - D.nextstate = OPEN - else if(D.density) - spawn(0) - D.open() - return /area/proc/updateicon() if(radalert) // always show the radiation alert, regardless of power diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 6d26555ca56..77c3179adf5 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -88,7 +88,7 @@ var/global/max_secret_rooms = 6 theme = "cavein" walltypes = list(/turf/simulated/mineral/random/high_chance=1) floortypes = list(/turf/simulated/floor/plating/airless/asteroid, /turf/simulated/floor/beach/sand) - treasureitems = list(/obj/mecha/working/ripley/mining=1, /obj/item/weapon/pickaxe/drill/diamonddrill=2,/obj/item/weapon/gun/energy/kinetic_accelerator/hyper=1, + treasureitems = list(/obj/mecha/working/ripley/mining=1, /obj/item/weapon/pickaxe/drill/diamonddrill=2, /obj/item/weapon/resonator/upgraded=1, /obj/item/weapon/pickaxe/drill/jackhammer=5) fluffitems = list(/obj/effect/decal/cleanable/blood=3,/obj/effect/decal/remains/human=1,/obj/item/clothing/under/overalls=1, /obj/item/weapon/reagent_containers/food/snacks/grown/chili=1,/obj/item/weapon/tank/oxygen/red=2) @@ -121,9 +121,9 @@ var/global/max_secret_rooms = 6 if("plantlab") theme = "plantlab" - treasureitems = list(/obj/item/weapon/gun/energy/floragun=1,/obj/item/seeds/ambrosiadeusseed=2,/obj/item/seeds/bluespacetomatoseed=2,/obj/item/seeds/bluetomatoseed=2, - /obj/item/seeds/coffeerseed=2, /obj/item/seeds/stobaccoseed=2) - fluffitems = list(/obj/item/weapon/twohanded/required/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/portable_atmospherics/hydroponics=1, + treasureitems = list(/obj/item/weapon/gun/energy/floragun=1,/obj/item/seeds/ambrosia/deus=2,/obj/item/seeds/tomato/blue/bluespace=2,/obj/item/seeds/tomato/blue=2, + /obj/item/seeds/coffee/robusta=2, /obj/item/seeds/tobacco/space=2) + fluffitems = list(/obj/item/weapon/twohanded/required/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/hydroponics=1, /obj/effect/glowshroom/single=2,/obj/item/weapon/reagent_containers/syringe/charcoal=2, /obj/item/weapon/reagent_containers/glass/bottle/diethylamine=3,/obj/item/weapon/reagent_containers/glass/bottle/ammonia=3) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 663d6c5a8f9..a7d464fb9db 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -37,6 +37,8 @@ var/allow_spin = 1 //Set this to 1 for a _target_ that is being thrown at; if an atom has this set to 1 then atoms thrown AT it will not spin; currently used for the singularity. -Fox + var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff. + /atom/proc/onCentcom() var/turf/T = get_turf(src) if(!T) @@ -79,6 +81,10 @@ reagents = null invisibility = 101 return ..() + +//Hook for running code when a dir change occurs +/atom/proc/setDir(newdir) + dir = newdir /atom/proc/CheckParts(list/parts_list) for(var/A in parts_list) @@ -220,11 +226,6 @@ /atom/proc/relaymove() return -//called to set the atom's dir and used to add behaviour to dir-changes - Not fully used (yet) -/atom/proc/set_dir(new_dir) - . = new_dir != dir - dir = new_dir - /atom/proc/ex_act() return @@ -464,3 +465,8 @@ /atom/proc/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list()) return + +/atom/on_varedit(modified_var) + if(!Debug2) + admin_spawned = TRUE + ..() \ No newline at end of file diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 107e8aee518..b8673b497d5 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -32,7 +32,13 @@ /atom/movable/Destroy() for(var/atom/movable/AM in contents) qdel(AM) + var/turf/un_opaque + if(opacity && isturf(loc)) + un_opaque = loc + loc = null + if(un_opaque) + un_opaque.recalc_atom_opacity() if(pulledby) if(pulledby.pulling == src) pulledby.pulling = null @@ -225,6 +231,10 @@ if(isobj(A)) if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement src.throw_impact(A,speed) + +/atom/movable/proc/throw_at_fast(atom/target, range, speed, thrower, no_spin) + set waitfor = 0 + throw_at(target, range, speed, thrower, no_spin) /atom/movable/proc/throw_at(atom/target, range, speed, thrower, no_spin) if(!target || !src || (flags & NODROP)) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 13752088a18..59557caea6a 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -44,7 +44,7 @@ hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD) /datum/atom_hud/data/diagnostic - hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD) + hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD) /datum/atom_hud/data/hydroponic hud_icons = list (PLANT_NUTRIENT_HUD, PLANT_WATER_HUD, PLANT_STATUS_HUD, PLANT_HEALTH_HUD, PLANT_TOXIN_HUD, PLANT_PEST_HUD, PLANT_WEED_HUD) @@ -68,47 +68,55 @@ return 1 return 0 -//helper for getting the appropriate health status +//helper for getting the appropriate health status UPDATED BY PUCKABOO2 TO INCLUDE NEGATIVES. /proc/RoundHealth(health) switch(health) if(100 to INFINITY) return "health100" - if(93 to 100) - return "health93" - if(86 to 93) - return "health86" - if(78 to 86) - return "health78" - if(71 to 78) - return "health71" - if(64 to 71) - return "health64" - if(56 to 64) - return "health56" - if(49 to 56) - return "health49" - if(42 to 49) - return "health42" - if(35 to 42) - return "health35" - if(28 to 35) - return "health28" - if(21 to 28) - return "health21" - if(14 to 21) - return "health14" - if(7 to 14) - return "health7" - if(1 to 7) - return "health1" - if(-50 to 1) + if(95 to 100) + return "health95" //For telling patients to eat a warm donk pocket and go on with their shift. + if(90 to 95) + return "health90" + if(80 to 90) + return "health80" + if(70 to 80) + return "health70" + if(60 to 70) + return "health60" + if(50 to 60) + return "health50" + if(40 to 50) + return "health40" + if(30 to 40) + return "health30" + if(20 to 30) + return "health20" + if(10 to 20) + return "health10" + if(0 to 10) return "health0" - if(-85 to -50) + if(-10 to 0) + return "health-0" //The health bar will turn a brilliant red and flash as usual, but deducted health will be black. + if(-20 to -10) + return "health-10" + if(-30 to -20) + return "health-20" + if(-40 to -30) + return "health-30" + if(-50 to -40) + return "health-40" + if(-60 to -50) return "health-50" - if(-99 to -85) - return "health-85" + if(-70 to -60) + return "health-60" + if(-80 to -70) + return "health-70" //Doc? + if(-90 to -80) + return "health-80" //Hey, doc? + if(-100 to -90) + return "health-90" //HURRY UP, DOC! else - return "health-100" + return "health-100" //doc u had 1 job return "0" ///HOOKS @@ -279,6 +287,17 @@ if(internal_damage) holder.icon_state = "hudwarn" +/obj/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech + var/image/holder = hud_list[DIAG_TRACK_HUD] + var/new_icon_state //This var exists so that the holder's icon state is set only once in the event of multiple mech beacons. + for(var/obj/item/mecha_parts/mecha_tracking/T in trackers) + if(T.ai_beacon) //Beacon with AI uplink + new_icon_state = "hudtrackingai" + break //Immediately terminate upon finding an AI beacon to ensure it is always shown over the normal one, as mechs can have several trackers. + else + new_icon_state = "hudtracking" + holder.icon_state = new_icon_state + /*~~~~~~~~~ Bots! ~~~~~~~~~~*/ @@ -347,17 +366,17 @@ return "zero" return "zero" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_nutrient() +/obj/machinery/hydroponics/proc/plant_hud_set_nutrient() var/image/holder = hud_list[PLANT_NUTRIENT_HUD] holder.icon_state = "hudnutrient[RoundPlantBar(nutrilevel/maxnutri)]" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_water() +/obj/machinery/hydroponics/proc/plant_hud_set_water() var/image/holder = hud_list[PLANT_WATER_HUD] holder.icon_state = "hudwater[RoundPlantBar(waterlevel/maxwater)]" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_status() +/obj/machinery/hydroponics/proc/plant_hud_set_status() var/image/holder = hud_list[PLANT_STATUS_HUD] - if(!seed) + if(!myseed) holder.icon_state = "" return if(harvest) @@ -368,30 +387,30 @@ return holder.icon_state = "" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_health() +/obj/machinery/hydroponics/proc/plant_hud_set_health() var/image/holder = hud_list[PLANT_HEALTH_HUD] - if(!seed) + if(!myseed) holder.icon_state = "" return - holder.icon_state = "hudplanthealth[RoundPlantBar(health/seed.get_trait(TRAIT_ENDURANCE))]" + holder.icon_state = "hudplanthealth[RoundPlantBar(plant_health/myseed.endurance)]" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_toxin() +/obj/machinery/hydroponics/proc/plant_hud_set_toxin() var/image/holder = hud_list[PLANT_TOXIN_HUD] - if(toxins < 1) // You don't want to see these icons if the value is small + if(toxic < 10) // You don't want to see these icons if the value is small holder.icon_state = "" return - holder.icon_state = "hudtoxin[RoundPlantBar(toxins/10)]" + holder.icon_state = "hudtoxin[RoundPlantBar(toxic/100)]" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_pest() +/obj/machinery/hydroponics/proc/plant_hud_set_pest() var/image/holder = hud_list[PLANT_PEST_HUD] if(pestlevel < 1) // You don't want to see these icons if the value is small holder.icon_state = "" return holder.icon_state = "hudpest[RoundPlantBar(pestlevel/10)]" -/obj/machinery/portable_atmospherics/hydroponics/proc/plant_hud_set_weed() +/obj/machinery/hydroponics/proc/plant_hud_set_weed() var/image/holder = hud_list[PLANT_WEED_HUD] if(weedlevel < 1) // You don't want to see these icons if the value is small holder.icon_state = "" return - holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]" \ No newline at end of file + holder.icon_state = "hudweed[RoundPlantBar(weedlevel/10)]" diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm index 4cfa6f45750..aaea991d5cf 100644 --- a/code/game/dna/genes/disabilities.dm +++ b/code/game/dna/genes/disabilities.dm @@ -115,6 +115,24 @@ /datum/dna/gene/disability/blindness/New() block=BLINDBLOCK +/datum/dna/gene/disability/colourblindness + name = "Colourblindness" + activation_message = "You feel a peculiar prickling in your eyes while your perception of colour changes." + deactivation_message ="Your eyes tingle unsettlingly, though everything seems to become alot more colourful." + instability = -GENE_INSTABILITY_MODERATE + disability = COLOURBLIND + +/datum/dna/gene/disability/colourblindness/New() + block=COLOURBLINDBLOCK + +/datum/dna/gene/disability/colourblindness/activate(var/mob/M, var/connected, var/flags) + ..() + M.update_client_colour() //Handle the activation of the colourblindness on the mob. + +/datum/dna/gene/disability/colourblindness/deactivate(var/mob/M, var/connected, var/flags) + ..() + M.update_client_colour() //Handle the deactivation of the colourblindness on the mob. + /datum/dna/gene/disability/deaf name="Deafness" activation_message="It's kinda quiet." @@ -126,7 +144,7 @@ block=DEAFBLOCK /datum/dna/gene/disability/deaf/activate(var/mob/M, var/connected, var/flags) - ..(M,connected,flags) + ..() M.EarDeaf(1) /datum/dna/gene/disability/nearsighted @@ -139,7 +157,6 @@ /datum/dna/gene/disability/nearsighted/New() block=GLASSESBLOCK - /datum/dna/gene/disability/lisp name = "Lisp" desc = "I wonder wath thith doeth." diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index f2489a2490a..a2ad15e797b 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -259,8 +259,8 @@ action_icon_state = "genetic_incendiary" -/obj/effect/proc_holder/spell/targeted/immolate/cast(list/targets) - var/mob/living/carbon/L = usr +/obj/effect/proc_holder/spell/targeted/immolate/cast(list/targets,mob/living/user = usr) + var/mob/living/carbon/L = user L.adjust_fire_stacks(0.5) L.visible_message("[L.name] suddenly bursts into flames!") L.IgniteMob() diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 36c9af1c48c..0e8415a15e3 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -57,12 +57,7 @@ var/turf/simulated/T = get_turf(M) if(!istype(T)) return - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/light_available - if(L) - light_available = L.get_clamped_lum()*10 - else - light_available = 5 + var/light_available = T.get_lumcount() * 10 if(light_available <= 2) M.alpha = round(M.alpha * 0.8) else @@ -254,7 +249,6 @@ /mob/living/carbon/slime, /mob/living/carbon/alien/larva, /mob/living/simple_animal/slime, - /mob/living/simple_animal/adultslime, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, /mob/living/simple_animal/lizard, diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index c42ac3e43e3..e159aa44247 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -28,17 +28,17 @@ action_icon_state = "genetic_morph" -/obj/effect/proc_holder/spell/targeted/morph/cast(list/targets) - if(!ishuman(usr)) return +/obj/effect/proc_holder/spell/targeted/morph/cast(list/targets, mob/user = usr) + if(!ishuman(user)) return - if(istype(usr.loc,/mob/)) - to_chat(usr, "You can't change your appearance right now!") + if(istype(user.loc,/mob/)) + to_chat(user, "You can't change your appearance right now!") return - var/mob/living/carbon/human/M=usr + var/mob/living/carbon/human/M = user var/obj/item/organ/external/head/head_organ = M.get_organ("head") var/obj/item/organ/internal/eyes/eyes_organ = M.get_int_organ(/obj/item/organ/internal/eyes) - var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") + var/new_gender = alert(user, "Please select gender.", "Character Generation", "Male", "Female") if(new_gender) if(new_gender == "Male") M.change_gender(MALE) @@ -219,7 +219,7 @@ validtargets += M if(!validtargets.len) - to_chat(usr, "There are no valid targets!") + to_chat(user, "There are no valid targets!") start_recharge() return @@ -229,24 +229,24 @@ revert_cast(user) return - perform(targets) + perform(targets, user = user) -/obj/effect/proc_holder/spell/targeted/remotetalk/cast(list/targets) - if(!ishuman(usr)) return +/obj/effect/proc_holder/spell/targeted/remotetalk/cast(list/targets, mob/user = usr) + if(!ishuman(user)) return var/say = input("What do you wish to say") as text|null if(!say) return say = strip_html(say) for(var/mob/living/target in targets) - log_say("Project Mind: [key_name(usr)]->[key_name(target)]: [say]") + log_say("Project Mind: [key_name(user)]->[key_name(target)]: [say]") if(REMOTE_TALK in target.mutations) - target.show_message("You hear [usr.real_name]'s voice: [say]") + target.show_message("You hear [user.real_name]'s voice: [say]") else target.show_message("You hear a voice that seems to echo around the room: [say]") - usr.show_message("You project your mind into [target.real_name]: [say]") + user.show_message("You project your mind into [target.real_name]: [say]") for(var/mob/dead/observer/G in player_list) - G.show_message("Telepathic message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]") + G.show_message("Telepathic message from [user] ([ghost_follow_link(user, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]") /datum/dna/gene/basic/grant_spell/remoteview name="Remote Viewing" @@ -283,39 +283,39 @@ if(REMOTE_VIEW in M.mutations) remoteviewers += M if(!remoteviewers.len || remoteviewers.len == 1) - to_chat(usr, "No valid targets with remote view were found!") + to_chat(user, "No valid targets with remote view were found!") start_recharge() return targets += input("Choose the target to spy on.", "Targeting") as mob in remoteviewers - perform(targets) + perform(targets, user = user) -/obj/effect/proc_holder/spell/targeted/remoteview/cast(list/targets) - var/mob/living/carbon/human/user - if(ishuman(usr)) - user = usr +/obj/effect/proc_holder/spell/targeted/remoteview/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/H + if(ishuman(user)) + H = user else return var/mob/target - if(istype(user.l_hand, /obj/item/tk_grab) || istype(user.r_hand, /obj/item/tk_grab/)) - to_chat(user, "Your mind is too busy with that telekinetic grab.") - user.remoteview_target = null - user.reset_perspective(0) + if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab/)) + to_chat(H, "Your mind is too busy with that telekinetic grab.") + H.remoteview_target = null + H.reset_perspective(0) return - if(user.client.eye != user.client.mob) - user.remoteview_target = null - user.reset_perspective(0) + if(H.client.eye != user.client.mob) + H.remoteview_target = null + H.reset_perspective(0) return for(var/mob/living/L in targets) target = L if(target) - user.remoteview_target = target - user.reset_perspective(target) + H.remoteview_target = target + H.reset_perspective(target) else - user.remoteview_target = null - user.reset_perspective(0) + H.remoteview_target = null + H.reset_perspective(0) diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index d00acddecf2..7c307295dc7 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -196,5 +196,3 @@ //message_admins("New traitor roll failed. No new traitor.") //else //message_admins("Late Joiner does not have Be Syndicate") - - diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index d8f4a7a3850..16f98927e17 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -51,7 +51,7 @@ var/list/blob_nodes = list() if(!infected_crew.len) return 0 - + ..() return 1 /datum/game_mode/blob/proc/get_blob_candidates() @@ -192,7 +192,7 @@ var/list/blob_nodes = list() declared = 1 if(1) - command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') + event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') if(2) send_intercept(2) diff --git a/code/game/gamemodes/blob/blob_report.dm b/code/game/gamemodes/blob/blob_report.dm index 198c0264dd1..9d24e4992df 100644 --- a/code/game/gamemodes/blob/blob_report.dm +++ b/code/game/gamemodes/blob/blob_report.dm @@ -49,7 +49,7 @@ playsound(comm.loc, "sound/goonstation/machines/printer_dotmatrix.ogg", 50, 1) intercept.name = "Classified Central Command Update" intercept.info = intercepttext - command_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg') + event_announcement.Announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg') return diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index afbc4ec9236..0142d198cc3 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -14,6 +14,7 @@ /obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2, offspring) blob_cores += src processing_objects.Add(src) + poi_list |= src adjustcolors(color) //so it atleast appears if(!overmind) create_overmind(new_overmind) @@ -41,6 +42,7 @@ overmind.blob_core = null overmind = null processing_objects.Remove(src) + poi_list.Remove(src) return ..() /obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 805db2be393..1e67760322c 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -3,13 +3,12 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /datum/game_mode var/list/datum/mind/changelings = list() - /datum/game_mode/changeling name = "changeling" config_tag = "changeling" restricted_jobs = list("AI", "Cyborg") protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Brig Physician", "Internal Affairs Agent", "Nanotrasen Navy Officer", "Special Operations Officer") - protected_species = list("Machine", "Slime People", "Plasmaman") + protected_species = list("Machine") required_players = 15 required_enemies = 1 recommended_enemies = 4 @@ -38,7 +37,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" to_chat(world, "There are alien changelings on the station. Do not let the changelings succeed!") /datum/game_mode/changeling/pre_setup() - if(config.protect_roles_from_antagonist) restricted_jobs += protected_jobs @@ -55,6 +53,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" changeling.restricted_roles = restricted_jobs modePlayer += changelings changeling.special_role = SPECIAL_ROLE_CHANGELING + ..() return 1 else return 0 @@ -68,8 +67,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" ..() - -/datum/game_mode/proc/forge_changeling_objectives(var/datum/mind/changeling) +/datum/game_mode/proc/forge_changeling_objectives(datum/mind/changeling) //OBJECTIVES - Always absorb 5 genomes, plus random traitor objectives. //If they have two objectives as well as absorb, they must survive rather than escape //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting @@ -128,7 +126,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" changeling.objectives += identity_theft return -/datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1) +/datum/game_mode/proc/greet_changeling(datum/mind/changeling, you_are=1) if(you_are) to_chat(changeling.current, "You are a changeling!") to_chat(changeling.current, "Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them.") @@ -144,8 +142,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" obj_count++ return - - /datum/game_mode/proc/remove_changeling(datum/mind/changeling_mind) if(changeling_mind in changelings) changelings -= changeling_mind @@ -170,7 +166,8 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" set_antag_hud(changeling.current, null) /datum/game_mode/proc/grant_changeling_powers(mob/living/carbon/changeling_mob) - if(!istype(changeling_mob)) return + if(!istype(changeling_mob)) + return changeling_mob.make_changeling() /datum/game_mode/proc/auto_declare_completion_changeling() @@ -217,7 +214,6 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" to_chat(world, text) - return 1 /datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind) @@ -227,13 +223,14 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" var/dna_max = 5 //How many total DNA strands the changeling can store for transformation. var/absorbedcount = 1 //Would require at least 1 sample to take on the form of a human var/chem_charges = 20 - var/chem_recharge_rate = 0.5 + var/chem_recharge_rate = 1 var/chem_recharge_slowdown = 0 - var/chem_storage = 50 + var/chem_storage = 75 var/sting_range = 2 var/changelingID = "Changeling" var/geneticdamage = 0 var/isabsorbing = 0 + var/islinking = 0 var/geneticpoints = 10 var/purchasedpowers = list() var/mimicing = "" @@ -242,11 +239,13 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" var/datum/dna/chosen_dna var/obj/effect/proc_holder/changeling/sting/chosen_sting -/datum/changeling/New(var/gender=FEMALE) +/datum/changeling/New(gender=FEMALE) ..() var/honorific - if(gender == FEMALE) honorific = "Ms." - else honorific = "Mr." + if(gender == FEMALE) + honorific = "Ms." + else + honorific = "Mr." if(possible_changeling_IDs.len) changelingID = pick(possible_changeling_IDs) possible_changeling_IDs -= changelingID @@ -258,25 +257,24 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" chem_charges = min(max(0, chem_charges + chem_recharge_rate - chem_recharge_slowdown), chem_storage) geneticdamage = max(0, geneticdamage-1) - -/datum/changeling/proc/GetDNA(var/dna_owner) +/datum/changeling/proc/GetDNA(dna_owner) for(var/datum/dna/DNA in (absorbed_dna + protected_dna)) if(dna_owner == DNA.real_name) return DNA -/datum/changeling/proc/find_dna(var/datum/dna/tDNA) +/datum/changeling/proc/find_dna(datum/dna/tDNA) for(var/datum/dna/D in (absorbed_dna + protected_dna)) if(tDNA.unique_enzymes == D.unique_enzymes && tDNA.uni_identity == D.uni_identity && tDNA.species == D.species) return D return null -/datum/changeling/proc/has_dna(var/datum/dna/tDNA) +/datum/changeling/proc/has_dna(datum/dna/tDNA) if(find_dna(tDNA)) return 1 return 0 // A changeling's DNA is "stale" if their current form's DNA is the oldest DNA in a full list -/datum/changeling/proc/using_stale_dna(var/mob/living/carbon/user) +/datum/changeling/proc/using_stale_dna(mob/living/carbon/user) var/current_dna = find_dna(user.dna) if(absorbed_dna.len < dna_max) return 0 // Still more room for DNA @@ -291,7 +289,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" if(absorbed_dna.len > dna_max) absorbed_dna.Cut(1, (absorbed_dna.len - dna_max) + 1) -/datum/changeling/proc/can_absorb_dna(var/mob/living/carbon/user, var/mob/living/carbon/target) +/datum/changeling/proc/can_absorb_dna(mob/living/carbon/user, mob/living/carbon/target) if(using_stale_dna(user))//If our current DNA is the stalest, we gotta ditch it. to_chat(user, "We have reached our capacity to store genetic information! We must transform before absorbing more.") return @@ -313,18 +311,10 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" to_chat(user, "This creature does not have DNA!") return - if(T.species.flags & NO_SCAN) - to_chat(user, "We do not know how to parse this creature's DNA!") - return - - if(T.species.flags & NO_BLOOD) - to_chat(user, "We are not able to use the DNA of a creature without a circulatory system.") - return - if(has_dna(target.dna)) to_chat(user, "We already have this DNA in storage!") return 1 /proc/check_species_absorb(datum/species/S) - return !((S.flags & NO_DNA) || (S.flags & NO_SCAN) || (S.flags & NO_BLOOD)) + return !(S.flags & NO_DNA) diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 3800597709a..06402a584b7 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -1,3 +1,5 @@ +#define LING_ABSORB_RECENT_SPEECH 8 //The amount of recent spoken lines to gain on absorbing a mob + /obj/effect/proc_holder/changeling/absorbDNA name = "Absorb DNA" desc = "Absorb the DNA of our victim." @@ -26,8 +28,6 @@ var/mob/living/carbon/target = G.affecting return changeling.can_absorb_dna(user,target) - - /obj/effect/proc_holder/changeling/absorbDNA/sting_action(var/mob/user) var/datum/changeling/changeling = user.mind.changeling var/obj/item/weapon/grab/G = user.get_active_hand() @@ -58,12 +58,30 @@ if(!changeling.has_dna(target.dna)) changeling.absorb_dna(target, user) - if(user.nutrition < 450) // Nutrition level before overeat_duration starts ticking for you to become obese. - user.nutrition = min((user.nutrition + target.nutrition), 450) + if(user.nutrition < NUTRITION_LEVEL_WELL_FED) + user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED) if(target.mind)//if the victim has got a mind - target.mind.show_memory(src, 0) //I can read your mind, kekeke. Output all their notes. + target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes. + + //Some of target's recent speech, so the changeling can attempt to imitate them better. + //Recent as opposed to all because rounds tend to have a LOT of text. + var/list/recent_speech = list() + + if(target.say_log.len > LING_ABSORB_RECENT_SPEECH) + recent_speech = target.say_log.Copy(target.say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list + else + recent_speech = target.say_log.Copy() + + if(recent_speech.len) + user.mind.store_memory("Some of [target]'s speech patterns, we should study these to better impersonate them!") + to_chat(user, "Some of [target]'s speech patterns, we should study these to better impersonate them!") + for(var/spoken_memory in recent_speech) + user.mind.store_memory("\"[spoken_memory]\"") + to_chat(user, "\"[spoken_memory]\"") + user.mind.store_memory("We have no more knowledge of [target]'s speech patterns.") + to_chat(user, "We have no more knowledge of [target]'s speech patterns.") if(target.mind.changeling)//If the target was a changeling, suck out their extra juice and objective points! changeling.chem_charges += min(target.mind.changeling.chem_charges, changeling.chem_storage) @@ -72,7 +90,6 @@ target.mind.changeling.absorbed_dna.len = 1 target.mind.changeling.absorbedcount = 0 - changeling.chem_charges=min(changeling.chem_charges+10, changeling.chem_storage) changeling.isabsorbing = 0 @@ -82,8 +99,6 @@ target.Drain() return 1 - - //Absorbs the target DNA. /datum/changeling/proc/absorb_dna(mob/living/carbon/T, var/mob/user) T.dna.real_name = T.real_name //Set this again, just to be sure that it's properly set. @@ -104,3 +119,5 @@ return absorbed_dna |= new_dna trim_dna() + +#undef LING_ABSORB_RECENT_SPEECH diff --git a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm index 83c29ed9109..a9899b33462 100644 --- a/code/game/gamemodes/changeling/powers/augmented_eyesight.dm +++ b/code/game/gamemodes/changeling/powers/augmented_eyesight.dm @@ -7,7 +7,6 @@ helptext = "Grants us thermal vision or flash protection. We will become a lot more vulnerable to flash-based devices while thermal vision is active." chemical_cost = 0 dna_cost = 2 //Would be 1 without thermal vision - var/active = 0 //Whether or not vision is enhanced /obj/effect/proc_holder/changeling/augmented_eyesight/sting_action(mob/living/carbon/human/user) if(!istype(user)) diff --git a/code/game/gamemodes/changeling/powers/glands.dm b/code/game/gamemodes/changeling/powers/glands.dm deleted file mode 100644 index d08bd3021aa..00000000000 --- a/code/game/gamemodes/changeling/powers/glands.dm +++ /dev/null @@ -1,13 +0,0 @@ -/obj/effect/proc_holder/changeling/glands - name = "Engorged Chemical Glands" - desc = "Our chemical glands swell, permitting us to store more chemicals inside of them." - helptext = "Allows us to store an extra 25 units of chemicals, and doubles production rate." - dna_cost = 2 - chemical_cost = -1 - -/obj/effect/proc_holder/changeling/glands/on_purchase(var/mob/user) - ..() - var/datum/changeling/changeling=user.mind.changeling - changeling.chem_storage += 25 - changeling.chem_recharge_rate *=2 - return \ No newline at end of file diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index e587a7db0ab..fb3012cd274 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -24,15 +24,18 @@ if(!user) return 0 to_chat(user, "We transform our appearance.") - user.dna.SetSEState(MONKEYBLOCK,0) - domutcheck(user, null) // Do a pre-mutcheck to cleanly switch from monkey form. - user.dna = chosen_dna + user.dna.SetSEState(MONKEYBLOCK,0,1) + genemutcheck(user,MONKEYBLOCK,null,MUTCHK_FORCED) + user.dna = chosen_dna.Clone() user.real_name = chosen_dna.real_name + if(istype(user)) + user.set_species(chosen_dna.species) + domutcheck(user,null,MUTCHK_FORCED) user.flavor_text = "" - if(ishuman(user)) - user.set_species() + user.dna.UpdateSE() + user.dna.UpdateUI() + user.sync_organ_dna(1) user.UpdateAppearance() - domutcheck(user, null) changeling.purchasedpowers -= src //O.mind.changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/lesserform(null) diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index ea22ba5800a..8ba1e53cb10 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -18,9 +18,10 @@ var/mob/living/carbon/human/H = user if(!istype(H) || !H.species.primitive_form) - to_chat(src, "We cannot perform this ability in this form!") + to_chat(H, "We cannot perform this ability in this form!") return + user.dna = user.dna.Clone() H.visible_message("[H] transforms!") changeling.geneticdamage = 30 to_chat(H, "Our genes cry out!") diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm new file mode 100644 index 00000000000..7c198f5e6af --- /dev/null +++ b/code/game/gamemodes/changeling/powers/linglink.dm @@ -0,0 +1,73 @@ +/obj/effect/proc_holder/changeling/linglink + name = "Hivemind Link" + desc = "Link your victim's mind into the hivemind for personal interrogation" + chemical_cost = 0 + dna_cost = 0 + req_human = 1 + max_genetic_damage = 100 + +/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user) + if(!..()) + return + var/datum/changeling/changeling = user.mind.changeling + var/obj/item/weapon/grab/G = user.get_active_hand() + + if(changeling.islinking) + to_chat(user, "We have already formed a link with the victim!") + return + if(!istype(G)) + to_chat(user, "We must be tightly grabbing a creature in our active hand to link with them!") + return + if(G.state <= GRAB_AGGRESSIVE) + to_chat(user, "We must have a tighter grip to link with this creature!") + return + if(iscarbon(G.affecting)) + var/mob/living/carbon/target = G.affecting + if(!target.mind) + to_chat(user, "The victim has no mind to link to!") + return + if(target.stat == DEAD) + to_chat(user, "The victim is dead, you cannot link to a dead mind!") + return + if(target.mind.changeling) + to_chat(user, "The victim is already a part of the hivemind!") + return + return changeling.can_absorb_dna(user,target) + +/obj/effect/proc_holder/changeling/linglink/sting_action(mob/user) + var/datum/changeling/changeling = user.mind.changeling + var/obj/item/weapon/grab/G = user.get_active_hand() + var/mob/living/carbon/target = G.affecting + changeling.islinking = 1 + for(var/stage = 1, stage<=3, stage++) + switch(stage) + if(1) + to_chat(user, "This creature is compatible. We must hold still...") + if(2) + to_chat(user, "We stealthily stab [target] with a minor proboscis...") + to_chat(target, "You experience a stabbing sensation and your ears begin to ring...") + if(3) + to_chat(user, "You mold the [target]'s mind like clay, they can now speak in the hivemind!") + to_chat(target, "A migraine throbs behind your eyes, you hear yourself screaming - but your mouth has not opened!") + for(var/mob/M in mob_list) + if(all_languages["Changeling"] in M.languages) + to_chat(M, "We can sense a foreign presence in the hivemind...") + target.mind.linglink = 1 + target.add_language("Changeling") + target.say(":g AAAAARRRRGGGGGHHHHH!!") + to_chat(target, "You can now communicate in the changeling hivemind, say \":g message\" to communicate!") + target.reagents.add_reagent("salbutamol", 40) // So they don't choke to death while you interrogate them + sleep(1800) + feedback_add_details("changeling_powers","A[stage]") + if(!do_mob(user, target, 20)) + to_chat(user, "Our link with [target] has ended!") + target.remove_language("Changeling") + changeling.islinking = 0 + target.mind.linglink = 0 + return + + target.remove_language("Changeling") + changeling.islinking = 0 + target.mind.linglink = 0 + to_chat(user, "You cannot sustain the connection any longer, your victim fades from the hivemind") + to_chat(target, "The link cannot be sustained any longer, your connection to the hivemind has faded!") diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index fd5d71e9453..4219032fb96 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -159,18 +159,20 @@ if(!A.requiresID() || A.allowed(user)) //This is to prevent stupid shit like hitting a door with an arm blade, the door opening because you have acces and still getting a "the airlocks motors resist our efforts to force it" message. return - if(A.arePowerSystemsOn()) - to_chat(user, "The airlock's motors resist our efforts to force it.") - return - - else if(A.locked) + if(A.locked) to_chat(user, "The airlock's bolts prevent it from being forced.") return - else - //user.say("Heeeeeeeeeerrre's Johnny!") - user.visible_message("[user] forces the door to open with \his [src]!", "We force the door to open.", "You hear a metal screeching sound.") - A.open(1) + if(A.arePowerSystemsOn()) + user.visible_message("[user] jams [src] into the airlock and starts prying it open!", "We start forcing the airlock open.", \ + "You hear a metal screeching sound.") + playsound(A, 'sound/machines/airlock_alien_prying.ogg', 150, 1) + if(!do_after(user, 150, target = A)) + return + + //user.say("Heeeeeeeeeerrre's Johnny!") + user.visible_message("[user] forces the airlock to open with \his [src]!", "We force the airlock to open.", "You hear a metal screeching sound.") + A.open(2) /***************************************\ diff --git a/code/game/gamemodes/changeling/powers/strained_muscles.dm b/code/game/gamemodes/changeling/powers/strained_muscles.dm index 92cf9ad7fdf..28884c2653a 100644 --- a/code/game/gamemodes/changeling/powers/strained_muscles.dm +++ b/code/game/gamemodes/changeling/powers/strained_muscles.dm @@ -9,11 +9,11 @@ dna_cost = 1 req_human = 1 var/stacks = 0 //Increments every 5 seconds; damage increases over time - var/active = 0 //Whether or not you are a hedgehog + var/enabled = 0 //Whether or not you are a hedgehog /obj/effect/proc_holder/changeling/strained_muscles/sting_action(var/mob/living/carbon/user) - active = !active - if(active) + enabled = !enabled + if(enabled) to_chat(user, "Our muscles tense and strengthen.") else user.status_flags &= ~GOTTAGOFAST @@ -23,10 +23,10 @@ user.Weaken(3) user.emote("gasp") - while(active) + while(enabled) user.status_flags |= GOTTAGOFAST if(user.stat || user.staminaloss >= 90) - active = 0 //Let's use something exact instead of !active where we can. + enabled = 0 //Let's use something exact instead of !enabled where we can. to_chat(user, "Our muscles relax without the energy to strengthen them.") user.status_flags &= ~GOTTAGOFAST user.Weaken(2) @@ -42,7 +42,7 @@ sleep(40) - while(!active) //Damage stacks decrease fairly rapidly while not in sanic mode + while(!enabled) //Damage stacks decrease fairly rapidly while not in sanic mode if(stacks >= 1) stacks-- sleep(20) diff --git a/code/game/gamemodes/changeling/powers/swap_form.dm b/code/game/gamemodes/changeling/powers/swap_form.dm index ce8bda64d03..82baf6d5293 100644 --- a/code/game/gamemodes/changeling/powers/swap_form.dm +++ b/code/game/gamemodes/changeling/powers/swap_form.dm @@ -17,7 +17,7 @@ if((NOCLONE || SKELETON || HUSK) in target.mutations) to_chat(user, "DNA of [target] is ruined beyond usability!") return - if(!istype(target) || issmall(target) || target.species.flags & NO_DNA || target.species.flags & NO_SCAN || target.species.flags & NO_BLOOD) + if(!istype(target) || issmall(target) || target.species.flags & NO_DNA) to_chat(user, "[target] is not compatible with this ability.") return return 1 @@ -28,7 +28,7 @@ var/mob/living/carbon/human/target = G.affecting var/datum/changeling/changeling = user.mind.changeling - to_chat(user, "We tighen our grip. We must hold still....") + to_chat(user, "We tighten our grip. We must hold still....") target.do_jitter_animation(500) user.do_jitter_animation(500) diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index 0df371009a8..648d8ac1cbb 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -27,7 +27,7 @@ /mob/living/carbon/proc/unset_sting() if(mind && mind.changeling && mind.changeling.chosen_sting) - src.mind.changeling.chosen_sting.unset_sting(src) + mind.changeling.chosen_sting.unset_sting(src) /obj/effect/proc_holder/changeling/sting/can_sting(var/mob/user, var/mob/target) if(!..()) @@ -66,8 +66,8 @@ desc = "We silently sting a human, injecting a retrovirus that forces them to transform." helptext = "The victim will transform much like a changeling would. The effects will be obvious to the victim, and the process will damage our genomes." sting_icon = "sting_transform" - chemical_cost = 40 - dna_cost = 2 + chemical_cost = 50 + dna_cost = 3 genetic_damage = 100 var/datum/dna/selected_dna = null @@ -80,6 +80,10 @@ selected_dna = changeling.select_dna("Select the target DNA: ", "Target DNA") if(!selected_dna) return + var/datum/species/newspecies = all_species[selected_dna.species] + if((newspecies.flags & NOTRANSSTING) || newspecies.is_small) + to_chat(user, "The selected DNA is incompatible with our sting.") + return ..() /obj/effect/proc_holder/changeling/sting/transformation/can_sting(var/mob/user, var/mob/target) @@ -87,19 +91,13 @@ return if((HUSK in target.mutations) || (!ishuman(target))) to_chat(user, "Our sting appears ineffective against its DNA.") - return 0 + return FALSE if(ishuman(target)) var/mob/living/carbon/human/H = target - if(H.species.flags & NO_SCAN) //Prevents transforming slimes and killing them instantly - to_chat(user, "This won't work on a creature with abnormal genetic material.") - return 0 - if(H.species.flags & NO_BLOOD) - to_chat(user, "This won't work on a creature without a circulatory system.") - return 0 if(H.species.flags & NO_DNA) to_chat(user, "This won't work on a creature without DNA.") - return 0 - return 1 + return FALSE + return TRUE /obj/effect/proc_holder/changeling/sting/transformation/sting_action(var/mob/user, var/mob/target) add_logs(user, target, "stung", object="transformation sting", addition=" new identity is [selected_dna.real_name]") @@ -122,7 +120,7 @@ target.UpdateAppearance() domutcheck(target, null) feedback_add_details("changeling_powers","TS") - return 1 + return TRUE obj/effect/proc_holder/changeling/sting/extract_dna name = "Extract DNA Sting" diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index f1ff51a42a2..b7c8abefd1d 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -16,12 +16,15 @@ return user.dna = chosen_dna.Clone() user.real_name = chosen_dna.real_name - user.flavor_text = "" if(ishuman(user)) - user.set_species() + user.set_species(chosen_dna.species) + domutcheck(user, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them + user.flavor_text = "" + user.dna.UpdateSE() + user.dna.UpdateUI() + user.sync_organ_dna(1) user.UpdateAppearance() - domutcheck(user, null) - + user.changeling_update_languages(changeling.absorbed_languages) feedback_add_details("changeling_powers","TR") diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 7ef4f0bc7b4..fbb7506f121 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -6,7 +6,7 @@ required_players = 10 required_enemies = 1 // how many of each type are required recommended_enemies = 3 - var/protected_species_changeling = list("Machine", "Slime People") + var/protected_species_changeling = list("Machine") /datum/game_mode/traitor/changeling/announce() to_chat(world, "The current game mode is - Traitor+Changeling!") diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 6a92052eed5..3af75d1f14d 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -99,20 +99,13 @@ var/global/list/all_cults = list() cult += cultist cultist.restricted_roles = restricted_jobs cultist.special_role = SPECIAL_ROLE_CULTIST + ..() return (cult.len>0) /datum/game_mode/cult/post_setup() modePlayer += cult acolytes_needed = acolytes_needed + round((num_players_started() / 10)) - if("sacrifice" in objectives) - var/list/possible_targets = get_unconvertables() - if(!possible_targets.len) - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) - possible_targets += player.mind - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) for(var/datum/mind/cult_mind in cult) equip_cultist(cult_mind.current) @@ -182,10 +175,13 @@ var/global/list/all_cults = list() cult_mind.current.faction |= "cult" var/datum/action/innate/cultcomm/C = new() C.Grant(cult_mind.current) - cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!" + cult_mind.current.create_attack_log("Has been converted to the cult!") if(jobban_isbanned(cult_mind.current, ROLE_CULTIST)) replace_jobbaned_player(cult_mind.current, ROLE_CULTIST) update_cult_icons_added(cult_mind) + if(GAMEMODE_IS_CULT) + var/datum/game_mode/cult/cult_mode = ticker.mode + cult_mode.check_numbers() return 1 @@ -326,7 +322,7 @@ var/global/list/all_cults = list() feedback_add_details("cult_objective","cult_demons|FAIL") if("convert")//convert half the crew - if(obj_count < objectives.len) + if(cult.len >= convert_target) explanation = "Convert [convert_target] crewmembers ([cult.len] cultists at round end). Success!" feedback_add_details("cult_objective","cult_convertion|SUCCESS") else @@ -334,7 +330,7 @@ var/global/list/all_cults = list() feedback_add_details("cult_objective","cult_convertion|FAIL") if("bloodspill")//cover a large portion of the station in blood - if(obj_count < objectives.len) + if(max_spilled_blood >= spilltarget) explanation = "Cover [spilltarget] tiles of the station in blood (The peak number of covered tiles was: [max_spilled_blood]). Success!" feedback_add_details("cult_objective","cult_bloodspill|SUCCESS") else diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index de13c11d852..bfe25eba5d5 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -34,6 +34,6 @@ if(iscultist(M)) to_chat(M, my_message) else if(M in dead_mob_list) - to_chat(M, " (F) [my_message] ") + to_chat(M, " (F) [my_message] ") log_say("[user.real_name]/[user.key] : [message]") \ No newline at end of file diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index edf0912c4d6..cbbe5590475 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -7,6 +7,7 @@ force = 30 throwforce = 10 sharp = 1 + edge = 1 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") diff --git a/code/game/gamemodes/cult/cult_objectives.dm b/code/game/gamemodes/cult/cult_objectives.dm index a84a83be688..2fe00023c20 100644 --- a/code/game/gamemodes/cult/cult_objectives.dm +++ b/code/game/gamemodes/cult/cult_objectives.dm @@ -155,13 +155,11 @@ if(!sacrificed.len) var/list/possible_targets = list() for(var/mob/living/carbon/human/player in player_list) - if(is_secure_level(player.z)) //We can't sacrifice people that are on the centcom z-level - continue if(player.mind && !is_convertable_to_cult(player.mind) && (player.stat != DEAD)) possible_targets += player.mind if(!possible_targets.len) - //There are no living Unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers + //There are no living Unconvertables on the station. Looking for a Sacrifice Target among the ordinary crewmembers for(var/mob/living/carbon/human/player in player_list) if(is_secure_level(player.z)) //We can't sacrifice people that are on the centcom z-level continue @@ -172,8 +170,7 @@ sacrifice_target = pick(possible_targets) possible_objectives |= "sacrifice" else - message_admins("Didn't find a suitable sacrifice target...what the hell? Shout at a coder.") - log_admin("Didn't find a suitable sacrifice target...what the hell? Shout at a coder.") + log_runtime(EXCEPTION("Didn't find a suitable sacrifice target...what the hell? Shout at a coder.")) if(!mass_convert) var/living_crew = 0 @@ -192,12 +189,9 @@ if(total < 15) message_admins("There are [total] players, too little for the mass convert objective!") log_admin("There are [total] players, too little for the mass convert objective!") - else if(total > 50) - message_admins("There are [total] players, too many for the mass convert objective!") - log_admin("There are [total] players, too many for the mass convert objective!") else possible_objectives |= "convert" - convert_target = round(total / 2) + convert_target = rand(9,15) if(!possible_objectives.len)//No more possible objectives, time to summon Nar-Sie message_admins("No suitable objectives left! Nar-Sie objective unlocked.") diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 72b5bfa292b..1f35890373c 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -38,7 +38,7 @@ var/selection_prompt = "Choose your weapon, nerdwad" var/creation_delay = 2400 var/list/choosable_items = list( - "A coder forgot to set this" = /obj/item/weapon/bananapeel + "A coder forgot to set this" = /obj/item/weapon/grown/bananapeel ) var/creation_message = "A dank smoke comes out, and you pass out. When you come to, you notice a %ITEM%!" diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index da0cdc79e94..752e8e353d0 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -12,7 +12,11 @@ return /obj/effect/rune/proc/check_icon() - icon = get_rune_cult(invocation) + if(!ticker.mode)//work around for maps with runes and cultdat is not loaded all the way + var/bits = make_bit_triplet() + icon = get_rune(bits) + else + icon = get_rune_cult(invocation) /obj/item/weapon/tome name = "arcane tome" @@ -36,7 +40,10 @@ canbypass = 1 /obj/item/weapon/tome/New() - icon_state = ticker.mode.cultdat.tome_icon + if(!ticker.mode) + icon_state = "tome" + else + icon_state = ticker.mode.cultdat.tome_icon ..() /obj/item/weapon/tome/examine(mob/user) @@ -151,7 +158,7 @@ text += "Talisman of Stunning
Attacking a target will knock them down for a long duration in addition to inhibiting their speech. \ Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead.

" - text += "Talisman of Armaments
The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola, and a pair of boots. Any items that cannot \ + text += "Talisman of Armaments
The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola. Any items that cannot \ be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.

" text += "Talisman of Horrors
The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.

" @@ -194,10 +201,9 @@ return 1 /obj/item/weapon/tome/proc/finale_runes_ok(mob/living/user, obj/effect/rune/rune_to_scribe) - - if(ticker.mode.name == "cult") - if(!canbypass == 1)//not an admin-tome, check things - var/datum/game_mode/cult/cult_mode = ticker.mode + var/datum/game_mode/cult/cult_mode = ticker.mode + if(GAMEMODE_IS_CULT) + if(!canbypass)//not an admin-tome, check things if(!cult_mode.narsie_condition_cleared) to_chat(user, "There is still more to do before unleashing [cult_mode.cultdat.entity_name] power!") return 0 @@ -207,23 +213,22 @@ if(cult_mode.demons_summoned) to_chat(user, "\"We are already here. There is no need to try to summon us now.\"") return 0 - if(!(CULT_ELDERGOD in cult_mode.objectives) || !(CULT_SLAUGHTER in cult_mode.objectives)) + if(!((CULT_ELDERGOD in cult_mode.objectives) || (CULT_SLAUGHTER in cult_mode.objectives))) to_chat(user, "[cult_mode.cultdat.entity_name]'s power does not wish to be unleashed!") return 0 - var/confirm_final = alert(user, "This is the FINAL step to summon your dietys power, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") - if(confirm_final == "No") - to_chat(user, "You decide to prepare further before scribing the rune.") - return - else - return 1 + var/confirm_final = alert(user, "This is the FINAL step to summon your dietys power, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for [cult_mode.cultdat.entity_name]!", "No") + if(confirm_final == "No" || confirm_final == null) + to_chat(user, "You decide to prepare further before scribing the rune.") + return 0 + else + return 1 else//the game mode is not cult..but we ARE a cultist...ALL ON THE ADMINBUS - if(!canbypass == 1)//not an admin-tome, check things - var/confirm_final = alert(user, "This is the FINAL step to summon your dietys power, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") - if(confirm_final == "No") - to_chat(user, "You decide to prepare further before scribing the rune.") - return 0 - else - return 1 + var/confirm_final = alert(user, "This is the FINAL step to summon your dietys power, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for [cult_mode.cultdat.entity_name]!", "No") + if(confirm_final == "No" || confirm_final == null) + to_chat(user, "You decide to prepare further before scribing the rune.") + return 0 + else + return 1 /obj/item/weapon/tome/proc/scribe_rune(mob/living/user) var/turf/runeturf = get_turf(user) @@ -273,6 +278,8 @@ N.icon_state = "shield-cult" N.health = 60 shields |= N + else + return//don't do shit var/mob/living/carbon/human/H = user var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot") diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 68b13bb05aa..d4e78501639 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -153,6 +153,16 @@ structure_check() searches for nearby cultist structures required for the invoca L.changeNext_move(CLICK_CD_MELEE)//THIS IS WHY WE CAN'T HAVE NICE THINGS do_invoke_glow() +/obj/effect/rune/proc/burn_invokers(var/list/mobstoburn) + for(var/M in mobstoburn) + var/mob/living/L = M + to_chat(L, "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"") + if(L.reagents) + L.reagents.add_reagent("hell_water", 10) + L.Weaken(7) + L.Stun(7) + fail_invoke() + /obj/effect/rune/proc/do_invoke_glow() var/oldtransform = transform spawn(0) //animate is a delay, we want to avoid being delayed @@ -324,6 +334,7 @@ var/list/teleport_runes = list() /obj/effect/rune/convert/invoke(var/list/invokers) var/list/convertees = list() var/turf/T = get_turf(src) + for(var/mob/living/M in T.contents) if(!iscultist(M) && !isloyal(M)) convertees.Add(M) @@ -341,6 +352,7 @@ var/list/teleport_runes = list() log_game("Convert rune failed - convertee could not be converted") return ..() + new_cultist.visible_message("[new_cultist] writhes in pain as the markings below them glow a bloody red!", \ "AAAAAAAAAAAAAA-") ticker.mode.add_cultist(new_cultist.mind, 1) @@ -473,36 +485,32 @@ var/list/teleport_runes = list() if(used) return var/mob/living/user = invokers[1] - if(istype(ticker.mode.name, "cult")) - var/datum/game_mode/cult/cult_mode = ticker.mode - if(!is_station_level(user.z)) - message_admins("[user.real_name]([user.ckey]) tried to summon Nar-Sie off station") - for(var/M in invokers) - var/mob/living/L = M - to_chat(L, "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"") - if(L.reagents) - L.reagents.add_reagent("hell_water", 10) - L.Weaken(7) - L.Stun(7) - fail_invoke() - log_game("Summon Nar-Sie rune failed - off station Z level") - return - if(!cult_mode.eldergod) - for(var/M in invokers) - to_chat(M, "[ticker.mode.cultdat.entity_name] is already on this plane!") - log_game("Summon Nar-Sie rune failed - already summoned") - return - //BEGIN THE SUMMONING - used = 1 - color = rgb(255, 0, 0) - ..() - world << 'sound/effects/dimensional_rend.ogg' - to_chat(world, "The veil... is... TORN!!!--") - icon_state = "rune_large_distorted" - var/turf/T = get_turf(src) - sleep(40) - new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed - cult_mode.eldergod = 0 + var/datum/game_mode/cult/cult_mode = ticker.mode + if(!(CULT_ELDERGOD in cult_mode.objectives)) + message_admins("[key_name_admin(user)] tried to summonn an eldritch horror when the objective was wrong") + burn_invokers(invokers) + log_game("Summon Nar-Sie rune failed - improper objective") + if(!is_station_level(user.z)) + message_admins("[key_name_admin(user)] tried to summon an eldritch horror off station") + burn_invokers(invokers) + log_game("Summon Nar-Sie rune failed - off station Z level") + return + if(!cult_mode.eldergod) + for(var/M in invokers) + to_chat(M, "[ticker.mode.cultdat.entity_name] is already on this plane!") + log_game("Summon god rune failed - already summoned") + return + //BEGIN THE SUMMONING + used = 1 + color = rgb(255, 0, 0) + ..() + world << 'sound/effects/dimensional_rend.ogg' + to_chat(world, "The veil... is... TORN!!!--") + icon_state = "rune_large_distorted" + var/turf/T = get_turf(src) + sleep(40) + new /obj/singularity/narsie/large(T) //Causes Nar-Sie to spawn even if the rune has been removed + cult_mode.eldergod = 0 /obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. if((istype(I, /obj/item/weapon/tome) && iscultist(user))) @@ -562,56 +570,41 @@ var/list/teleport_runes = list() if(used) return var/mob/living/user = invokers[1] - if(istype(ticker.mode.name, "cult")) - var/datum/game_mode/cult/cult_mode = ticker.mode - if(!(CULT_SLAUGHTER in cult_mode.objectives)) - message_admins("[usr.real_name]([user.ckey]) tried to summon demons when the objective was wrong") - for(var/M in invokers) - var/mob/living/L = M - to_chat(L, "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"") - if(L.reagents) - L.reagents.add_reagent("hell_water", 10) - L.Weaken(7) - L.Stun(7) - fail_invoke() - log_game("Summon Demons rune failed - improper objective") + var/datum/game_mode/cult/cult_mode = ticker.mode + if(!(CULT_SLAUGHTER in cult_mode.objectives)) + message_admins("[usr.real_name]([user.ckey]) tried to summon demons when the objective was wrong") + burn_invokers(invokers) + log_game("Summon Demons rune failed - improper objective") + return + if(!is_station_level(user.z)) + message_admins("[user.real_name]([user.ckey]) tried to summon demons off station") + burn_invokers(invokers) + log_game("Summon demons rune failed - off station Z level") + return + if(cult_mode.demons_summoned) + for(var/M in invokers) + to_chat(M, "Demons are already on this plane!") + log_game("Summon Demons rune failed - already summoned") return - if(!is_station_level(user.z)) - message_admins("[user.real_name]([user.ckey]) tried to summon demons off station") - for(var/M in invokers) - var/mob/living/L = M - to_chat(L, "\"YOUR SOUL BURNS WITH YOUR ARROGANCE!!!\"") - if(L.reagents) - L.reagents.add_reagent("hell_water", 10) - L.Weaken(7) - L.Stun(7) - fail_invoke() - log_game("Summon demons rune failed - off station Z level") - return - if(cult_mode.demons_summoned) - for(var/M in invokers) - to_chat(M, "Demons are already on this plane!") - log_game("Summon Demons rune failed - already summoned") - return - //BEGIN THE SLAUGHTER - used = 1 - for(var/mob/living/M in range(1,src)) - if(iscultist(M)) - M.say("TOK-LYR RQA-NAP SHA-NEX!!") - world << 'sound/effects/dimensional_rend.ogg' - to_chat(world, "A hellish cacaphony bombards from all around as something awful tears through the world...") - icon_state = "rune_large_distorted" - sleep(55) - to_chat(world, "\"LIBREATE TE EX INFERIS!\"")//Fethas note:I COULDN'T HELP IT OKAY?! - visible_message("[src] melts away into blood, and three horrific figures emerge from within!") - var/turf/T = get_turf(src) - new /mob/living/simple_animal/slaughter/cult(T) - new /mob/living/simple_animal/slaughter/cult(T, pick(NORTH, EAST, SOUTH, WEST)) - new /mob/living/simple_animal/slaughter/cult(T, pick(NORTHEAST, SOUTHEAST, NORTHWEST, SOUTHWEST)) - cult_mode.demons_summoned = 1 - shuttle_master.emergency.request(null, 0.5,null) - cult_mode.third_phase() - qdel(src) + //BEGIN THE SLAUGHTER + used = 1 + for(var/mob/living/M in range(1,src)) + if(iscultist(M)) + M.say("TOK-LYR RQA-NAP SHA-NEX!!") + world << 'sound/effects/dimensional_rend.ogg' + to_chat(world, "A hellish cacaphony bombards from all around as something awful tears through the world...") + icon_state = "rune_large_distorted" + sleep(55) + to_chat(world, "\"LIBREATE TE EX INFERIS!\"")//Fethas note:I COULDN'T HELP IT OKAY?! + visible_message("[src] melts away into blood, and three horrific figures emerge from within!") + var/turf/T = get_turf(src) + new /mob/living/simple_animal/slaughter/cult(T) + new /mob/living/simple_animal/slaughter/cult(T, pick(NORTH, EAST, SOUTH, WEST)) + new /mob/living/simple_animal/slaughter/cult(T, pick(NORTHEAST, SOUTHEAST, NORTHWEST, SOUTHWEST)) + cult_mode.demons_summoned = 1 + shuttle_master.emergency.request(null, 0.5,null) + cult_mode.third_phase() + qdel(src) //Rite of Resurrection: Requires two corpses. Revives one and gibs the other. @@ -836,7 +829,7 @@ var/list/teleport_runes = list() var/mob/living/user = invokers[1] var/list/cultists = list() for(var/datum/mind/M in ticker.mode.cult) - if(!(M.current in invokers) && M.current.stat != DEAD) + if(!(M.current in invokers) && M.current && M.current.stat != DEAD) cultists |= M.current var/mob/living/cultist_to_summon = input(user, "Who do you wish to call to [src]?", "Followers of [ticker.mode.cultdat.entity_title3]") as null|anything in cultists if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) @@ -975,6 +968,7 @@ var/list/teleport_runes = list() var/mob/living/carbon/human/new_human = new(get_turf(src)) new_human.real_name = ghost_to_spawn.real_name new_human.alpha = 150 //Makes them translucent + new_human.color = "grey" //heh..cult greytide...litterly... ..() visible_message("A cloud of red mist forms above [src], and from within steps... a man.") to_chat(user, "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...") @@ -1000,4 +994,4 @@ var/list/teleport_runes = list() "Your link to the world fades. Your form breaks apart.") for(var/obj/I in new_human) new_human.unEquip(I) - new_human.dust() \ No newline at end of file + new_human.dust() diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 1d0ac22c81c..1b7d1bee5a9 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -272,15 +272,14 @@ "You speak the words of the talisman, arming yourself!") H.equip_or_collect(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), slot_wear_suit) H.equip_or_collect(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back) - H.drop_item() H.put_in_hands(new /obj/item/weapon/melee/cultblade(user)) H.put_in_hands(new /obj/item/weapon/restraints/legcuffs/bola/cult(user)) /obj/item/weapon/paper/talisman/armor/attack(mob/living/target, mob/living/user) if(iscultist(user) && iscultist(target)) user.drop_item() - invoke(target) qdel(src) + invoke(target) return ..() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index c52b54e6f7b..b2344639c1d 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -31,7 +31,7 @@ var/ert_disabled = 0 var/uplink_welcome = "Syndicate Uplink Console:" var/uplink_uses = 20 - var/datum/cult_info/cultdat = new /datum/cult_info() //here instead of cult for adminbus purposes + var/datum/cult_info/cultdat //here instead of cult for adminbus purposes var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) @@ -46,7 +46,6 @@ ///Checks to see if the game can be setup and ran with the current number of players or whatnot. /datum/game_mode/proc/can_start() var/playerC = 0 - cultdat = setupcult() for(var/mob/new_player/player in player_list) if((player.client)&&(player.ready)) playerC++ @@ -63,6 +62,7 @@ ///pre_setup() ///Attempts to select players for special roles the mode might have. /datum/game_mode/proc/pre_setup() + return 1 @@ -334,6 +334,7 @@ /datum/game_mode/New() newscaster_announcements = pick(newscaster_standard_feeds) + cultdat = setupcult() ////////////////////////// //Reports player logouts// diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index b51a6074ec9..5a3d0599c8c 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -407,7 +407,7 @@ var/round_start_time = 0 if(player.client) if(player.client.karma_spent == 0) - if(player.get_preference(DISABLE_KARMA_REMINDER)) + if(!player.get_preference(DISABLE_KARMA_REMINDER)) var/dat dat += {"Karma Reminder

Karma Reminder


You have not yet spent your karma for the round, surely there is a player who was worthy of receiving
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 70207a75598..4819ab20671 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -53,6 +53,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' for(var/datum/mind/raider in raiders) raider.assigned_role = "MODE" raider.special_role = SPECIAL_ROLE_RAIDER + ..() return 1 /datum/game_mode/heist/pre_setup() diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 9842757dc8c..a41f86020d5 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -30,7 +30,7 @@ set name = "Doomsday Device" to_chat(src, "Nuclear device armed.") - command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') + event_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') set_security_level("delta") nuking = 1 var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(src) diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 32e4b081e94..db86c482f03 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -42,7 +42,7 @@ for(var/i=1,i<=abductor_teams,i++) if(!make_abductor_team(i)) return 0 - + ..() return 1 /datum/game_mode/abduction/proc/make_abductor_team(team_number,preset_agent=null,preset_scientist=null) @@ -134,7 +134,7 @@ equip_scientist(H,team_number) greet_scientist(scientist,team_number) update_abductor_icons_added(scientist) - + return ..() //Used for create antag buttons @@ -341,17 +341,17 @@ else return 0 return 0 - + /datum/game_mode/proc/remove_abductor(datum/mind/abductor_mind) if(abductor_mind in abductors) ticker.mode.abductors -= abductor_mind abductor_mind.special_role = null - abductor_mind.current.attack_log += "\[[time_stamp()]\] No longer abductor" + abductor_mind.current.create_attack_log("No longer abductor") if(issilicon(abductor_mind.current)) to_chat(abductor_mind.current, "You have been turned into a robot! You are no longer an abductor.") else to_chat(abductor_mind.current, "You have been brainwashed! You are no longer an abductor.") - ticker.mode.update_abductor_icons_added(abductor_mind) + ticker.mode.update_abductor_icons_added(abductor_mind) /datum/game_mode/proc/update_abductor_icons_added(datum/mind/alien_mind) var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_ABDUCTOR] diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index a074773932b..56c52797c0d 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -313,7 +313,7 @@ to_chat(src, "You plunge your probosci deep into the cortex of the host brain, interfacing directly with their nervous system.") to_chat(host, "You feel a strange shifting sensation behind your eyes as an alien consciousness displaces yours.") var/borer_key = src.key - host.attack_log += text("\[[time_stamp()]\] [key_name(src)] has assumed control of [key_name(host)]") + host.create_attack_log("[key_name(src)] has assumed control of [key_name(host)]") msg_admin_attack("[key_name_admin(src)] has assumed control of [key_name_admin(host)]") // host -> brain var/h2b_id = host.computer_id @@ -457,7 +457,7 @@ if(host_brain) - host.attack_log += text("\[[time_stamp()]\] [host_brain.name] ([host_brain.ckey]) has taken control back from [src.name] ([host.ckey])") + host.create_attack_log("[host_brain.name] ([host_brain.ckey]) has taken control back from [src.name] ([host.ckey])") msg_admin_attack("[host_brain.name] ([host_brain.ckey]) has taken control back from [src.name] ([host.ckey]) (JMP)") // host -> self var/h2s_id = host.computer_id diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 56bb4dd14c5..70b5f82172f 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -6,7 +6,7 @@ icon_state = "swarmer_unactivated" /obj/item/unactivated_swarmer/New() - notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "(Click to enter)", source = src, attack_not_jump = 1) + notify_ghosts("An unactivated swarmer has been created in [get_area(src)]!", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK) ..() /obj/item/unactivated_swarmer/Topic(href, href_list) @@ -63,7 +63,7 @@ mob_size = MOB_SIZE_TINY ventcrawler = 2 ranged = 1 - ranged_cooldown_cap = 1 + ranged_cooldown_time = 20 universal_speak = 0 universal_understand = 0 projectilesound = 'sound/weapons/taser2.ogg' diff --git a/code/game/gamemodes/miniantags/guardian/guardian.dm b/code/game/gamemodes/miniantags/guardian/guardian.dm index b3319c34ecb..94a7895bf51 100644 --- a/code/game/gamemodes/miniantags/guardian/guardian.dm +++ b/code/game/gamemodes/miniantags/guardian/guardian.dm @@ -496,7 +496,7 @@ melee_damage_upper = 10 damage_transfer = 0.9 projectiletype = /obj/item/projectile/guardian - ranged_cooldown_cap = 1 + ranged_cooldown_time = 1 projectilesound = 'sound/effects/hit_on_shattered_glass.ogg' ranged = 1 rapid = 1 diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 6a75c3e9d01..f263d658f6b 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -36,6 +36,7 @@ anchored = 1 mob_size = MOB_SIZE_TINY pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) var/essence = 75 //The resource of revenants. Max health is equal to three times this amount var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount. diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index 0f9173c31ea..85560dda620 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -111,7 +111,6 @@ action_icon_state = "r_nightvision" action_background_icon_state = "bg_revenant" - //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob /obj/effect/proc_holder/spell/targeted/revenant_transmit name = "Transmit" @@ -127,12 +126,12 @@ /obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) for(var/mob/living/M in targets) spawn(0) - var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "") + var/msg = stripped_input(user, "What do you wish to tell [M]?", null, "") if(!msg) charge_counter = charge_max return log_say("RevenantTransmit: [key_name(user)]->[key_name(M)] : [msg]") - to_chat(usr, "You transmit to [M]: [msg]") + to_chat(user, "You transmit to [M]: [msg]") to_chat(M, "An alien voice resonates from all around... [msg]") diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 2750341e982..6988d2b16dd 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -193,10 +193,9 @@ return ..() /datum/action/innate/demon/whisper/proc/choose_targets(mob/user = usr)//yes i am copying from telepathy..hush... - var/list/targets = new /list() - var/list/validtargets = new /list() - for(var/mob/M in view(user.client.view, user)) - if(M && M.mind) + var/list/validtargets = list() + for(var/mob/living/M in view(user.client.view, get_turf(user))) + if(M && M.mind && M.stat != DEAD) if(M == user) continue @@ -206,15 +205,12 @@ to_chat(usr, "There are no valid targets!") return - targets += input("Choose the target to talk to.", "Targeting") as null|mob in validtargets - - if(!targets.len || !targets[1]) - return + var/mob/living/target = input("Choose the target to talk to.", "Targeting") as null|mob in validtargets + return target /datum/action/innate/demon/whisper/Activate() - var/list/choice = choose_targets() - - if(!choice.len) + var/mob/living/choice = choose_targets() + if(!choice) return var/msg = stripped_input(usr, "What do you wish to tell [choice]?", null, "") diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm index 74038879fd7..15f5493543e 100644 --- a/code/game/gamemodes/nations/nations.dm +++ b/code/game/gamemodes/nations/nations.dm @@ -23,7 +23,7 @@ datum/game_mode/nations return ..() /datum/game_mode/nations/proc/send_intercept() - command_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ + event_announcement.Announce("Due to recent and COMPLETELY UNFOUNDED allegations of massive fraud and insider trading \ affecting trillions of investors, the Nanotrasen Corporation has decided to liquidate all \ assets of the Centcom Division in order to pay the massive legal fees that will be incurred \ during the following centuries long court process. Therefore, all current employment contracts \ diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 5d9a880e12e..a7f3b36fc74 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -55,6 +55,7 @@ proc/issyndicate(mob/living/M as mob) /datum/game_mode/nuclear/pre_setup() + ..() return 1 /datum/game_mode/proc/remove_operative(datum/mind/operative_mind) @@ -63,13 +64,13 @@ proc/issyndicate(mob/living/M as mob) operative_mind.special_role = null for(var/datum/objective/nuclear/O in operative_mind.objectives) operative_mind.objectives -= O - operative_mind.current.attack_log += "\[[time_stamp()]\] No longer nuclear operative" + operative_mind.current.create_attack_log("No longer nuclear operative") if(issilicon(operative_mind.current)) to_chat(operative_mind.current, "You have been turned into a robot! You are no longer a Syndicate operative.") else to_chat(operative_mind.current, "You have been brainwashed! You are no longer a Syndicate operative.") - ticker.mode.update_synd_icons_removed(operative_mind) - + ticker.mode.update_synd_icons_removed(operative_mind) + //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// @@ -161,8 +162,8 @@ proc/issyndicate(mob/living/M as mob) head_organ.b_hair = color2B(hair_c) M.change_eye_color(color2R(eye_c), color2G(eye_c), color2B(eye_c)) M.s_tone = skin_tone - head_organ.h_style = random_hair_style(M.gender, head_organ.species.name) - head_organ.f_style = random_facial_hair_style(M.gender, head_organ.species.name) + head_organ.h_style = random_hair_style(M.gender, head_organ.species.name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.species.name) M.body_accessory = null M.regenerate_icons() M.update_body() @@ -299,7 +300,7 @@ proc/issyndicate(mob/living/M as mob) /datum/game_mode/nuclear/declare_completion() var/disk_rescued = 1 - for(var/obj/item/weapon/disk/nuclear/D in world) + for(var/obj/item/weapon/disk/nuclear/D in poi_list) if(!D.onCentcom()) disk_rescued = 0 break diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index 790c6a18e34..089e91cdbec 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -35,7 +35,7 @@ return var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them." - command_announcement.Announce(war_declaration, "Declaration of War", 'sound/effects/siren.ogg') + event_announcement.Announce(war_declaration, "Declaration of War", 'sound/effects/siren.ogg') to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.") for(var/obj/machinery/computer/shuttle/syndicate/S in machines) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 060dd76cc66..6e50736e722 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -32,10 +32,12 @@ var/bomb_set r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. wires = new/datum/wires/nuclearbomb(src) previous_level = get_security_level() + poi_list |= src /obj/machinery/nuclearbomb/Destroy() qdel(wires) wires = null + poi_list.Remove(src) return ..() /obj/machinery/nuclearbomb/process() @@ -181,7 +183,7 @@ var/bomb_set ui.open() ui.set_auto_update(1) -/obj/machinery/nuclearbomb/ui_data(mob/user, datum/topic_state/state) +/obj/machinery/nuclearbomb/ui_data(mob/user, datum/topic_state/state) var/data[0] data["is_syndicate"] = is_syndicate data["hacking"] = 0 @@ -392,10 +394,7 @@ var/bomb_set /obj/item/weapon/disk/nuclear name = "nuclear authentication disk" desc = "Better keep this safe." - icon = 'icons/obj/items.dmi' icon_state = "nucleardisk" - item_state = "card-id" - w_class = 1 /obj/item/weapon/disk/nuclear/New() ..() diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index fd6f07960e1..5b912908046 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -192,19 +192,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \ if(shuttle_master.emergency.areaInstance != A) return 0 - for(var/mob/living/player in player_list) - if(player.mind && player.mind != owner) - if(player.stat != DEAD) - if(issilicon(player)) //Borgs are technically dead anyways - continue - if(isanimal(player)) //Poly does not own the shuttle - continue - if(player.mind.special_role && !(player.mind.special_role == SPECIAL_ROLE_ERT)) //Is antag, and not ERT - continue - - if(get_area(player) == A) - return 0 - return 1 + return shuttle_master.emergency.is_hijacked() /datum/objective/hijackclone explanation_text = "Hijack the emergency shuttle by ensuring only you (or your copies) escape." @@ -295,11 +283,11 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \ var/target_real_name // Has to be stored because the target's real_name can change over the course of the round /datum/objective/escape/escape_with_identity/find_target() - var/list/possible_targets = list() //Copypasta because NO_SCAN races, yay for snowflakes. + var/list/possible_targets = list() //Copypasta because NO_DNA races, yay for snowflakes. for(var/datum/mind/possible_target in ticker.minds) if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != DEAD) && possible_target.current.client) var/mob/living/carbon/human/H = possible_target.current - if(!(H.species.flags & NO_SCAN)) + if(!(H.species.flags & NO_DNA)) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -455,12 +443,12 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) \ if(ticker.current_state == GAME_STATE_SETTING_UP) for(var/mob/new_player/P in player_list) if(P.client && P.ready && P.mind != owner) - if(P.client.prefs && (P.client.prefs.species == "Vox" || P.client.prefs.species == "Slime People" || P.client.prefs.species == "Machine")) // Special check for species that can't be absorbed. No better solution. + if(P.client.prefs && (P.client.prefs.species == "Machine")) // Special check for species that can't be absorbed. No better solution. continue n_p++ else if(ticker.current_state == GAME_STATE_PLAYING) for(var/mob/living/carbon/human/P in player_list) - if(P.species.flags & NO_SCAN) + if(P.species.flags & NO_DNA) continue if(P.client && !(P.mind in ticker.mode.changelings) && P.mind!=owner) n_p++ diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 461fe0e4ca7..1a42ae58d61 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -245,7 +245,7 @@ carbon_mob.flash_eyes(1, 1) rev_mind.current.Stun(5) to_chat(rev_mind.current, " You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!") - rev_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the revolution!" + rev_mind.current.create_attack_log("Has been converted to the revolution!") rev_mind.special_role = SPECIAL_ROLE_REV update_rev_icons_added(rev_mind) if(jobban_isbanned(rev_mind.current, ROLE_REV)) @@ -263,7 +263,7 @@ if((rev_mind in revolutionaries) || remove_head) revolutionaries -= rev_mind rev_mind.special_role = null - rev_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the revolution!" + rev_mind.current.create_attack_log("Has renounced the revolution!") if(beingborged) to_chat(rev_mind.current, "The frame's firmware detects and deletes your neural reprogramming! You remember nothing[remove_head ? "." : " but the name of the one who flashed you."]") diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 61abe7bf39e..c785c511304 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -35,6 +35,7 @@ // Standard muts BLINDBLOCK = getAssignedBlock("BLIND", numsToAssign) + COLOURBLINDBLOCK = getAssignedBlock("COLOURBLIND", numsToAssign) DEAFBLOCK = getAssignedBlock("DEAF", numsToAssign) HULKBLOCK = getAssignedBlock("HULK", numsToAssign, DNA_HARD_BOUNDS, good=1) TELEBLOCK = getAssignedBlock("TELE", numsToAssign, DNA_HARD_BOUNDS, good=1) @@ -150,12 +151,15 @@ ticker.syndicate_coalition.Add(S) /proc/setupcult() + var/static/picked_cult // Only needs to get picked once + + if(picked_cult) + return picked_cult + var/random_cult = pick(all_cults) - var/picked_cult = new random_cult() //this seems redundent as fuck - log_startup_progress("Summoning eldritch horrors...") - if(!picked_cult)//shouldn't happen BUT JUST TO BE SURE LET US KNOW - log_startup_progress(" Failed to select a cult datum, Shank a coder!") - else - log_startup_progress(" [picked_cult] has risen!") + picked_cult = new random_cult() + + if(!picked_cult) + log_runtime(EXCEPTION("Cult datum creation failed")) //todo:add adminonly datum var, check for said var here... - return picked_cult \ No newline at end of file + return picked_cult diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index c9f29cefc2f..10dac6414d2 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -97,6 +97,11 @@ Made by Xhuis shadow.special_role = SPECIAL_ROLE_SHADOWLING shadow.restricted_roles = restricted_jobs shadowlings-- + + var/thrall_scaling = round(num_players() / 3) + required_thralls = Clamp(thrall_scaling, 15, 25) + + ..() return 1 @@ -147,9 +152,8 @@ Made by Xhuis shadowling_thralls += new_thrall_mind new_thrall_mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL update_shadow_icons_added(new_thrall_mind) - new_thrall_mind.current.attack_log += "\[[time_stamp()]\] Became a thrall" + new_thrall_mind.current.create_attack_log("Became a thrall") new_thrall_mind.current.add_language("Shadowling Hivemind") - new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare(null)) new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk(null)) new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_vision/thrall(null)) to_chat(new_thrall_mind.current, "You see the truth. Reality has been torn away and you realize what a fool you've been.") @@ -167,7 +171,7 @@ Made by Xhuis if(!istype(thrall_mind) || !(thrall_mind in shadowling_thralls) || !isliving(thrall_mind.current)) return 0 //If there is no mind, the mind isn't a thrall, or the mind's mob isn't alive, return shadowling_thralls.Remove(thrall_mind) - thrall_mind.current.attack_log += "\[[time_stamp()]\] Dethralled" + thrall_mind.current.create_attack_log("Dethralled") thrall_mind.special_role = null update_shadow_icons_removed(thrall_mind) for(var/obj/effect/proc_holder/spell/S in thrall_mind.spell_list) @@ -212,7 +216,7 @@ Made by Xhuis if(!istype(ling_mind) || !(ling_mind in shadows)) return 0 update_shadow_icons_removed(ling_mind) shadows.Remove(ling_mind) - ling_mind.current.attack_log += "\[[time_stamp()]\] Deshadowlinged" + ling_mind.current.create_attack_log("Deshadowlinged") ling_mind.special_role = null for(var/obj/effect/proc_holder/spell/S in ling_mind.spell_list) ling_mind.RemoveSpell(S) @@ -303,24 +307,28 @@ Made by Xhuis flags = NO_BLOOD | NO_BREATHE | RADIMMUNE | NOGUNS //Can't use guns due to muzzle flash burn_mod = 1.5 //1.5x burn damage, 2x is excessive + oxy_mod = 0 hot_env_multiplier = 1.5 silent_steps = 1 + grant_vision_toggle = 0 /datum/species/shadow/ling/handle_life(var/mob/living/carbon/human/H) if(!H.weakeyes) H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs var/light_amount = 0 - H.nutrition = 450 //i aint never get hongry + H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry if(isturf(H.loc)) var/turf/T = H.loc light_amount = T.get_lumcount() * 10 if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes + H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN) if(H.stat != DEAD) to_chat(H, "The light burns you!")//Message spam to say "GET THE FUCK OUT" H << 'sound/weapons/sear.ogg' else if(light_amount < LIGHT_HEAL_THRESHOLD) + H.clear_alert("lightexposure") H.heal_overall_damage(5, 5) H.adjustToxLoss(-5) H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!" @@ -340,19 +348,22 @@ Made by Xhuis flags = NO_BLOOD | NO_BREATHE | RADIMMUNE burn_mod = 1.1 + oxy_mod = 0 hot_env_multiplier = 1.1 /datum/species/shadow/ling/lesser/handle_life(var/mob/living/carbon/human/H) if(!H.weakeyes) H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs var/light_amount = 0 - H.nutrition = 450 //i aint never get hongry + H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry if(isturf(H.loc)) var/turf/T = H.loc light_amount = T.get_lumcount() * 10 if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) + H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN/2) else if(light_amount < LIGHT_HEAL_THRESHOLD) + H.clear_alert("lightexposure") H.heal_overall_damage(2,2) H.adjustToxLoss(-5) H.adjustBrainLoss(-25) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index b9525ee282e..b04a3012fc3 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -21,67 +21,33 @@ clothes_req = 0 action_icon_state = "glare" -/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/human/target in targets) if(!ishuman(target)) - to_chat(usr, "You may only glare at humans!") + to_chat(user, "You may only glare at humans!") charge_counter = charge_max return - if(!shadowling_check(usr)) + if(!shadowling_check(user)) charge_counter = charge_max return if(target.stat) - to_chat(usr, "[target] must be conscious!") + to_chat(user, "[target] must be conscious!") charge_counter = charge_max return if(is_shadow_or_thrall(target)) - to_chat(usr, "You don't see why you would want to paralyze an ally.") + to_chat(user, "You don't see why you would want to paralyze an ally.") charge_counter = charge_max return var/mob/living/carbon/human/M = target - usr.visible_message("[usr]'s eyes flash a blinding red!") + user.visible_message("[user]'s eyes flash a blinding red!") target.visible_message("[target] freezes in place, their eyes glazing over...") - if(in_range(target, usr)) - to_chat(target, "Your gaze is forcibly drawn into [usr]'s eyes, and you are mesmerized by their heavenly beauty...") + if(in_range(target, user)) + to_chat(target, "Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by their heavenly beauty...") else //Only alludes to the shadowling if the target is close by to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights...") target.Stun(10) M.AdjustSilence(10) - -/obj/effect/proc_holder/spell/targeted/lesser_glare - name = "Lesser Glare" - desc = "Stuns and mutes a target for a short duration." - panel = "Thrall Abilities" - charge_max = 450 - clothes_req = 0 - action_icon_state = "glare" - -/obj/effect/proc_holder/spell/targeted/lesser_glare/cast(list/targets) - for(var/mob/living/carbon/human/target in targets) - if(!ishuman(target) || !target) - to_chat(usr, "You nay only glare at humans!") - charge_counter = charge_max - return - if(target.stat) - to_chat(usr, "[target] must be conscious!") - charge_counter = charge_max - return - if(is_shadow_or_thrall(target)) - to_chat(usr, "You cannot glare at allies!") - charge_counter = charge_max - return - var/mob/living/carbon/human/M = target - usr.visible_message("[usr]'s eyes flash a blinding red!") - target.visible_message("[target] freezes in place, their eyes glazing over...") - if(in_range(target, usr)) - to_chat(target, "Your gaze is forcibly drawn into [usr]'s eyes, and you are mesmerized by the heavenly lights...") - else - to_chat(target, "Red lights suddenly dance in your vision, and you are mesmerized by their heavenly beauty...") - target.Stun(3) //Roughly 30% as long as the normal one - M.AdjustSilence(3) - - /obj/effect/proc_holder/spell/aoe_turf/veil name = "Veil" desc = "Extinguishes most nearby light sources." @@ -118,8 +84,8 @@ P.visible_message("[P]'s light fades and turns off.") else if(istype(I, /obj/item/weapon/gun)) var/obj/item/weapon/gun/G = I - if(G.F) - var/obj/item/device/flashlight/F = G.F + if(G.gun_light) + var/obj/item/device/flashlight/F = G.gun_light if(F.on) G.toggle_gunlight() G.visible_message("[G]'s light fades and turns off.") @@ -138,12 +104,12 @@ if(F.light_range > 0) extinguishItem(F) -/obj/effect/proc_holder/spell/aoe_turf/veil/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/aoe_turf/veil/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return - to_chat(usr, "You silently disable all nearby lights.") - for(var/obj/effect/glowshroom/G in orange(2, usr)) //Why the fuck was this in the loop below? + to_chat(user, "You silently disable all nearby lights.") + for(var/obj/effect/glowshroom/G in orange(2, user)) //Why the fuck was this in the loop below? G.visible_message("\The [G] withers away!") qdel(G) for(var/turf/T in targets) @@ -175,30 +141,30 @@ include_user = 1 action_icon_state = "shadow_walk" -/obj/effect/proc_holder/spell/targeted/shadow_walk/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/targeted/shadow_walk/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return - for(var/mob/living/user in targets) + for(var/mob/living/target in targets) playsound(user.loc, 'sound/effects/bamf.ogg', 50, 1) - user.visible_message("[user] vanishes in a puff of black mist!", "You enter the space between worlds as a passageway.") - user.SetStunned(0) - user.SetWeakened(0) - user.incorporeal_move = 1 - user.alpha = 0 - user.ExtinguishMob() - var/turf/T = get_turf(user) - user.forceMove(T) //to properly move the mob out of a potential container - if(user.buckled) - user.buckled.unbuckle_mob() - if(user.pulledby) - user.pulledby.stop_pulling() - user.stop_pulling() + target.visible_message("[target] vanishes in a puff of black mist!", "You enter the space between worlds as a passageway.") + target.SetStunned(0) + target.SetWeakened(0) + target.incorporeal_move = 1 + target.alpha = 0 + target.ExtinguishMob() + var/turf/T = get_turf(target) + target.forceMove(T) //to properly move the mob out of a potential container + if(target.buckled) + target.buckled.unbuckle_mob() + if(target.pulledby) + target.pulledby.stop_pulling() + target.stop_pulling() sleep(40) //4 seconds - user.visible_message("[user] suddenly manifests!", "The pressure becomes too much and you vacate the interdimensional darkness.") - user.incorporeal_move = 0 - user.alpha = 255 - user.forceMove(user.loc) + target.visible_message("[target] suddenly manifests!", "The pressure becomes too much and you vacate the interdimensional darkness.") + target.incorporeal_move = 0 + target.alpha = 255 + target.forceMove(user.loc) /obj/effect/proc_holder/spell/targeted/lesser_shadow_walk name = "Guise" @@ -210,13 +176,13 @@ include_user = 1 action_icon_state = "shadow_walk" -/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk/cast(list/targets) - for(var/mob/living/user in targets) - user.visible_message("[user] suddenly fades away!", "You veil yourself in darkness, making you harder to see.") - user.alpha = 10 +/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk/cast(list/targets, mob/user = usr) + for(var/mob/living/target in targets) + target.visible_message("[target] suddenly fades away!", "You veil yourself in darkness, making you harder to see.") + target.alpha = 10 sleep(40) - user.visible_message("[user] appears from nowhere!", "Your shadowy guise slips away.") - user.alpha = initial(user.alpha) + target.visible_message("[target] appears from nowhere!", "Your shadowy guise slips away.") + target.alpha = initial(target.alpha) /obj/effect/proc_holder/spell/targeted/shadow_vision @@ -230,11 +196,11 @@ var/datum/vision_override/vision_path = /datum/vision_override/nightvision action_icon_state = "darksight" -/obj/effect/proc_holder/spell/targeted/shadow_vision/cast(list/targets) - for(var/mob/living/user in targets) - if(!istype(user) || !ishuman(user)) +/obj/effect/proc_holder/spell/targeted/shadow_vision/cast(list/targets, mob/user = usr) + for(var/mob/living/target in targets) + if(!istype(target) || !ishuman(target)) return - var/mob/living/carbon/human/H = user + var/mob/living/carbon/human/H = target if(!H.vision_type) to_chat(H, "You shift the nerves in your eyes, allowing you to see in the dark.") H.vision_type = new vision_path @@ -256,17 +222,17 @@ clothes_req = 0 action_icon_state = "icy_veins" -/obj/effect/proc_holder/spell/aoe_turf/flashfreeze/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/aoe_turf/flashfreeze/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return - to_chat(usr, "You freeze the nearby air.") - playsound(usr.loc, 'sound/effects/ghost2.ogg', 50, 1) + to_chat(user, "You freeze the nearby air.") + playsound(user.loc, 'sound/effects/ghost2.ogg', 50, 1) for(var/turf/T in targets) for(var/mob/living/carbon/M in T.contents) if(is_shadow_or_thrall(M)) - if(M == usr) //No message for the user, of course + if(M == user) //No message for the user, of course continue else to_chat(M, "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!") @@ -290,80 +256,80 @@ var/enthralling = 0 action_icon_state = "enthrall" -/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets) - var/mob/living/carbon/human/user = usr +/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/ling = user listclearnulls(ticker.mode.shadowling_thralls) - if(!(user.mind in ticker.mode.shadows)) + if(!(ling.mind in ticker.mode.shadows)) return - if(user.get_species() != "Shadowling") + if(ling.get_species() != "Shadowling") if(ticker.mode.shadowling_thralls.len >= 5) charge_counter = charge_max return for(var/mob/living/carbon/human/target in targets) - if(!in_range(usr, target)) - to_chat(usr, "You need to be closer to enthrall [target].") + if(!in_range(user, target)) + to_chat(user, "You need to be closer to enthrall [target].") charge_counter = charge_max return if(!target.key || !target.mind) - to_chat(usr, "The target has no mind.") + to_chat(user, "The target has no mind.") charge_counter = charge_max return if(target.stat) - to_chat(usr, "The target must be conscious.") + to_chat(user, "The target must be conscious.") charge_counter = charge_max return if(is_shadow_or_thrall(target)) - to_chat(usr, "You can not enthrall allies.") + to_chat(user, "You can not enthrall allies.") charge_counter = charge_max return if(!ishuman(target)) - to_chat(usr, "You can only enthrall humans.") + to_chat(user, "You can only enthrall humans.") charge_counter = charge_max return if(enthralling) - to_chat(usr, "You are already enthralling!") + to_chat(user, "You are already enthralling!") charge_counter = charge_max return if(!target.client) - to_chat(usr, "[target]'s mind is vacant of activity.") + to_chat(user, "[target]'s mind is vacant of activity.") enthralling = 1 - to_chat(usr, "This target is valid. You begin the enthralling.") - to_chat(target, "[usr] stares at you. You feel your head begin to pulse.") + to_chat(user, "This target is valid. You begin the enthralling.") + to_chat(target, "[user] stares at you. You feel your head begin to pulse.") for(var/progress = 0, progress <= 3, progress++) switch(progress) if(1) - to_chat(usr, "You place your hands to [target]'s head...") - usr.visible_message("[usr] places their hands onto the sides of [target]'s head!") + to_chat(user, "You place your hands to [target]'s head...") + user.visible_message("[user] places their hands onto the sides of [target]'s head!") if(2) - to_chat(usr, "You begin preparing [target]'s mind as a blank slate...") - usr.visible_message("[usr]'s palms flare a bright red against [target]'s temples!") + to_chat(user, "You begin preparing [target]'s mind as a blank slate...") + user.visible_message("[user]'s palms flare a bright red against [target]'s temples!") to_chat(target, "A terrible red light floods your mind. You collapse as conscious thought is wiped away.") target.Weaken(12) sleep(20) if(isloyal(target)) - to_chat(usr, "They have a mindshield implant. You begin to deactivate it - this will take some time.") - usr.visible_message("[usr] pauses, then dips their head in concentration!") + to_chat(user, "They have a mindshield implant. You begin to deactivate it - this will take some time.") + user.visible_message("[user] pauses, then dips their head in concentration!") to_chat(target, "Your mindshield implant becomes hot as it comes under attack!") sleep(100) //10 seconds - not spawn() so the enthralling takes longer - to_chat(usr, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.") - usr.visible_message("[usr] relaxes again.") + to_chat(user, "The nanobots composing the mindshield implant have been rendered inert. Now to continue.") + user.visible_message("[user] relaxes again.") for(var/obj/item/weapon/implant/loyalty/L in target) if(L && L.implanted) qdel(L) to_chat(target, "Your mental protection implant unexpectedly falters, dims, dies.") if(3) - to_chat(usr, "You begin planting the tumor that will control the new thrall...") - usr.visible_message("A strange energy passes from [usr]'s hands into [target]'s head!") + to_chat(user, "You begin planting the tumor that will control the new thrall...") + user.visible_message("A strange energy passes from [user]'s hands into [target]'s head!") to_chat(target, "You feel your memories twisting, morphing. A sense of horror dominates your mind.") - if(!do_mob(usr, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a mindshield implant - to_chat(usr, "The enthralling has been interrupted - your target's mind returns to its previous state.") - to_chat(target, "You wrest yourself away from [usr]'s hands and compose yourself") + if(!do_mob(user, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a mindshield implant + to_chat(user, "The enthralling has been interrupted - your target's mind returns to its previous state.") + to_chat(target, "You wrest yourself away from [user]'s hands and compose yourself") enthralling = 0 return enthralling = 0 - to_chat(usr, "You have enthralled [target]!") + to_chat(user, "You have enthralled [target]!") target.visible_message("[target] looks to have experienced a revelation!", \ "False faces all dark not real not real not--") target.setOxyLoss(0) //In case the shadowling was choking them out @@ -380,18 +346,18 @@ clothes_req = 0 action_icon_state = "regen_armor" -/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor/cast(list/targets) - if(!is_shadow(usr)) - to_chat(usr, "You must be a shadowling to do this!") +/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor/cast(list/targets, mob/user = usr) + if(!is_shadow(user)) + to_chat(user, "You must be a shadowling to do this!") charge_counter = charge_max return - for(var/mob/living/user in targets) - if(!istype(user) || !ishuman(user)) + for(var/mob/living/target in targets) + if(!istype(target) || !ishuman(target)) return - var/mob/living/carbon/human/H = user + var/mob/living/carbon/human/H = target H.visible_message("[H]'s skin suddenly bubbles and shifts around their body!", \ "You regenerate your protective armor and cleanse your form of defects.") - H.adjustCloneLoss(user.getCloneLoss()) + H.adjustCloneLoss(target.getCloneLoss()) H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(H), slot_wear_suit) @@ -415,54 +381,54 @@ var/reviveThrallAcquired action_icon_state = "collective_mind" -/obj/effect/proc_holder/spell/targeted/collective_mind/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/targeted/collective_mind/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return - for(var/mob/living/user in targets) + for(var/mob/living/target in targets) var/thralls = 0 - var/victory_threshold = 15 + var/victory_threshold = ticker.mode.required_thralls var/mob/M - to_chat(user, "You focus your telepathic energies abound, harnessing and drawing together the strength of your thralls.") + to_chat(target, "You focus your telepathic energies abound, harnessing and drawing together the strength of your thralls.") for(M in living_mob_list) if(is_thrall(M)) thralls++ to_chat(M, "You feel hooks sink into your mind and pull.") - if(!do_after(user, 30, target = user)) - to_chat(user, "Your concentration has been broken. The mental hooks you have sent out now retract into your mind.") + if(!do_after(target, 30, target = target)) + to_chat(target, "Your concentration has been broken. The mental hooks you have sent out now retract into your mind.") return if(thralls >= 3 && !screech_acquired) screech_acquired = 1 - to_chat(user, "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.") - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech(null)) + to_chat(target, "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.") + target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech(null)) if(thralls >= 5 && !blind_smoke_acquired) blind_smoke_acquired = 1 - to_chat(user, "The power of your thralls has granted you the Blinding Smoke ability. \ + to_chat(target, "The power of your thralls has granted you the Blinding Smoke ability. \ It will create a choking cloud that will blind any non-thralls who enter.") - user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke(null)) + target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke(null)) if(thralls >= 7 && !drainLifeAcquired) drainLifeAcquired = 1 - to_chat(user, "The power of your thralls has granted you the Drain Life ability. You can now drain the health of nearby humans to heal yourself.") - user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drainLife(null)) + to_chat(target, "The power of your thralls has granted you the Drain Life ability. You can now drain the health of nearby humans to heal yourself.") + target.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drainLife(null)) if(thralls >= 9 && !reviveThrallAcquired) reviveThrallAcquired = 1 - to_chat(user, "The power of your thralls has granted you the Black Recuperation ability. \ + to_chat(target, "The power of your thralls has granted you the Black Recuperation ability. \ This will, after a short time, bring a dead thrall completely back to life with no bodily defects.") - user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/reviveThrall(null)) + target.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/reviveThrall(null)) if(thralls < victory_threshold) - to_chat(user, "You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present.") + to_chat(target, "You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present.") else if(thralls >= victory_threshold) - to_chat(usr, "You are now powerful enough to ascend. Use the Ascendance ability when you are ready. This will kill all of your thralls.") - to_chat(usr, "You may find Ascendance in the Shadowling Evolution tab.") + to_chat(target, "You are now powerful enough to ascend. Use the Ascendance ability when you are ready. This will kill all of your thralls.") + to_chat(target, "You may find Ascendance in the Shadowling Evolution tab.") for(M in living_mob_list) if(is_shadow(M)) var/obj/effect/proc_holder/spell/targeted/collective_mind/CM @@ -471,10 +437,10 @@ qdel(CM) M.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/shadowling_hatch) M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_ascend(null)) - if(M == usr) + if(M == user) to_chat(M, "You project this power to the rest of the shadowlings.") else - to_chat(M, "[user.real_name] has coalesced the strength of the thralls. You can draw upon it at any time to ascend. (Shadowling Evolution Tab)")//Tells all the other shadowlings + to_chat(M, "[target.real_name] has coalesced the strength of the thralls. You can draw upon it at any time to ascend. (Shadowling Evolution Tab)")//Tells all the other shadowlings @@ -489,15 +455,15 @@ include_user = 1 action_icon_state = "black_smoke" -/obj/effect/proc_holder/spell/targeted/blindness_smoke/cast(list/targets) //Extremely hacky - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/targeted/blindness_smoke/cast(list/targets, mob/user = usr) //Extremely hacky + if(!shadowling_check(user)) charge_counter = charge_max return - for(var/mob/living/user in targets) - user.visible_message("[user] suddenly bends over and coughs out a cloud of black smoke, which begins to spread rapidly!") - to_chat(user, "You regurgitate a vast cloud of blinding smoke.") - playsound(user, 'sound/effects/bamf.ogg', 50, 1) - var/obj/item/weapon/reagent_containers/glass/beaker/large/B = new /obj/item/weapon/reagent_containers/glass/beaker/large(user.loc) + for(var/mob/living/target in targets) + target.visible_message("[target] suddenly bends over and coughs out a cloud of black smoke, which begins to spread rapidly!") + to_chat(target, "You regurgitate a vast cloud of blinding smoke.") + playsound(target, 'sound/effects/bamf.ogg', 50, 1) + var/obj/item/weapon/reagent_containers/glass/beaker/large/B = new /obj/item/weapon/reagent_containers/glass/beaker/large(target.loc) B.reagents.clear_reagents() //Just in case! B.icon_state = null //Invisible B.reagents.add_reagent("blindness_smoke", 10) @@ -539,17 +505,17 @@ clothes_req = 0 action_icon_state = "screech" -/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return - usr.audible_message("[usr] lets out a horrible scream!") - playsound(usr.loc, 'sound/effects/screech.ogg', 100, 1) + user.audible_message("[user] lets out a horrible scream!") + playsound(user.loc, 'sound/effects/screech.ogg', 100, 1) for(var/turf/T in targets) for(var/mob/target in T.contents) if(is_shadow_or_thrall(target)) - if(target == usr) //No message for the user, of course + if(target == user) //No message for the user, of course continue else continue @@ -583,10 +549,11 @@ var/list/nearbyTargets action_icon_state = "drain_life" -/obj/effect/proc_holder/spell/aoe_turf/drainLife/cast(list/targets, var/mob/living/carbon/human/U = usr) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/aoe_turf/drainLife/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return + var/mob/living/carbon/human/U = usr targetsDrained = 0 nearbyTargets = list() for(var/turf/T in targets) @@ -597,7 +564,7 @@ nearbyTargets.Add(M) if(!targetsDrained) charge_counter = charge_max - to_chat(usr, "There were no nearby humans for you to drain.") + to_chat(U, "There were no nearby humans for you to drain.") return for(var/mob/living/carbon/M in nearbyTargets) U.heal_organ_damage(10, 10) @@ -608,8 +575,8 @@ U.AdjustStunned(-1) M.adjustOxyLoss(20) M.adjustStaminaLoss(20) - to_chat(M, "You feel a wave of exhaustion and a curious draining sensation directed towards [usr]!") - to_chat(usr, "You draw life from those around you to heal your wounds.") + to_chat(M, "You feel a wave of exhaustion and a curious draining sensation directed towards [U]!") + to_chat(U, "You draw life from those around you to heal your wounds.") @@ -623,24 +590,24 @@ include_user = 0 action_icon_state = "revive_thrall" -/obj/effect/proc_holder/spell/targeted/reviveThrall/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/targeted/reviveThrall/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return for(var/mob/living/carbon/human/thrallToRevive in targets) - var/choice = alert(usr,"Empower a living thrall or revive a dead one?",,"Empower","Revive","Cancel") + var/choice = alert(user,"Empower a living thrall or revive a dead one?",,"Empower","Revive","Cancel") switch(choice) if("Empower") if(!is_thrall(thrallToRevive)) - to_chat(usr, "[thrallToRevive] is not a thrall.") + to_chat(user, "[thrallToRevive] is not a thrall.") charge_counter = charge_max return if(thrallToRevive.stat != CONSCIOUS) - to_chat(usr, "[thrallToRevive] must be conscious to become empowered.") + to_chat(user, "[thrallToRevive] must be conscious to become empowered.") charge_counter = charge_max return if(thrallToRevive.get_species() == "Lesser Shadowling") - to_chat(usr, "[thrallToRevive] is already empowered.") + to_chat(user, "[thrallToRevive] is already empowered.") charge_counter = charge_max return var/empowered_thralls = 0 @@ -651,54 +618,53 @@ if(H.get_species() == "Lesser Shadowling") empowered_thralls++ if(empowered_thralls >= EMPOWERED_THRALL_LIMIT) - to_chat(usr, "You cannot spare this much energy. There are too many empowered thralls.") + to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.") charge_counter = charge_max return - usr.visible_message("[usr] places their hands over [thrallToRevive]'s face, red light shining from beneath.", \ + user.visible_message("[user] places their hands over [thrallToRevive]'s face, red light shining from beneath.", \ "You place your hands on [thrallToRevive]'s face and begin gathering energy...") - to_chat(thrallToRevive, "[usr] places their hands over your face. You feel energy gathering. Stand still...") - if(!do_mob(usr, thrallToRevive, 80)) - to_chat(usr, "Your concentration snaps. The flow of energy ebbs.") + to_chat(thrallToRevive, "[user] places their hands over your face. You feel energy gathering. Stand still...") + if(!do_mob(user, thrallToRevive, 80)) + to_chat(user, "Your concentration snaps. The flow of energy ebbs.") charge_counter = charge_max return - to_chat(usr, "You release a massive surge of power into [thrallToRevive]!") - usr.visible_message("Red lightning surges into [thrallToRevive]'s face!") + to_chat(user, "You release a massive surge of power into [thrallToRevive]!") + user.visible_message("Red lightning surges into [thrallToRevive]'s face!") playsound(thrallToRevive, 'sound/weapons/Egloves.ogg', 50, 1) playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) - usr.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) + user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) thrallToRevive.Weaken(5) thrallToRevive.visible_message("[thrallToRevive] collapses, their skin and face distorting!", \ "AAAAAAAAAAAAAAAAAAAGH-") sleep(20) thrallToRevive.visible_message("[thrallToRevive] slowly rises, no longer recognizable as human.", \ "You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \ - darkness but wither slowly in light. In addition, Lesser Glare and Guise have been upgraded into their true forms.") + darkness but wither slowly in light. In addition, you now have glare and true shadow walk.") thrallToRevive.set_species("Lesser Shadowling") - thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_glare) thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk) thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null)) thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk(null)) if("Revive") if(!is_thrall(thrallToRevive)) - to_chat(usr, "[thrallToRevive] is not a thrall.") + to_chat(user, "[thrallToRevive] is not a thrall.") charge_counter = charge_max return if(thrallToRevive.stat != DEAD) - to_chat(usr, "[thrallToRevive] is not dead.") + to_chat(user, "[thrallToRevive] is not dead.") charge_counter = charge_max return - usr.visible_message("[usr] kneels over [thrallToRevive], placing their hands on \his chest.", \ + user.visible_message("[user] kneels over [thrallToRevive], placing their hands on \his chest.", \ "You crouch over the body of your thrall and begin gathering energy...") thrallToRevive.notify_ghost_cloning("Your masters are resuscitating you! Re-enter your corpse if you wish to be brought to life.", source = thrallToRevive) - if(!do_mob(usr, thrallToRevive, 30)) - to_chat(usr, "Your concentration snaps. The flow of energy ebbs.") + if(!do_mob(user, thrallToRevive, 30)) + to_chat(user, "Your concentration snaps. The flow of energy ebbs.") charge_counter = charge_max return - to_chat(usr, "You release a massive surge of power into [thrallToRevive]!") - usr.visible_message("Red lightning surges from [usr]'s hands into [thrallToRevive]'s chest!") + to_chat(user, "You release a massive surge of power into [thrallToRevive]!") + user.visible_message("Red lightning surges from [user]'s hands into [thrallToRevive]'s chest!") playsound(thrallToRevive, 'sound/weapons/Egloves.ogg', 50, 1) playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1) - usr.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) + user.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) sleep(10) if(thrallToRevive.revive()) thrallToRevive.visible_message("[thrallToRevive] heaves in breath, dim red light shining in their eyes.", \ @@ -719,8 +685,8 @@ charge_max = 600 action_icon_state = "extend_shuttle" -/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets) - if(!shadowling_check(usr)) +/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/user = usr) + if(!shadowling_check(user)) charge_counter = charge_max return for(var/mob/living/carbon/human/target in targets) @@ -728,23 +694,23 @@ charge_counter = charge_max return if(!is_thrall(target)) - to_chat(usr, "[target] must be a thrall.") + to_chat(user, "[target] must be a thrall.") charge_counter = charge_max return if(shuttle_master.emergency.mode != SHUTTLE_CALL) - to_chat(usr, "The shuttle must be inbound only to the station.") + to_chat(user, "The shuttle must be inbound only to the station.") charge_counter = charge_max return var/mob/living/carbon/human/M = target - usr.visible_message("[usr]'s eyes flash a bright red!", \ + user.visible_message("[user]'s eyes flash a bright red!", \ "You begin to draw [M]'s life force.") M.visible_message("[M]'s face falls slack, their jaw slightly distending.", \ "You are suddenly transported... far, far away...") - if(!do_after(usr, 50, target = M)) + if(!do_after(user, 50, target = M)) to_chat(M, "You are snapped back to reality, your haze dissipating!") - to_chat(usr, "You have been interrupted. The draw has failed.") + to_chat(user, "You have been interrupted. The draw has failed.") return - to_chat(usr, "You project [M]'s life force toward the approaching shuttle, extending its arrival duration!") + to_chat(user, "You project [M]'s life force toward the approaching shuttle, extending its arrival duration!") M.visible_message("[M]'s eyes suddenly flare red. They proceed to collapse on the floor, not breathing.", \ "...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...") M.death() @@ -752,9 +718,9 @@ var/more_minutes = 9000 var/timer = shuttle_master.emergency.timeLeft() timer += more_minutes - command_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg') + event_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg') shuttle_master.emergency.setTimer(timer) - usr.mind.spell_list.Remove(src) //Can only be used once! + user.mind.spell_list.Remove(src) //Can only be used once! qdel(src) // ASCENDANT ABILITIES BEYOND THIS POINT // @@ -768,20 +734,20 @@ clothes_req = 0 action_icon_state = "annihilate" -/obj/effect/proc_holder/spell/targeted/annihilate/cast(list/targets) - var/mob/living/simple_animal/ascendant_shadowling/SHA = usr +/obj/effect/proc_holder/spell/targeted/annihilate/cast(list/targets, mob/user = usr) + var/mob/living/simple_animal/ascendant_shadowling/SHA = user if(SHA.phasing) - to_chat(usr, "You are not in the same plane of existence. Unphase first.") + to_chat(user, "You are not in the same plane of existence. Unphase first.") charge_counter = charge_max return - playsound(usr.loc, 'sound/magic/Staff_Chaos.ogg', 100, 1) + playsound(user.loc, 'sound/magic/Staff_Chaos.ogg', 100, 1) for(var/mob/living/boom in targets) if(is_shadow(boom)) //Used to not work on thralls. Now it does so you can PUNISH THEM LIKE THE WRATHFUL GOD YOU ARE. - to_chat(usr, "Making an ally explode seems unwise.") + to_chat(user, "Making an ally explode seems unwise.") charge_counter = charge_max return - usr.visible_message("[usr]'s markings flare as they gesture at [boom]!", \ + user.visible_message("[user]'s markings flare as they gesture at [boom]!", \ "You direct a lance of telekinetic energy at [boom].") sleep(4) if(iscarbon(boom)) @@ -800,32 +766,32 @@ clothes_req = 0 action_icon_state = "enthrall" -/obj/effect/proc_holder/spell/targeted/hypnosis/cast(list/targets) - var/mob/living/simple_animal/ascendant_shadowling/SHA = usr +/obj/effect/proc_holder/spell/targeted/hypnosis/cast(list/targets, mob/user = usr) + var/mob/living/simple_animal/ascendant_shadowling/SHA = user if(SHA.phasing) charge_counter = charge_max - to_chat(usr, "You are not in the same plane of existence. Unphase first.") + to_chat(user, "You are not in the same plane of existence. Unphase first.") return for(var/mob/living/carbon/human/target in targets) if(is_shadow_or_thrall(target)) - to_chat(usr, "You cannot enthrall an ally.") + to_chat(user, "You cannot enthrall an ally.") charge_counter = charge_max return if(!target.ckey || !target.mind) - to_chat(usr, "The target has no mind.") + to_chat(user, "The target has no mind.") charge_counter = charge_max return if(target.stat) - to_chat(usr, "The target must be conscious.") + to_chat(user, "The target must be conscious.") charge_counter = charge_max return if(!ishuman(target)) - to_chat(usr, "You can only enthrall humans.") + to_chat(user, "You can only enthrall humans.") charge_counter = charge_max return - to_chat(usr, "You instantly rearrange [target]'s memories, hyptonitizing them into a thrall.") + to_chat(user, "You instantly rearrange [target]'s memories, hyptonitizing them into a thrall.") to_chat(target, "An agonizing spike of pain drives into your mind, and--") ticker.mode.add_thrall(target.mind) target.mind.special_role = SPECIAL_ROLE_SHADOWLING_THRALL @@ -843,8 +809,8 @@ clothes_req = 0 action_icon_state = "shadow_walk" -/obj/effect/proc_holder/spell/targeted/shadowling_phase_shift/cast(list/targets) - var/mob/living/simple_animal/ascendant_shadowling/SHA = usr +/obj/effect/proc_holder/spell/targeted/shadowling_phase_shift/cast(list/targets, mob/user = usr) + var/mob/living/simple_animal/ascendant_shadowling/SHA = user for(SHA in targets) SHA.phasing = !SHA.phasing if(SHA.phasing) @@ -869,16 +835,16 @@ clothes_req = 0 action_icon_state = "lightning_storm" -/obj/effect/proc_holder/spell/aoe_turf/ascendant_storm/cast(list/targets) - var/mob/living/simple_animal/ascendant_shadowling/SHA = usr +/obj/effect/proc_holder/spell/aoe_turf/ascendant_storm/cast(list/targets, mob/user = usr) + var/mob/living/simple_animal/ascendant_shadowling/SHA = user if(SHA.phasing) - to_chat(usr, "You are not in the same plane of existence. Unphase first.") + to_chat(user, "You are not in the same plane of existence. Unphase first.") charge_counter = charge_max return - usr.visible_message("A massive ball of lightning appears in [usr]'s hands and flares out!", \ + user.visible_message("A massive ball of lightning appears in [user]'s hands and flares out!", \ "You conjure a ball of lightning and release it.") - playsound(usr.loc, 'sound/magic/lightningbolt.ogg', 100, 1) + playsound(user.loc, 'sound/magic/lightningbolt.ogg', 100, 1) for(var/turf/T in targets) for(var/mob/living/carbon/human/target in T.contents) if(is_shadow_or_thrall(target)) @@ -887,7 +853,7 @@ playsound(target, 'sound/magic/LightningShock.ogg', 50, 1) target.Weaken(8) target.take_organ_damage(0,50) - usr.Beam(target,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) + user.Beam(target,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1) /obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit name = "Ascendant Broadcast" @@ -899,9 +865,9 @@ include_user = 1 action_icon_state = "transmit" -/obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit/cast(list/targets) - for(var/mob/living/user in targets) - var/text = stripped_input(user, "What do you want to say to everything on and near [station_name()]?.", "Transmit to World", "") +/obj/effect/proc_holder/spell/targeted/shadowlingAscendantTransmit/cast(list/targets, mob/user = usr) + for(var/mob/living/target in targets) + var/text = stripped_input(target, "What do you want to say to everything on and near [station_name()]?.", "Transmit to World", "") if(!text) return to_chat(world, "\"[text]\"") diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 2c06168499e..1ebf944173d 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -10,11 +10,11 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N include_user = 1 action_icon_state = "hatch" -/obj/effect/proc_holder/spell/targeted/shadowling_hatch/cast(list/targets) - if(usr.stat || !ishuman(usr) || !usr || !is_shadow(usr || isinspace(usr))) +/obj/effect/proc_holder/spell/targeted/shadowling_hatch/cast(list/targets, mob/user = usr) + if(user.stat || !ishuman(user) || !user || !is_shadow(user || isinspace(user))) return - if(!isturf(usr.loc)) - to_chat(usr, "You can't hatch here!") + if(!isturf(user.loc)) + to_chat(user, "You can't hatch here!") return for(var/mob/living/carbon/human/H in targets) var/hatch_or_no = alert(H,"Are you sure you want to hatch? You cannot undo this!",,"Yes","No") @@ -33,8 +33,8 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N sleep(50) var/turf/simulated/floor/F - var/turf/shadowturf = get_turf(usr) - for(F in orange(1, usr)) + var/turf/shadowturf = get_turf(user) + for(F in orange(1, user)) new /obj/structure/alien/resin/wall/shadowling(F) for(var/obj/structure/alien/resin/wall/shadowling/R in shadowturf) //extremely hacky qdel(R) @@ -68,7 +68,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N var/newNameId = pick(possibleShadowlingNames) possibleShadowlingNames.Remove(newNameId) H.real_name = newNameId - H.name = usr.real_name + H.name = user.real_name H.SetStunned(0) to_chat(H, "YOU LIVE!!!") @@ -83,13 +83,13 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N H.socks = "None" H.faction |= "faithless" - H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(usr), slot_w_uniform) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(usr), slot_shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(usr), slot_wear_suit) - H.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(usr), slot_head) - H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) - H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) - H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(usr), slot_glasses) + H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(user), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(user), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(user), slot_wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(user), slot_head) + H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(user), slot_gloves) + H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(user), slot_wear_mask) + H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(user), slot_glasses) H.set_species("Shadowling") //can't be a shadowling without being a shadowling H.mind.RemoveSpell(src) @@ -116,8 +116,8 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N include_user = 1 action_icon_state = "ascend" -/obj/effect/proc_holder/spell/targeted/shadowling_ascend/cast(list/targets) - var/mob/living/carbon/human/H = usr +/obj/effect/proc_holder/spell/targeted/shadowling_ascend/cast(list/targets, mob/user = usr) + var/mob/living/carbon/human/H = user if(!shadowling_check(H)) return for(H in targets) @@ -143,7 +143,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N sleep(90) H.visible_message("[H]'s body begins to violently stretch and contort.", \ - "You begin to rend apart the final barries to godhood.") + "You begin to rend apart the final barriers to godhood.") sleep(40) to_chat(H, "Yes!") diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 60a90b70638..371aef6c6a0 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -350,7 +350,7 @@ if(traitor_mind in traitors) ticker.mode.traitors -= traitor_mind traitor_mind.special_role = null - traitor_mind.current.attack_log += "\[[time_stamp()]\] De-traitored" + traitor_mind.current.create_attack_log("De-traitored") if(issilicon(traitor_mind.current)) to_chat(traitor_mind.current, "You have been turned into a robot! You are no longer a traitor.") else diff --git a/code/game/gamemodes/vampire/traitor_vamp.dm b/code/game/gamemodes/vampire/traitor_vamp.dm index 068ad772b66..b06db47f02c 100644 --- a/code/game/gamemodes/vampire/traitor_vamp.dm +++ b/code/game/gamemodes/vampire/traitor_vamp.dm @@ -32,7 +32,8 @@ slaved.masters += vampire vampire.som = slaved //we MIGT want to mindslave someone vampire.restricted_roles = restricted_jobs - return ..() + ..() + return 1 else return 0 diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 39c9c24ec50..f3dc8e4e41a 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -59,6 +59,7 @@ slaved.masters += vampire vampire.som = slaved //we MIGT want to mindslave someone vampire.special_role = SPECIAL_ROLE_VAMPIRE + ..() return 1 else return 0 @@ -274,8 +275,8 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha var/blood = 0 var/old_bloodtotal = 0 //used to see if we increased our blood total var/old_bloodusable = 0 //used to see if we increased our blood usable - owner.attack_log += text("\[[time_stamp()]\] Bit [H] ([H.ckey]) in the neck and draining their blood") - H.attack_log += text("\[[time_stamp()]\] Has been bit in the neck by [owner] ([owner.ckey])") + owner.create_attack_log("Bit [H] ([H.ckey]) in the neck and draining their blood") + H.create_attack_log("Has been bit in the neck by [owner] ([owner.ckey])") log_attack("[owner] ([owner.ckey]) bit [H] ([H.ckey]) in the neck") owner.visible_message("[owner] grabs [H]'s neck harshly and sinks in their fangs!", "You sink your fangs into [H] and begin to drain their blood.", "You hear a soft puncture and a wet sucking noise.") if(!iscarbon(owner)) @@ -304,7 +305,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha H.vessel.remove_reagent("blood", 25) if(ishuman(owner)) var/mob/living/carbon/human/V = owner - V.nutrition = min(450, V.nutrition + (blood / 2)) + V.nutrition = min(NUTRITION_LEVEL_WELL_FED, V.nutrition + (blood / 2)) draining = null to_chat(owner, "You stop draining [H.name] of blood.") @@ -334,7 +335,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(vampire_mind in vampires) ticker.mode.vampires -= vampire_mind vampire_mind.special_role = null - vampire_mind.current.attack_log += "\[[time_stamp()]\] De-vampired" + vampire_mind.current.create_attack_log("De-vampired") if(vampire_mind.vampire) vampire_mind.vampire.remove_vampire_powers() qdel(vampire_mind.vampire) @@ -415,12 +416,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha owner.alpha = 255 return var/turf/simulated/T = get_turf(owner) - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/light_available - if(L) - light_available = L.get_clamped_lum(0.5) * 10 - else - light_available = 10 + var/light_available = T.get_lumcount(0.5) * 10 if(!istype(T)) return 0 @@ -428,6 +424,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha if(!iscloaking) owner.alpha = 255 return 0 + if(light_available <= 2) owner.alpha = round((255 * 0.15)) return 1 diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index 92a1a3dfa19..c38c50ad40a 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -117,7 +117,7 @@ revert_cast(user) return - perform(list(T)) + perform(list(T), user = user) /obj/effect/proc_holder/spell/vampire/self/choose_targets(mob/user = usr) perform(list(user)) @@ -131,7 +131,7 @@ revert_cast(user) return - perform(targets) + perform(targets, user = user) /datum/vampire_passive var/gain_desc @@ -150,14 +150,14 @@ charge_max = 200 stat_allowed = 1 -/obj/effect/proc_holder/spell/vampire/self/rejuvenate/cast() - var/mob/living/U = usr +/obj/effect/proc_holder/spell/vampire/self/rejuvenate/cast(list/targets, mob/user = usr) + var/mob/living/U = user - usr.SetWeakened(0) - usr.SetStunned(0) - usr.SetParalysis(0) + user.SetWeakened(0) + user.SetStunned(0) + user.SetParalysis(0) U.adjustStaminaLoss(-75) - to_chat(usr, "You flush your system with clean blood and remove any incapacitating effects.") + to_chat(user, "You flush your system with clean blood and remove any incapacitating effects.") spawn(1) if(usr.mind.vampire.get_ability(/datum/vampire_passive/regen)) for(var/i = 1 to 5) @@ -173,15 +173,15 @@ action_icon_state = "vampire_hypnotise" required_blood = 20 -/obj/effect/proc_holder/spell/vampire/targetted/hypnotise/cast(list/targets) +/obj/effect/proc_holder/spell/vampire/targetted/hypnotise/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) - usr.visible_message("[usr]'s eyes flash briefly as he stares into [target]'s eyes") - if(do_mob(usr, target, 50)) + user.visible_message("[user]'s eyes flash briefly as he stares into [target]'s eyes") + if(do_mob(user, target, 50)) if(!affects(target)) - to_chat(usr, "Your piercing gaze fails to knock out [target].") - to_chat(target, "\blue [usr]'s feeble gaze is ineffective.") + to_chat(user, "Your piercing gaze fails to knock out [target].") + to_chat(target, "\blue [user]'s feeble gaze is ineffective.") else - to_chat(usr, "Your piercing gaze knocks out [target].") + to_chat(user, "Your piercing gaze knocks out [target].") to_chat(target, "You find yourself unable to move and barely able to speak.") target.Weaken(10) target.Stun(10) @@ -197,12 +197,12 @@ action_icon_state = "vampire_disease" required_blood = 100 -/obj/effect/proc_holder/spell/vampire/targetted/disease/cast(list/targets) +/obj/effect/proc_holder/spell/vampire/targetted/disease/cast(list/targets, mob/user = usr) for(var/mob/living/carbon/target in targets) - to_chat(usr, "You stealthily infect [target] with your diseased touch.") - target.help_shake_act(usr) + to_chat(user, "You stealthily infect [target] with your diseased touch.") + target.help_shake_act(user) if(!affects(target)) - to_chat(usr, "They seem to be unaffected.") + to_chat(user, "They seem to be unaffected.") continue var/datum/disease/D = new /datum/disease/vampire target.ForceContractDisease(D) @@ -214,10 +214,10 @@ charge_max = 300 stat_allowed = 1 -/obj/effect/proc_holder/spell/vampire/mob_aoe/glare/cast(list/targets) - usr.visible_message("[usr]'s eyes emit a blinding flash!") - if(istype(usr:glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) - to_chat(usr, "You're blindfolded!") +/obj/effect/proc_holder/spell/vampire/mob_aoe/glare/cast(list/targets, mob/user = usr) + user.visible_message("[user]'s eyes emit a blinding flash!") + if(istype(user:glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) + to_chat(user, "You're blindfolded!") return for(var/mob/living/target in targets) if(!affects(target)) @@ -225,7 +225,7 @@ target.Stun(5) target.Weaken(5) target.stuttering = 20 - to_chat(target, "You are blinded by [usr]'s glare.") + to_chat(target, "You are blinded by [user]'s glare.") /obj/effect/proc_holder/spell/vampire/self/shapeshift name = "Shapeshift (50)" @@ -234,12 +234,12 @@ action_icon_state = "genetic_poly" required_blood = 50 -/obj/effect/proc_holder/spell/vampire/self/shapeshift/cast() - usr.visible_message("[usr] transforms!") - usr.client.prefs.real_name = usr.generate_name() - usr.client.prefs.random_character() - usr.client.prefs.copy_to(usr) - usr.regenerate_icons() +/obj/effect/proc_holder/spell/vampire/self/shapeshift/cast(list/targets, mob/user = usr) + user.visible_message("[user] transforms!") + user.client.prefs.real_name = user.generate_name() + user.client.prefs.random_character() + user.client.prefs.copy_to(user) + user.regenerate_icons() /obj/effect/proc_holder/spell/vampire/self/screech name = "Chiroptean Screech (30)" @@ -248,10 +248,10 @@ action_icon_state = "vampire_screech" required_blood = 30 -/obj/effect/proc_holder/spell/vampire/self/screech/cast() - usr.visible_message("[usr] lets out an ear piercing shriek!", "You let out a loud shriek.", "You hear a loud painful shriek!") +/obj/effect/proc_holder/spell/vampire/self/screech/cast(list/targets, mob/user = usr) + user.visible_message("[user] lets out an ear piercing shriek!", "You let out a loud shriek.", "You hear a loud painful shriek!") for(var/mob/living/carbon/C in hearers(4)) - if(C == usr) + if(C == user) continue if(ishuman(C) && (C:l_ear || C:r_ear) && istype((C:l_ear || C:r_ear), /obj/item/clothing/ears/earmuffs)) continue @@ -265,7 +265,7 @@ C.Jitter(150) for(var/obj/structure/window/W in view(4)) W.destroy() - playsound(usr.loc, 'sound/effects/creepyshriek.ogg', 100, 1) + playsound(user.loc, 'sound/effects/creepyshriek.ogg', 100, 1) /proc/isvampirethrall(mob/living/M as mob) @@ -278,19 +278,19 @@ action_icon_state = "vampire_enthrall" required_blood = 300 -/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets) +/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) - usr.visible_message("[usr] bites [target]'s neck!", "You bite [target]'s neck and begin the flow of power.") + user.visible_message("[user] bites [target]'s neck!", "You bite [target]'s neck and begin the flow of power.") to_chat(target, "You feel the tendrils of evil invade your mind.") if(!ishuman(target)) - to_chat(usr, "You can only enthrall humans.") + to_chat(user, "You can only enthrall humans.") break - if(do_mob(usr, target, 50)) - if(can_enthrall(usr, target)) - handle_enthrall(usr, target) + if(do_mob(user, target, 50)) + if(can_enthrall(user, target)) + handle_enthrall(user, target) else - revert_cast(usr) - to_chat(usr, "You or your target either moved or you dont have enough usable blood.") + revert_cast(user) + to_chat(user, "You or your target either moved or you dont have enough usable blood.") /obj/effect/proc_holder/spell/vampire/targetted/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) var/enthrall_safe = 0 @@ -359,11 +359,11 @@ return name = "[initial(name)] ([user.mind.vampire.iscloaking ? "Deactivate" : "Activate"])" -/obj/effect/proc_holder/spell/vampire/self/cloak/cast() - var/datum/vampire/V = usr.mind.vampire +/obj/effect/proc_holder/spell/vampire/self/cloak/cast(list/targets, mob/user = usr) + var/datum/vampire/V = user.mind.vampire V.iscloaking = !V.iscloaking update_name() - to_chat(usr, "You will now be [V.iscloaking ? "hidden" : "seen"] in darkness.") + to_chat(user, "You will now be [V.iscloaking ? "hidden" : "seen"] in darkness.") /obj/effect/proc_holder/spell/vampire/bats name = "Summon Bats (75)" @@ -387,11 +387,11 @@ for(var/i = locs.len + 1 to num_bats) locs += user.loc - perform(locs) + perform(locs, user = user) -/obj/effect/proc_holder/spell/vampire/bats/cast(list/targets) +/obj/effect/proc_holder/spell/vampire/bats/cast(list/targets, mob/user = usr) for(var/T in targets) - new /mob/living/simple_animal/hostile/scarybat(T, usr) + new /mob/living/simple_animal/hostile/scarybat(T, user) /obj/effect/proc_holder/spell/vampire/self/jaunt name = "Mist Form (30)" @@ -402,12 +402,12 @@ required_blood = 30 var/jaunt_duration = 50 //in deciseconds -/obj/effect/proc_holder/spell/vampire/self/jaunt/cast() - if(usr.buckled) - usr.buckled.unbuckle_mob() +/obj/effect/proc_holder/spell/vampire/self/jaunt/cast(list/targets, mob/user = usr) + if(user.buckled) + user.buckled.unbuckle_mob() spawn(0) - var/mob/living/U = usr - var/originalloc = get_turf(usr.loc) + var/mob/living/U = user + var/originalloc = get_turf(user.loc) var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt(originalloc) var/atom/movable/overlay/animation = new /atom/movable/overlay(originalloc) animation.name = "water" @@ -418,34 +418,34 @@ animation.layer = 5 animation.master = holder U.ExtinguishMob() - if(usr.buckled) - usr.buckled.unbuckle_mob() + if(user.buckled) + user.buckled.unbuckle_mob() flick("liquify", animation) - usr.forceMove(holder) - usr.client.eye = holder + user.forceMove(holder) + user.client.eye = holder var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() steam.set_up(10, 0, originalloc) steam.start() sleep(jaunt_duration) - var/mobloc = get_turf(usr.loc) + var/mobloc = get_turf(user.loc) if(get_area(mobloc) == /area/security/armoury/gamma) - to_chat(usr, "A strange energy repels you!") + to_chat(user, "A strange energy repels you!") mobloc = originalloc animation.loc = mobloc steam.location = mobloc steam.start() - usr.canmove = 0 + user.canmove = 0 sleep(20) flick("reappear",animation) sleep(5) - if(!usr.Move(mobloc)) + if(!user.Move(mobloc)) for(var/direction in list(1,2,4,8,5,6,9,10)) var/turf/T = get_step(mobloc, direction) if(T) - if(usr.Move(T)) + if(user.Move(T)) break - usr.canmove = 1 - usr.client.eye = usr + user.canmove = 1 + user.client.eye = user qdel(animation) qdel(holder) @@ -479,8 +479,7 @@ if(T.y > world.maxy-outer_tele_radius || T.y < outer_tele_radius) continue - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/lightingcount = L.get_clamped_lum(0.5) * 10 + var/lightingcount = T.get_lumcount(0.5) * 10 // LIGHTING CHECK if(lightingcount > max_lum) @@ -492,29 +491,29 @@ to_chat(user, "\red You cannot find darkness to step to.") return - perform(turfs) + perform(turfs, user = user) -/obj/effect/proc_holder/spell/vampire/shadowstep/cast(list/targets) +/obj/effect/proc_holder/spell/vampire/shadowstep/cast(list/targets, mob/user = usr) if(usr.buckled) - usr.buckled.unbuckle_mob() + user.buckled.unbuckle_mob() spawn(0) var/turf/picked = pick(targets) if(!picked || !isturf(picked)) return - var/mob/living/U = usr + var/mob/living/U = user U.ExtinguishMob() - if(usr.buckled) - usr.buckled.unbuckle_mob() - var/atom/movable/overlay/animation = new /atom/movable/overlay(get_turf(usr)) - animation.name = usr.name + if(user.buckled) + user.buckled.unbuckle_mob() + var/atom/movable/overlay/animation = new /atom/movable/overlay(get_turf(user)) + animation.name = user.name animation.density = 0 animation.anchored = 1 - animation.icon = usr.icon + animation.icon = user.icon animation.alpha = 127 animation.layer = 5 //animation.master = src - usr.forceMove(picked) + user.forceMove(picked) spawn(10) qdel(animation) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 44565a6d157..7e9f98a64f2 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -60,7 +60,7 @@ switch(href_list["school"]) if("destruction") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null)) - M.mind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball(null)) + M.mind.AddSpell(new /obj/effect/proc_holder/spell/fireball(null)) to_chat(M, "Your service has not gone unrewarded, however. Studying under [H.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.") if("bluespace") M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null)) @@ -786,6 +786,7 @@ var/global/list/multiverse = list() GiveHint(target) cooldown = world.time +cooldown_time return + if(!link) if(I.loc == user && istype(I) && I.w_class <= 2) user.drop_item() @@ -794,13 +795,17 @@ var/global/list/multiverse = list() to_chat(user, "You attach [I] to the doll.") update_targets() ..() + /obj/item/voodoo/check_eye(mob/user as mob) - return src.loc == user + if(loc != user) + user.reset_perspective(null) + user.unset_machine() /obj/item/voodoo/attack_self(mob/user as mob) if(!target && possible.len) target = input(user, "Select your victim!", "Voodoo") as null|anything in possible return + if(user.zone_sel.selecting == "chest") if(link) target = null @@ -809,6 +814,7 @@ var/global/list/multiverse = list() link = null update_targets() return + if(target && cooldown < world.time) switch(user.zone_sel.selecting) if("mouth") diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index 3899d10d23c..7145a414d7e 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -1,7 +1,7 @@ /mob/proc/rightandwrong(var/summon_type) //0 = Summon Guns, 1 = Summon Magic - var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","hyperkinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam") + var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","arg","uzi","turret","pulsecarbine","decloner","mindflayer","kinetic","advplasmacutter","wormhole","wt550","grenadelauncher","medibeam") var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffhealing", "armor", "scrying", "staffdoor", "special","voodoo","special") var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos","necromantic") @@ -76,8 +76,8 @@ new /obj/item/weapon/gun/energy/decloner(get_turf(H)) if("mindflayer") new /obj/item/weapon/gun/energy/mindflayer(get_turf(H)) - if("hyperkinetic") - new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper(get_turf(H)) + if("kinetic") + new /obj/item/weapon/gun/energy/kinetic_accelerator(get_turf(H)) if("advplasmacutter") new /obj/item/weapon/gun/energy/plasmacutter/adv(get_turf(H)) if("wormhole") @@ -88,6 +88,8 @@ new /obj/item/weapon/gun/projectile/revolver/grenadelauncher(get_turf(H)) if("medibeam") new /obj/item/weapon/gun/medbeam(get_turf(H)) + + playsound(get_turf(H), 'sound/magic/Summon_guns.ogg', 50, 1) else switch(randomizemagic) if("fireball") @@ -155,3 +157,5 @@ if("necromantic") new /obj/item/device/necromantic_stone(get_turf(H)) to_chat(H, "You suddenly feel lucky.") + + playsound(get_turf(H), 'sound/magic/Summon_Magic.ogg', 50, 1) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 29eae864fb8..5a2d4ebb411 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -8,84 +8,118 @@ slot_flags = SLOT_BELT origin_tech = "bluespace=4;materials=4" var/imprinted = "empty" + + var/usability = TRUE // Can this soul stone be used by anyone, or only cultists/wizards? + var/reusable = TRUE // Can this soul stone be used more than once? + var/spent = FALSE // If the soul stone can only be used once, has it been used? +/obj/item/device/soulstone/proc/can_use(mob/living/user) + if(iscultist(user) || iswizard(user) || usability) + return TRUE -//////////////////////////////Capturing//////////////////////////////////////////////////////// + return FALSE + +/obj/item/device/soulstone/proc/was_used() + if(!reusable) + spent = TRUE + name = "dull [name]" + desc = "A fragment of the legendary treasure known simply as \ + the 'Soul Stone'. The shard lies still, dull and lifeless; \ + whatever spark it once held long extinguished." + +/obj/item/device/soulstone/anybody + usability = TRUE - attack(mob/living/carbon/human/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/human))//If target is not a human. - return ..() - if(istype(M, /mob/living/carbon/human/dummy)) - return ..() - - if(M.has_brain_worms()) //Borer stuff - RR - to_chat(user, "This being is corrupted by an alien intelligence and cannot be soul trapped.") - return ..() - - if(jobban_isbanned(M, "cultist") || jobban_isbanned(M, "Syndicate")) - to_chat(user, "A mysterious force prevents you from trapping this being's soul.") - return ..() - - M.attack_log += text("\[[time_stamp()]\] Has had their soul captured with [src.name] by [key_name(user)]") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to capture the soul of [key_name(M)]") - - log_attack("[key_name(user)] used the [src.name] to capture the soul of [key_name(M)]") - - - transfer_soul("VICTIM", M, user) +/obj/item/device/soulstone/anybody/chaplain + name = "mysterious old shard" + reusable = FALSE + +/obj/item/device/soulstone/pickup(mob/living/user) + ..() + if(!can_use(user)) + to_chat(user, "An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly.") + user.Dizzy(120) + +//////////////////////////////Capturing//////////////////////////////////////////////////////// +/obj/item/device/soulstone/attack(mob/living/carbon/human/M as mob, mob/user as mob) + if(!can_use(user)) + user.Paralyse(5) + to_chat(user, "Your body is wracked with debilitating pain!") return - /*attack(mob/living/simple_animal/shade/M as mob, mob/user as mob)//APPARENTLY THEY NEED THEIR OWN SPECIAL SNOWFLAKE CODE IN THE LIVING ANIMAL DEFINES - if(!istype(M, /mob/living/simple_animal/shade))//If target is not a shade - return ..() - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to capture the soul of [M.name] ([M.ckey])") - - transfer_soul("SHADE", M, user) - return*/ -///////////////////Options for using captured souls/////////////////////////////////////// - - attack_self(mob/user) - if(!in_range(src, user)) - return - user.set_machine(src) - var/dat = "Soul Stone
" - for(var/mob/living/simple_animal/shade/A in src) - dat += "Captured Soul: [A.name]
" - dat += {"Summon Shade"} - dat += "
" - dat += {" Close"} - user << browse(dat, "window=aicard") - onclose(user, "aicard") + if(spent) + to_chat(user, "There is no power left in the shard.") return + if(!ishuman(M) || istype(M, /mob/living/carbon/human/dummy)) //If target is not a human or a dummy + return ..() + + if(M.has_brain_worms()) //Borer stuff - RR + to_chat(user, "This being is corrupted by an alien intelligence and cannot be soul trapped.") + return ..() + if(jobban_isbanned(M, "cultist") || jobban_isbanned(M, "Syndicate")) + to_chat(user, "A mysterious force prevents you from trapping this being's soul.") + return ..() + M.create_attack_log("Has had their soul captured with [src.name] by [key_name(user)]") + user.create_attack_log("Used the [src.name] to capture the soul of [key_name(M)]") + log_attack("[key_name(user)] used the [src.name] to capture the soul of [key_name(M)]") - Topic(href, href_list) - var/mob/U = usr - if(!in_range(src, U)||U.machine!=src) + transfer_soul("VICTIM", M, user) + return + +///////////////////Options for using captured souls/////////////////////////////////////// +/obj/item/device/soulstone/attack_self(mob/user) + if(!in_range(src, user)) + return + + if(!can_use(user)) + user.Paralyse(5) + to_chat(user, "Your body is wracked with debilitating pain!") + return + + user.set_machine(src) + var/dat = "Soul Stone
" + for(var/mob/living/simple_animal/shade/A in src) + dat += "Captured Soul: [A.name]
" + dat += {"Summon Shade"} + dat += "
" + dat += {" Close"} + user << browse(dat, "window=aicard") + onclose(user, "aicard") + return + +/obj/item/device/soulstone/Topic(href, href_list) + var/mob/U = usr + if(!in_range(src, U) || U.machine != src || !can_use(usr)) + U << browse(null, "window=aicard") + U.unset_machine() + return + + add_fingerprint(U) + U.set_machine(src) + + switch(href_list["choice"])//Now we switch based on choice. + if("Close") U << browse(null, "window=aicard") U.unset_machine() return - add_fingerprint(U) - U.set_machine(src) - - switch(href_list["choice"])//Now we switch based on choice. - if("Close") - U << browse(null, "window=aicard") - U.unset_machine() - return - - if("Summon") - for(var/mob/living/simple_animal/shade/A in src) - A.status_flags &= ~GODMODE - A.canmove = 1 - to_chat(A, "You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.") - A.loc = U.loc - A.cancel_camera() - src.icon_state = "soulstone" - attack_self(U) + if("Summon") + for(var/mob/living/simple_animal/shade/A in src) + A.status_flags &= ~GODMODE + A.canmove = 1 + A.forceMove(get_turf(usr)) + A.cancel_camera() + icon_state = "soulstone" + name = initial(name) + if(iswizard(usr) || usability) + to_chat(A, "You have been released from your prison, but you are still bound to [usr.real_name]'s will. Help them succeed in their goals at all costs.") + else if(iscultist(usr)) + to_chat(A, "You have been released from your prison, but you are still bound to the cult's will. Help them succeed in their goals at all costs.") + was_used() + attack_self(U) ///////////////////////////Transferring to constructs///////////////////////////////////////////////////// /obj/structure/constructshell @@ -93,15 +127,30 @@ icon = 'icons/obj/wizard.dmi' icon_state = "construct" desc = "A wicked machine used by those skilled in magical arts. It is inactive" + +/obj/structure/constructshell/examine(mob/user) + if(..(user, 0)) + if(iscultist(user) || iswizard(user) || user.stat == DEAD) + to_chat(user, "A construct shell, used to house bound souls from a soulstone.") + to_chat(user, "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:") + to_chat(user, "An Artificer, which can produce more shells and soulstones, as well as fortifications.") + to_chat(user, "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile.") + to_chat(user, "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow.") /obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob, params) if(istype(O, /obj/item/device/soulstone)) - O.transfer_soul("CONSTRUCT",src,user) - + var/obj/item/device/soulstone/SS = O + if(!SS.can_use(user)) + to_chat(user, "An overwhelming feeling of dread comes over you as you attempt to place the soulstone into the shell. It would be wise to be rid of this quickly.") + user.Dizzy(120) + return + SS.transfer_soul("CONSTRUCT",src,user) + SS.was_used() + else + return ..() ////////////////////////////Proc for moving soul in and out off stone////////////////////////////////////// - /obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob). switch(choice) if("FORCE") @@ -238,7 +287,6 @@ to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") newstruct.cancel_camera() - /obj/item/device/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0) new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton T.invisibility = 101 @@ -268,7 +316,6 @@ if(vic && U) to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from their body and stored within the soul stone.") - /obj/item/device/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U) var/mob/dead/observer/chosen_ghost diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 4c06f84d7cd..3c59d47f020 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -103,7 +103,7 @@ /datum/spellbook_entry/fireball name = "Fireball" - spell_type = /obj/effect/proc_holder/spell/dumbfire/fireball + spell_type = /obj/effect/proc_holder/spell/fireball log_name = "FB" /datum/spellbook_entry/magicm @@ -699,7 +699,7 @@ else user.mind.AddSpell(S) to_chat(user, "you rapidly read through the arcane book. Suddenly you realize you understand [spellname]!") - user.attack_log += text("\[[time_stamp()]\] [user.real_name] ([user.ckey]) learned the spell [spellname] ([S]).") + user.create_attack_log("[user.real_name] ([user.ckey]) learned the spell [spellname] ([S]).") onlearned(user) @@ -714,7 +714,7 @@ return /obj/item/weapon/spellbook/oneuse/fireball - spell = /obj/effect/proc_holder/spell/dumbfire/fireball + spell = /obj/effect/proc_holder/spell/fireball spellname = "fireball" icon_state ="bookfireball" desc = "This book feels warm to the touch." @@ -848,9 +848,14 @@ to_chat(user, "[src] suddenly vanishes!") qdel(src) - /obj/item/weapon/spellbook/oneuse/fake_gib spell = /obj/effect/proc_holder/spell/targeted/touch/fake_disintegrate spellname = "disintegrate" icon_state ="bookfireball" desc = "This book feels like it will rip stuff apart." + +/obj/item/weapon/spellbook/oneuse/sacredflame + spell = /obj/effect/proc_holder/spell/targeted/sacred_flame + spellname = "sacred flame" + icon_state ="booksacredflame" + desc = "Become one with the flames that burn within... and invite others to do so as well." \ No newline at end of file diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index a38e7dc5541..c00e0436473 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -38,7 +38,7 @@ /datum/game_mode/wizard/pre_setup() for(var/datum/mind/wiz in wizards) wiz.current.loc = pick(wizardstart) - + ..() return 1 @@ -54,20 +54,20 @@ update_wiz_icons_added(wizard) ..() - + /datum/game_mode/proc/remove_wizard(datum/mind/wizard_mind) if(wizard_mind in wizards) ticker.mode.wizards -= wizard_mind wizard_mind.special_role = null - wizard_mind.current.attack_log += "\[[time_stamp()]\] De-wizarded" + wizard_mind.current.create_attack_log("De-wizarded") wizard_mind.current.spellremove(wizard_mind.current) wizard_mind.current.faction = list("Station") if(issilicon(wizard_mind.current)) to_chat(wizard_mind.current, "You have been turned into a robot! You can feel your magical powers fading away...") else to_chat(wizard_mind.current, "You have been brainwashed! You are no longer a wizard.") - ticker.mode.update_wiz_icons_removed(wizard_mind) - + ticker.mode.update_wiz_icons_removed(wizard_mind) + /datum/game_mode/proc/update_wiz_icons_added(datum/mind/wiz_mind) var/datum/atom_hud/antag/wizhud = huds[ANTAG_HUD_WIZ] wizhud.join_hud(wiz_mind.current) diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 0384276a5e6..7e6f664252f 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -4,6 +4,7 @@ department_flag = ENGSEC total_positions = 1 spawn_positions = 1 + is_engineering = 1 supervisors = "the captain" selection_color = "#ffeeaa" idtype = /obj/item/weapon/card/id/ce @@ -45,6 +46,7 @@ department_flag = ENGSEC total_positions = 5 spawn_positions = 5 + is_engineering = 1 supervisors = "the chief engineer" selection_color = "#fff5cc" idtype = /obj/item/weapon/card/id/engineering @@ -76,6 +78,7 @@ department_flag = ENGSEC total_positions = 3 spawn_positions = 2 + is_engineering = 1 supervisors = "the chief engineer" selection_color = "#fff5cc" idtype = /obj/item/weapon/card/id/engineering @@ -103,6 +106,7 @@ department_flag = KARMA total_positions = 1 spawn_positions = 1 + is_engineering = 1 supervisors = "the chief engineer" selection_color = "#fff5cc" idtype = /obj/item/weapon/card/id/engineering diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 52a33e0f0fb..b4dc5610ce6 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -38,6 +38,16 @@ //If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect. var/req_admin_notify + //Various Departmental identifiers + var/is_supply + var/is_service + var/is_command + var/is_legal + var/is_engineering + var/is_medical + var/is_science + var/is_security + //If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.) var/minimal_player_age = 0 diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 64b34a4fa79..9e4e5f5acee 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -4,6 +4,7 @@ department_flag = MEDSCI total_positions = 1 spawn_positions = 1 + is_medical = 1 supervisors = "the captain" selection_color = "#ffddf0" idtype = /obj/item/weapon/card/id/cmo @@ -43,6 +44,7 @@ department_flag = MEDSCI total_positions = 5 spawn_positions = 3 + is_medical = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical @@ -103,6 +105,7 @@ department_flag = MEDSCI total_positions = 2 spawn_positions = 2 + is_medical = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical @@ -134,6 +137,7 @@ department_flag = MEDSCI total_positions = 2 spawn_positions = 2 + is_medical = 1 supervisors = "the chief medical officer and the research director" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical @@ -162,6 +166,7 @@ department_flag = MEDSCI total_positions = 1 spawn_positions = 1 + is_medical = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical @@ -192,6 +197,7 @@ department_flag = MEDSCI total_positions = 1 spawn_positions = 1 + is_medical = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical @@ -229,6 +235,7 @@ department_flag = MEDSCI total_positions = 1 spawn_positions = 1 + is_medical = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" idtype = /obj/item/weapon/card/id/medical diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 7ea2eb5464f..2e07a08b2bc 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -4,6 +4,7 @@ department_flag = MEDSCI total_positions = 1 spawn_positions = 1 + is_science = 1 supervisors = "the captain" selection_color = "#ffddff" req_admin_notify = 1 @@ -49,6 +50,7 @@ department_flag = MEDSCI total_positions = 6 spawn_positions = 6 + is_science = 1 supervisors = "the research director" selection_color = "#ffeeff" idtype = /obj/item/weapon/card/id/research @@ -84,6 +86,7 @@ department_flag = MEDSCI total_positions = 2 spawn_positions = 2 + is_science = 1 supervisors = "the research director" selection_color = "#ffeeff" idtype = /obj/item/weapon/card/id/research diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 19539a83f4e..cd1e3fb370d 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -4,6 +4,7 @@ department_flag = ENGSEC total_positions = 1 spawn_positions = 1 + is_security = 1 supervisors = "the captain" selection_color = "#ffdddd" idtype = /obj/item/weapon/card/id/hos @@ -52,6 +53,7 @@ department_flag = ENGSEC total_positions = 1 spawn_positions = 1 + is_security = 1 supervisors = "the head of security" selection_color = "#ffeeee" idtype = /obj/item/weapon/card/id/security @@ -94,6 +96,7 @@ department_flag = ENGSEC total_positions = 1 spawn_positions = 1 + is_security = 1 supervisors = "the head of security" selection_color = "#ffeeee" alt_titles = list("Forensic Technician") @@ -148,6 +151,7 @@ department_flag = ENGSEC total_positions = 5 spawn_positions = 5 + is_security = 1 supervisors = "the head of security" selection_color = "#ffeeee" idtype = /obj/item/weapon/card/id/security @@ -185,6 +189,7 @@ department_flag = KARMA total_positions = 1 spawn_positions = 1 + is_security = 1 supervisors = "the head of security" selection_color = "#ffeeee" idtype = /obj/item/weapon/card/id/security @@ -218,6 +223,7 @@ department_flag = KARMA total_positions = 1 spawn_positions = 1 + is_security = 1 supervisors = "the head of security" selection_color = "#ffeeee" idtype = /obj/item/weapon/card/id/security diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 586fd27d639..090fc6681a0 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -1,4 +1,4 @@ -var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) +var/datum/announcement/minor/captain_announcement = new(do_newscast = 0) /datum/job/captain title = "Captain" flag = CAPTAIN @@ -9,6 +9,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) selection_color = "#ccccff" idtype = /obj/item/weapon/card/id/gold req_admin_notify = 1 + is_command = 1 access = list() //See get_access() minimal_access = list() //See get_access() minimal_player_age = 30 @@ -57,6 +58,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) selection_color = "#ddddff" idtype = /obj/item/weapon/card/id/silver req_admin_notify = 1 + is_command = 1 minimal_player_age = 21 exp_requirements = 600 exp_type = EXP_TYPE_CREW @@ -101,6 +103,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) selection_color = "#ddddff" idtype = /obj/item/weapon/card/id/nanotrasen req_admin_notify = 1 + is_command = 1 minimal_player_age = 21 access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_eva, access_heads, @@ -145,6 +148,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) selection_color = "#ddddff" idtype = /obj/item/weapon/card/id/nanotrasen req_admin_notify = 1 + is_command = 1 minimal_player_age = 21 access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_eva, access_heads, @@ -187,6 +191,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) selection_color = "#ddddff" idtype = /obj/item/weapon/card/id/nanotrasen req_admin_notify = 1 + is_legal = 1 minimal_player_age = 30 access = list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers, access_medical, access_engine, access_change_ids, access_eva, access_heads, @@ -225,6 +230,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) department_flag = SUPPORT total_positions = 2 spawn_positions = 2 + is_legal = 1 supervisors = "the magistrate" selection_color = "#ddddff" access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 1f475891103..2148c339000 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -5,6 +5,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" access = list(access_hydroponics, access_bar, access_kitchen, access_morgue, access_weapons, access_mineral_storeroom) @@ -41,6 +42,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" access = list(access_hydroponics, access_bar, access_kitchen, access_morgue) @@ -71,10 +73,11 @@ department_flag = SUPPORT total_positions = 3 spawn_positions = 2 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" - access = list(access_hydroponics, access_bar, access_kitchen) - minimal_access = list(access_hydroponics, access_maint_tunnels) + access = list(access_hydroponics, access_bar, access_kitchen, access_morgue) + minimal_access = list(access_hydroponics, access_morgue, access_maint_tunnels) alt_titles = list("Hydroponicist", "Botanical Researcher") @@ -89,7 +92,7 @@ H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes) H.equip_or_collect(new /obj/item/clothing/gloves/botanic_leather(H), slot_gloves) H.equip_or_collect(new /obj/item/clothing/suit/apron(H), slot_wear_suit) - H.equip_or_collect(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store) + H.equip_or_collect(new /obj/item/device/plant_analyzer(H), slot_s_store) H.equip_or_collect(new /obj/item/device/pda/botanist(H), slot_wear_pda) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_in_backpack) return 1 @@ -103,6 +106,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_supply = 1 supervisors = "the head of personnel" selection_color = "#dddddd" idtype = /obj/item/weapon/card/id/supply @@ -133,6 +137,7 @@ department_flag = SUPPORT total_positions = 2 spawn_positions = 2 + is_supply = 1 supervisors = "the quartermaster" selection_color = "#dddddd" idtype = /obj/item/weapon/card/id/supply @@ -161,6 +166,7 @@ department_flag = SUPPORT total_positions = 3 spawn_positions = 3 + is_supply = 1 supervisors = "the quartermaster" selection_color = "#dddddd" idtype = /obj/item/weapon/card/id/supply @@ -200,6 +206,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" idtype = /obj/item/weapon/card/id/clown @@ -244,6 +251,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" idtype = /obj/item/weapon/card/id/mime @@ -284,6 +292,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" access = list(access_janitor, access_maint_tunnels) @@ -313,6 +322,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" access = list(access_library, access_maint_tunnels) @@ -343,6 +353,7 @@ department_flag = KARMA total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" alt_titles = list("Hair Stylist","Beautician") diff --git a/code/game/jobs/job/support_chaplain.dm b/code/game/jobs/job/support_chaplain.dm index 5904cd4b020..da9bd5c8ec1 100644 --- a/code/game/jobs/job/support_chaplain.dm +++ b/code/game/jobs/job/support_chaplain.dm @@ -5,6 +5,7 @@ department_flag = SUPPORT total_positions = 1 spawn_positions = 1 + is_service = 1 supervisors = "the head of personnel" selection_color = "#dddddd" access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels) diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 93d048ce96e..a770084dbbc 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -51,6 +51,8 @@ var/global/datum/controller/occupations/job_master if(!job) return 0 if(jobban_isbanned(player, rank)) return 0 if(!job.player_old_enough(player.client)) return 0 + if(job.available_in_playtime(player.client)) + return 0 if(!is_job_whitelisted(player, rank)) return 0 var/position_limit = job.total_positions if(!latejoin) @@ -87,13 +89,16 @@ var/global/datum/controller/occupations/job_master Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]") var/list/candidates = list() for(var/mob/new_player/player in unassigned) - Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]") + Debug(" - Player: [player] Banned: [jobban_isbanned(player, job.title)] Old Enough: [!job.player_old_enough(player.client)] AvInPlaytime: [job.available_in_playtime(player.client)] Flag && Be Special: [flag] && [player.client.prefs.be_special] Job Department: [player.client.prefs.GetJobDepartment(job, level)] Job Flag: [job.flag] Job Department Flag = [job.department_flag]") if(jobban_isbanned(player, job.title)) Debug("FOC isbanned failed, Player: [player]") continue if(!job.player_old_enough(player.client)) Debug("FOC player not old enough, Player: [player]") continue + if(job.available_in_playtime(player.client)) + Debug("FOC player not enough playtime, Player: [player]") + continue if(flag && !(flag in player.client.prefs.be_special)) Debug("FOC flag failed, Player: [player], Flag: [flag], ") continue @@ -123,9 +128,6 @@ var/global/datum/controller/occupations/job_master if(job.admin_only) // No admin positions either. continue - if(job.available_in_playtime(player.client)) - continue - if(jobban_isbanned(player, job.title)) Debug("GRJ isbanned failed, Player: [player], Job: [job.title]") continue @@ -134,6 +136,10 @@ var/global/datum/controller/occupations/job_master Debug("GRJ player not old enough, Player: [player]") continue + if(job.available_in_playtime(player.client)) + Debug("GRJ player not enough playtime, Player: [player]") + continue + if(player.mind && job.title in player.mind.restricted_roles) Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") continue @@ -252,7 +258,8 @@ var/global/datum/controller/occupations/job_master for(var/mob/new_player/player in player_list) if(player.ready && player.mind && !player.mind.assigned_role) unassigned += player - if(player.client.prefs.randomslot) player.client.prefs.random_character(player.client) + if(player.client.prefs.randomslot) + player.client.prefs.load_random_character_slot(player.client) Debug("DO, Len: [unassigned.len]") if(unassigned.len == 0) return 0 @@ -312,6 +319,10 @@ var/global/datum/controller/occupations/job_master Debug("DO player not old enough, Player: [player], Job:[job.title]") continue + if(job.available_in_playtime(player.client)) + Debug("DO player not enough playtime, Player: [player], Job:[job.title]") + continue + if(player.mind && job.title in player.mind.restricted_roles) Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") continue @@ -358,19 +369,19 @@ var/global/datum/controller/occupations/job_master Debug("DO, Running AC2") - // For those who wanted to be civilians if their preferences were filled, here you go. + // Antags, who have to get in, come first + for(var/mob/new_player/player in unassigned) + if(player.mind.special_role) + GiveRandomJob(player) + if(player in unassigned) + AssignRole(player, "Civilian") + + // Then we assign what we can to everyone else. for(var/mob/new_player/player in unassigned) if(player.client.prefs.alternate_option == BE_ASSISTANT) Debug("AC2 Assistant located, Player: [player]") AssignRole(player, "Civilian") - - for(var/mob/new_player/player in unassigned) - if(player.mind.special_role) - GiveRandomJob(player) - - //For ones returning to lobby - for(var/mob/new_player/player in unassigned) - if(player.client.prefs.alternate_option == RETURN_TO_LOBBY) + else if(player.client.prefs.alternate_option == RETURN_TO_LOBBY) player.ready = 0 unassigned -= player return 1 @@ -537,6 +548,23 @@ var/global/datum/controller/occupations/job_master to_chat(H, "You are the [alt_title ? alt_title : rank].") to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.") + to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") + if(job.is_service) + to_chat(H, "As a member of Service, make sure to read up on your Department SOP") + if(job.is_supply) + to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") + if(job.is_command) + to_chat(H, "As an important member of Command, read up on your Department SOP") + if(job.is_legal) + to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") + if(job.is_engineering) + to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") + if(job.is_medical) + to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") + if(job.is_science) + to_chat(H, "As a member of Science, make sure to read up on your Department SOP") + if(job.is_security) + to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") if(job.req_admin_notify) to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.") @@ -656,6 +684,9 @@ var/global/datum/controller/occupations/job_master if(!job.player_old_enough(player.client)) level6++ continue + if(job.available_in_playtime(player.client)) + level6++ + continue if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) level1++ else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index 23d217a83bc..746dfcacf44 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -106,9 +106,12 @@ /client/proc/get_exp_living() + return get_exp_format(get_exp_living_num()) + +/client/proc/get_exp_living_num() var/list/play_records = params2list(prefs.exp) var/exp_living = text2num(play_records[EXP_TYPE_LIVING]) - return get_exp_format(exp_living) + return exp_living /proc/get_exp_format(var/expnum) if(expnum > 60) diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index 873b86d9400..eb610c771a7 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -23,6 +23,15 @@ computer.table = src break +/obj/machinery/optable/Destroy() + if(computer) + computer.table = null + computer.victim = null + computer = null + if(victim) + victim = null + return ..() + /obj/machinery/optable/ex_act(severity) switch(severity) if(1.0) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 0e0067eafe9..2a29e23db73 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -390,6 +390,12 @@ go_out() ..(severity) +/obj/machinery/sleeper/narsie_act() + go_out() + new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH! + qdel(src) + + // ??? // This looks cool, although mildly broken, should it be included again? /obj/machinery/sleeper/alter_health(mob/living/M as mob) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 538e389c083..4f9e357cd61 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -193,6 +193,11 @@ A.blob_act() qdel(src) +/obj/machinery/bodyscanner/narsie_act() + go_out() + new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH! + qdel(src) + /obj/machinery/bodyscanner/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise if(M.environment_smash) M.do_attack_animation(src) @@ -448,6 +453,7 @@ occupantData["intOrgan"] = intOrganData occupantData["blind"] = (H.disabilities & BLIND) + occupantData["colourblind"] = (H.disabilities & COLOURBLIND) occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED) data["occupant"] = occupantData @@ -634,6 +640,8 @@ dat += "" if(occupant.disabilities & BLIND) dat += "Cataracts detected.
" + if(occupant.disabilities & COLOURBLIND) + dat += "Photoreceptor abnormalities detected.
" if(occupant.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" else diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index a5db47222e6..efa6a1ded81 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -572,34 +572,6 @@ frequency.post_signal(src, alert_signal) -/obj/machinery/alarm/proc/air_doors_close(manual) - var/area/A = get_area(src) - if(!A.air_doors_activated) - A.air_doors_activated = 1 - for(var/obj/machinery/door/E in A.all_doors) - if(istype(E,/obj/machinery/door/firedoor)) - if(!E:blocked) - if(E.operating) - E:nextstate = CLOSED - else if(!E.density) - spawn(0) - E.close() - continue - -/obj/machinery/alarm/proc/air_doors_open(manual) - var/area/A = get_area(loc) - if(A.air_doors_activated) - A.air_doors_activated = 0 - for(var/obj/machinery/door/E in A.all_doors) - if(istype(E, /obj/machinery/door/firedoor)) - if(!E:blocked) - if(E.operating) - E:nextstate = OPEN - else if(E.density) - spawn(0) - E.open() - continue - /////////////// //END HACKING// /////////////// diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index e52cf428fd3..6ae47a3042d 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -142,7 +142,7 @@ if(do_after(user, 14.4, target = src)) files.AddDesign2Known(D.blueprint) busy = 0 - else + else to_chat(user, "That disk does not have a design on it!") return 1 else @@ -298,6 +298,9 @@ desc = initial(desc) /obj/machinery/autolathe/proc/can_build(var/datum/design/D,var/multiplier=1,var/custom_metal,var/custom_glass) + if(D.make_reagents.len) + return 0 + var/coeff = get_coeff(D) var/metal_amount = materials.amount(MAT_METAL) diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm deleted file mode 100644 index 6344dec7bbf..00000000000 --- a/code/game/machinery/biogenerator.dm +++ /dev/null @@ -1,389 +0,0 @@ -/obj/machinery/biogenerator - name = "biogenerator" - desc = "Converts plants into biomass, which can be used to construct useful items." - icon = 'icons/obj/biogenerator.dmi' - icon_state = "biogen-empty" - density = 1 - anchored = 1 - use_power = 1 - idle_power_usage = 40 - var/processing = 0 - var/obj/item/weapon/reagent_containers/glass/beaker = null - var/points = 0 - var/in_beaker = 1 - var/menustat = "menu" - var/efficiency = 0 - var/productivity = 0 - var/max_items = 40 - -/obj/machinery/biogenerator/New() - ..() - create_reagents(1000) - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/biogenerator(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/stack/cable_coil(null, 1) - RefreshParts() - -/obj/machinery/biogenerator/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/biogenerator(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/stack/cable_coil(null, 1) - RefreshParts() - -/obj/machinery/biogenerator/RefreshParts() - var/E = 0 - var/P = 0 - var/max_storage = 40 - for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) - P += B.rating - max_storage = 40 * B.rating - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - E += M.rating - efficiency = E - productivity = P - max_items = max_storage - -/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. - update_icon() - -/obj/machinery/biogenerator/update_icon() - if(panel_open) - icon_state = "biogen-empty-o" - else if(!src.beaker) - icon_state = "biogen-empty" - else if(!src.processing) - icon_state = "biogen-stand" - else - icon_state = "biogen-work" - return - -/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/weapon/reagent_containers/glass) && !panel_open) - if(beaker) - to_chat(user, "A container is already loaded into the machine.") - return - else - if(!user.drop_item()) - to_chat(user, "\The [O] is stuck to you!") - return - O.forceMove(src) - beaker = O - to_chat(user, "You add the container to the machine.") - updateUsrDialog() - update_icon() - return - - if(!processing) - if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) - if(beaker) - var/obj/item/weapon/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - return - - if(exchange_parts(user, O)) - return - - else if(istype(O, /obj/item/weapon/crowbar)) - else if(panel_open) - to_chat(user, "Close the maintenance panel first.") - else if(processing) - to_chat(user, "The biogenerator is currently processing.") - else if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/PB = O - var/i = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) - i++ - if(i >= max_items) - to_chat(user, "The biogenerator is already full! Activate it.") - else - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents) - if(i >= max_items) - break - PB.remove_from_storage(G, src) - i++ - if(i < max_items) - to_chat(user, "You empty the plant bag into the biogenerator.") - else if(O.contents.len == 0) - to_chat(user, "You empty the plant bag into the biogenerator, filling it to its capacity.") - else - to_chat(user, "You fill the biogenerator to its capacity.") - - else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) && !istype(O, /obj/item/weapon/crowbar)) - to_chat(user, "You can not put this in [src.name]") - else - var/i = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) - i++ - if(i >= max_items) - to_chat(user, "The biogenerator is full! Activate it.") - else - user.unEquip(O) - O.forceMove(src) - to_chat(user, "You put [O.name] in [src.name]") - - - default_deconstruction_crowbar(O) - - update_icon() - return - -/obj/machinery/biogenerator/interact(mob/user as mob) - if(stat & BROKEN || panel_open) - return - user.set_machine(src) - var/dat - if(processing) - dat += "
Biogenerator is processing! Please wait...

" - else - switch(menustat) - if("nopoints") - dat += "
You do not have sufficient biomass to create products.
Please put growns into the reactor and activate it.
" - menustat = "menu" - if("complete") - dat += "
Operation complete.
" - menustat = "menu" - if("void") - dat += "
Error: No growns inside.
Please put growns into reactor.
" - menustat = "menu" - if("nobeakerspace") - dat += "
Not enough space left in container. Unable to create product.
" - menustat = "menu" - if(beaker) - dat += "
Biomass: [points] units.

" - dat += "ActivateDetach Container
" - dat += "Put fertilizer in: [in_beaker ? "Beaker" : "Bottle"]" - dat += "

Food:

" - dat += "
" - dat += "10 milk: Make ([20/efficiency])
" - dat += "10 cream: Make ([30/efficiency])
" - dat += "Monkey cube: Make ([250/efficiency])" - dat += "
" - dat += "

Nutrients:

" - dat += "
" - dat += "E-Z-Nutrient: Makex5 ([10/efficiency])
" - dat += "Left 4 Zed: Makex5 ([20/efficiency])
" - dat += "Robust Harvest: Makex5 ([25/efficiency])
" - dat += "
" - dat += "

Leather:

" - dat += "
" - dat += "Wallet: Make ([100/efficiency])
" - dat += "Book bag: Make ([200/efficiency])
" - dat += "Plant bag: Make ([200/efficiency])
" - dat += "Rag: Make ([200/efficiency])
" - dat += "Mining satchel: Make ([200/efficiency])
" - dat += "Chemistry bag: Make ([200/efficiency])
" - dat += "Botanical gloves: Make ([250/efficiency])
" - dat += "Leather Satchel: Make ([400/efficiency])
" - dat += "Cash Bag: Make ([400/efficiency])
" - dat += "Leather Jacket: Make ([500/efficiency])
" - dat += "
" - dat += "

Belts

" - dat += "
" - dat += "Utility belt: Make ([300/efficiency])
" - dat += "Botanist belt: Make ([300/efficiency])
" - dat += "Security belt: Make ([300/efficiency])
" - dat += "Medical belt: Make ([300/efficiency])
" - dat += "Janitor belt: Make ([300/efficiency])
" - dat += "Bandolier: Make ([300/efficiency])
" - dat += "
" - //dat += "

Other:

" - //dat += "Monkey: Make ([400/efficiency])
" - else - dat += "
No container inside. Please insert a container.
" - - var/datum/browser/popup = new(user, "biogen", name, 350, 520) - popup.set_content(dat) - popup.open() - return - -/obj/machinery/biogenerator/attack_hand(mob/user as mob) - interact(user) - -/obj/machinery/biogenerator/proc/activate() - if(usr.stat != 0) - return - if(src.stat != 0) //NOPOWER etc - return - if(src.processing) - to_chat(usr, "The biogenerator is in the process of working.") - return - var/S = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents) - S += 5 - var/reagent_amount = I.reagents.get_reagent_amount("nutriment") + I.reagents.get_reagent_amount("plantmatter") - if(reagent_amount < 0.1) - points += 1*productivity - else points += reagent_amount*10*productivity - qdel(I) - if(S) - processing = 1 - update_icon() - updateUsrDialog() - playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) - use_power(S*30) - sleep(S+15/productivity) - processing = 0 - update_icon() - else - menustat = "void" - return - -/obj/machinery/biogenerator/proc/check_cost(var/cost, var/checkonly) - if(cost > points) - menustat = "nopoints" - return 1 - else if(checkonly) - return 0 - else - points -= cost - processing = 1 - update_icon() - updateUsrDialog() - return 0 - -/obj/machinery/biogenerator/proc/check_container_volume(var/reagent_amount) - if(beaker.reagents.total_volume + reagent_amount > beaker.reagents.maximum_volume) - menustat = "nobeakerspace" - return 1 - -/obj/machinery/biogenerator/proc/create_product(var/create) - switch(create) - //Food - if("milk") - if(check_container_volume(10)) return 0 - else if(check_cost(20/efficiency)) return 0 - else beaker.reagents.add_reagent("milk",10) - if("cream") - if(check_container_volume(10)) return 0 - else if(check_cost(30/efficiency)) return 0 - else beaker.reagents.add_reagent("cream",10) - if("meat") - if(check_cost(250/efficiency)) return 0 - else new/obj/item/weapon/reagent_containers/food/snacks/monkeycube(src.loc) - //Nutrients - if("ez") - if(check_cost(10/efficiency, 1)) return 0 - if(in_beaker) - if(check_container_volume(10)) return 0 - else beaker.reagents.add_reagent("eznutrient",10) - else - new/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez(src.loc) - if(check_cost(10/efficiency)) return 0 - if("l4z") - if(check_cost(20/efficiency, 1)) return 0 - if(in_beaker) - if(check_container_volume(10)) return 0 - else beaker.reagents.add_reagent("left4zed",10) - else - new/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/l4z(src.loc) - if(check_cost(20/efficiency)) return 0 - if("rh") - if(check_cost(25/efficiency, 1)) return 0 - if(in_beaker) - if(check_container_volume(10)) return 0 - else beaker.reagents.add_reagent("robustharvest",10) - else - new/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/rh(src.loc) - if(check_cost(25/efficiency)) return 0 - //Leather - if("wallet") - if(check_cost(100/efficiency)) return 0 - else new/obj/item/weapon/storage/wallet(src.loc) - if("bkbag") - if(check_cost(200/efficiency)) return 0 - else new/obj/item/weapon/storage/bag/books(src.loc) - if("ptbag") - if(check_cost(200/efficiency)) return 0 - else new/obj/item/weapon/storage/bag/plants(src.loc) - if("mnbag") - if(check_cost(200/efficiency)) return 0 - else new/obj/item/weapon/storage/bag/ore(src.loc) - if("chbag") - if(check_cost(200/efficiency)) return 0 - else new/obj/item/weapon/storage/bag/chemistry(src.loc) - if("rag") - if(check_cost(200/efficiency)) return 0 - else new/obj/item/weapon/reagent_containers/glass/rag(src.loc) - if("gloves") - if(check_cost(250/efficiency)) return 0 - else new/obj/item/clothing/gloves/botanic_leather(src.loc) - if("satchel") - if(check_cost(400/efficiency)) return 0 - else new/obj/item/weapon/storage/backpack/satchel(src.loc) - if("cashbag") - if(check_cost(400/efficiency)) return 0 - else new/obj/item/weapon/storage/bag/cash(src.loc) - if("jacket") - if(check_cost(500/efficiency)) return 0 - else new/obj/item/clothing/suit/jacket/leather(src.loc) - //Belts - if("tbelt") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/utility(src.loc) - if("bbelt") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/botany(src.loc) - if("sbelt") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/security(src.loc) - if("mbelt") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/medical(src.loc) - if("jbelt") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/janitor(src.loc) - if("band") - if(check_cost(300/efficiency)) return 0 - else new/obj/item/weapon/storage/belt/bandolier(src.loc) - processing = 0 - menustat = "complete" - update_icon() - return 1 - -/obj/machinery/biogenerator/proc/detach() - if(beaker) - beaker.forceMove(src.loc) - beaker = null - update_icon() - -/obj/machinery/biogenerator/Topic(href, href_list) - if(..() || panel_open) - return 1 - - usr.set_machine(src) - - if(href_list["activate"]) - activate() - updateUsrDialog() - - else if(href_list["detach"]) - detach() - updateUsrDialog() - - else if(href_list["create"]) - var/amount = (text2num(href_list["amount"])) - var/i = amount - var/C = href_list["create"] - if(i <= 0) - return - while(i >= 1) - create_product(C) - i-- - processing = 0 - updateUsrDialog() - - else if(href_list["menu"]) - menustat = "menu" - updateUsrDialog() - - else if(href_list["inbeaker"]) - in_beaker = !in_beaker - updateUsrDialog() \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index c131652a69a..8ba7558d69b 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -103,10 +103,7 @@ //TO-DO: Make the genetics machine accept them. /obj/item/weapon/disk/data name = "Cloning Data Disk" - icon = 'icons/obj/cloning.dmi' icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. - item_state = "card-id" - w_class = 1 var/datum/dna2/record/buf=null var/read_only = 0 //Well,it's still a floppy disk diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 31700f8c2d3..19d61e0daf9 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -29,6 +29,14 @@ table.computer = src break +/obj/machinery/computer/operating/Destroy() + if(table) + table.computer = null + table = null + if(victim) + victim = null + return ..() + /obj/machinery/computer/operating/attack_ai(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) @@ -94,7 +102,9 @@ /obj/machinery/computer/operating/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) var/data[0] - var/mob/living/carbon/human/occupant = src.table.victim + var/mob/living/carbon/human/occupant + if(table) + occupant = table.victim data["hasOccupant"] = occupant ? 1 : 0 var/occupantData[0] diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 0c09bc5f2c5..71aad1085ff 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -39,6 +39,10 @@ name = "Circuit board (Camera Monitor)" build_path = /obj/machinery/computer/security origin_tech = "programming=2" +/obj/item/weapon/circuitboard/xenobiology + name = "Circuit board (Xenobiology Console)" + build_path = /obj/machinery/computer/camera_advanced/xenobio + origin_tech = "programming=3;biotech=3" /obj/item/weapon/circuitboard/aicore name = "Circuit board (AI Core)" origin_tech = "programming=4;biotech=2" diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index ebba68ec570..66e2ec25779 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -439,3 +439,5 @@ var/time_last_changed_position = 0 name = "\improper CentComm identification computer" circuit = /obj/item/weapon/circuitboard/card/centcom req_access = list(access_cent_commander) + change_position_cooldown = -1 + blacklisted = list() \ No newline at end of file diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 86a8b2d2bcf..8b838ceade5 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -39,7 +39,7 @@ /obj/machinery/computer/communications/New() shuttle_caller_list += src ..() - crew_announcement.newscast = 1 + crew_announcement.newscast = 0 /obj/machinery/computer/communications/proc/is_authenticated(var/mob/user, var/message = 1) if(authenticated == COMM_AUTHENTICATION_MAX) @@ -292,12 +292,12 @@ to_chat(usr, "Docking request accepted!") trade_dock_timelimit = world.time + 1200 trade_dockrequest_timelimit = 0 - command_announcement.Announce("Docking request for trading ship approved, please dock at port bay 4.", "Docking Request") + event_announcement.Announce("Docking request for trading ship approved, please dock at port bay 4.", "Docking Request") if("DenyDocking") to_chat(usr, "Docking requeset denied!") trade_dock_timelimit = 0 trade_dockrequest_timelimit = 0 - command_announcement.Announce("Docking request for trading ship denied.", "Docking request") + event_announcement.Announce("Docking request for trading ship denied.", "Docking request") nanomanager.update_uis(src) return 1 diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 1b8004f88cc..1162735db96 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -524,3 +524,4 @@ icon_state = "laptop" icon_keyboard = "laptop_key" icon_screen = "medlaptop" + density = 0 diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 1634ebdc4a0..2a11b4a8836 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -369,7 +369,7 @@ What a mess.*/ var/counter = 1 while(active2.fields[text("com_[]", counter)]) counter++ - active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], 2557
[t1]") + active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [worldtime2text()]
[t1]") if("Delete Record (ALL)") if(active1) diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 027b182e0c0..ee90fcc3b21 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -6,6 +6,7 @@ icon_state = "laptop" icon_keyboard = "laptop_key" icon_screen = "medlaptop" + density = 0 light_color = LIGHT_COLOR_GREEN req_one_access = list(access_heads) circuit = /obj/item/weapon/circuitboard/skills diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index d7384290164..70f0195ce5d 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -230,6 +230,7 @@ to destroy them and players will be able to make replacements. var/list/names_paths = list("Booze-O-Mat" = /obj/machinery/vending/boozeomat, "Solar's Best Hot Drinks" = /obj/machinery/vending/coffee, "Getmore Chocolate Corp" = /obj/machinery/vending/snack, + "Mr. Chang" = /obj/machinery/vending/chinese, "Robust Softdrinks" = /obj/machinery/vending/cola, "ShadyCigs Deluxe" = /obj/machinery/vending/cigarette, "AutoDrobe" = /obj/machinery/vending/autodrobe, @@ -334,14 +335,37 @@ to destroy them and players will be able to make replacements. /obj/item/stack/cable_coil = 1, /obj/item/weapon/stock_parts/console_screen = 1) +/obj/item/weapon/circuitboard/plantgenes + name = "Plant DNA Manipulator (Machine Board)" + build_path = /obj/machinery/plantgenes + board_type = "machine" + origin_tech = "programming=3;biotech=3" + frame_desc = "Requires 1 Manipulator, 1 Micro Laser, 1 Console Screen, and 1 Scanning Module." + req_components = list( + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/micro_laser = 1, + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/weapon/stock_parts/scanning_module = 1) + +/obj/item/weapon/circuitboard/seed_extractor + name = "circuit board (Seed Extractor)" + build_path = /obj/machinery/seed_extractor + board_type = "machine" + origin_tech = "programming=1" + frame_desc = "Requires 1 Matter Bin and 1 Manipulator." + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/stock_parts/manipulator = 1) + /obj/item/weapon/circuitboard/hydroponics name = "circuit board (Hydroponics Tray)" - build_path = /obj/machinery/portable_atmospherics/hydroponics + build_path = /obj/machinery/hydroponics/constructable board_type = "machine" origin_tech = "programming=1;biotech=1" - frame_desc = "Requires 2 Matter Bins and 1 Console Screen." + frame_desc = "Requires 2 Matter Bins, 1 Manipulator, and 1 Console Screen." req_components = list( /obj/item/weapon/stock_parts/matter_bin = 2, + /obj/item/weapon/stock_parts/manipulator = 1, /obj/item/weapon/stock_parts/console_screen = 1) /obj/item/weapon/circuitboard/microwave @@ -733,6 +757,17 @@ obj/item/weapon/circuitboard/rdserver /obj/item/stack/cable_coil = 1, /obj/item/weapon/stock_parts/console_screen = 1) +/obj/item/weapon/circuitboard/quantumpad + name = "circuit board (Quantum Pad)" + build_path = /obj/machinery/quantumpad + board_type = "machine" + origin_tech = "programming=3;engineering=3;plasmatech=3;bluespace=4" + frame_desc = "Requires 1 Bluespace Crystal, 1 Capacitor, 1 piece of cable and 1 Manipulator." + req_components = list( + /obj/item/weapon/ore/bluespace_crystal = 1, + /obj/item/weapon/stock_parts/capacitor = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/stack/cable_coil = 1) /obj/item/weapon/circuitboard/sleeper name = "circuit board (Sleeper)" @@ -925,26 +960,6 @@ obj/item/weapon/circuitboard/rdserver /obj/item/weapon/stock_parts/console_screen = 1, /obj/item/stack/cable_coil = 1) -/obj/item/weapon/circuitboard/botany_extractor - name = "circuit board (Lysis-Isolation Centrifuge)" - build_path = /obj/machinery/botany/extractor - board_type = "machine" - origin_tech = "biotech=3;programming=3" - req_components = list( - /obj/item/weapon/stock_parts/matter_bin = 1, - /obj/item/weapon/stock_parts/scanning_module = 1, - /obj/item/weapon/stock_parts/console_screen = 1) - -/obj/item/weapon/circuitboard/botany_editor - name = "circuit board (Bioballistic Delivery System)" - build_path = /obj/machinery/botany/editor - board_type = "machine" - origin_tech = "biotech=3;programming=3" - req_components = list( - /obj/item/weapon/stock_parts/matter_bin = 1, - /obj/item/weapon/stock_parts/manipulator = 1, - /obj/item/weapon/stock_parts/console_screen = 1) - /obj/item/weapon/circuitboard/gameboard name = "circuit board (Virtual Gameboard)" build_path = /obj/machinery/gameboard diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 0b078a74ec8..de5d69c2bbc 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -451,6 +451,12 @@ add_fingerprint(usr) return +/obj/machinery/atmospherics/unary/cryo_cell/narsie_act() + go_out() + new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH! + color = "red"//force the icon to red + light_color = LIGHT_COLOR_RED + /obj/machinery/atmospherics/unary/cryo_cell/verb/move_inside() set name = "Move Inside" set category = "Object" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index e48a5f44b32..807d3caf261 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -290,6 +290,11 @@ continue O.loc = src + for(var/obj/machinery/computer/cloning/cloner in machines) + for(var/datum/dna2/record/R in cloner.records) + if(occupant.mind == locate(R.mind)) + cloner.records.Remove(R) + //Delete all items not on the preservation list. var/list/items = src.contents items -= occupant // Don't delete the occupant @@ -705,6 +710,7 @@ for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags O.loc = R qdel(I) + R.module.remove_subsystems_and_actions(R) qdel(R.module) return ..() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 5f751556d0d..114bada5e19 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -476,7 +476,7 @@ About the new airlock wires panel: else if(duration) //electrify door for the given duration seconds if(usr) shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + usr.create_attack_log("Electrified the [name] at [x] [y] [z]") else shockedby += text("\[[time_stamp()]\] - EMP)") message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." @@ -736,7 +736,7 @@ About the new airlock wires panel: electrify(0) else if(activate) //electrify door for 30 seconds shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + usr.create_attack_log("Electrified the [name] at [x] [y] [z]") to_chat(usr, "The door is now electrified for thirty seconds.") electrify(30) if("electrify_permanently") @@ -747,7 +747,7 @@ About the new airlock wires panel: electrify(0) else if(activate) shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + usr.create_attack_log("Electrified the [name] at [x] [y] [z]") to_chat(usr, "The door is now electrified.") electrify(-1) if("open") diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 09f4885dc07..ca4dddd92b0 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -1,9 +1,15 @@ +#define CONSTRUCTION_COMPLETE 0 //No construction done - functioning as normal +#define CONSTRUCTION_PANEL_OPEN 1 //Maintenance panel is open, still functioning +#define CONSTRUCTION_WIRES_EXPOSED 2 //Cover plate is removed, wires are available +#define CONSTRUCTION_GUTTED 3 //Wires are removed, circuit ready to remove +#define CONSTRUCTION_NOCIRCUIT 4 //Circuit board removed, can safely weld apart + /var/const/OPEN = 1 /var/const/CLOSED = 2 /obj/machinery/door/firedoor - name = "Firelock" - desc = "Apply crowbar" + name = "firelock" + desc = "Apply crowbar." icon = 'icons/obj/doors/Doorfireglass.dmi' icon_state = "door_open" opacity = 0 @@ -11,47 +17,21 @@ heat_proof = 1 glass = 1 power_channel = ENVIRON - - var/list/areas_added - - var/blocked = 0 - var/nextstate = null - - var/logged_users closed_layer = 3.11 -/obj/machinery/door/firedoor/New() - . = ..() - for(var/obj/machinery/door/firedoor/F in loc) - if(F != src) - spawn(1) - qdel(src) - return . - - var/area/A = get_area(src) - ASSERT(istype(A)) - - A.all_doors.Add(src) - areas_added = list(A) - - for(var/direction in cardinal) - A = get_area(get_step(src,direction)) - if(istype(A) && !(A in areas_added)) - A.all_doors.Add(src) - areas_added += A - - -/obj/machinery/door/firedoor/Destroy() - for(var/area/A in areas_added) - A.all_doors.Remove(src) - . = ..() + var/assembly_type = /obj/structure/firelock_frame + var/nextstate = null + var/welded = 0 + var/boltslocked = 1 + var/can_deconstruct = 1 /obj/machinery/door/firedoor/Bumped(atom/AM) - if(p_open || operating) return - if(!density) return ..() + if(p_open || operating) + return + if(!density) + return ..() return 0 - /obj/machinery/door/firedoor/power_change() if(powered(power_channel)) stat &= ~NOPOWER @@ -60,154 +40,74 @@ stat |= NOPOWER return -/obj/machinery/door/firedoor/attack_hand(mob/user as mob) - return attackby(null, user) - /obj/machinery/door/firedoor/attackby(obj/item/weapon/C as obj, mob/user as mob, params) add_fingerprint(user) + if(operating) - return//Already doing something. + return if(istype(C, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/W = C if(W.remove_fuel(0, user)) - blocked = !blocked - user.visible_message("\red \The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].",\ - "You [blocked ? "weld" : "unweld"] \the [src] with \the [W].",\ - "You hear something being welded.") + welded = !welded + to_chat(user, "You [welded ? "welded" : "unwelded"] \the [src]") update_icon() return - if(blocked) - to_chat(user, "\red \The [src] is welded solid!") - return - - var/area/A = get_area_master(src) - ASSERT(istype(A)) // This worries me. - var/alarmed = A.air_doors_activated || A.fire - - if( istype(C, /obj/item/weapon/crowbar) || ( istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1 ) ) - if(operating) + if(welded) + if(istype(C, /obj/item/weapon/wrench)) + if(boltslocked) + to_chat(user, "There are screws locking the bolts in place!") + return + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message("[user] starts undoing [src]'s bolts...", \ + "You start unfastening [src]'s floor bolts...") + if(!do_after(user, 50, target = src)) + return + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + user.visible_message("[user] unfastens [src]'s bolts.", \ + "You undo [src]'s floor bolts.") + deconstruct(TRUE) + return + else if(istype(C, /obj/item/weapon/screwdriver)) + user.visible_message("[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts...", \ + "You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts...") + playsound(get_turf(src), 'sound/items/Screwdriver.ogg', 50, 1) + boltslocked = !boltslocked + return + else + to_chat(user, "\The [src] is welded solid!") return - if(blocked) - user.visible_message("\red \The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!",\ - "You try to pry \the [src] [density ? "open" : "closed"], but it is welded in place!",\ - "You hear someone struggle and metal straining.") - if(stat & (BROKEN|NOPOWER) || !density || !alarmed) - user.visible_message("\red \The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!",\ - "You force \the [src] [density ? "open" : "closed"] with \the [C]!",\ - "You hear metal strain, and a door [density ? "open" : "close"].") - - else if(allowed(user)) - user.visible_message("\blue \The [user] lifts \the [src] with \a [C].",\ - "\The [src] scans your ID, and obediently opens as you apply your [C].",\ - "You hear metal move, and a door [density ? "open" : "close"].") + if(istype(C, /obj/item/weapon/crowbar) || istype(C, /obj/item/weapon/twohanded/fireaxe)) + if(istype(C, /obj/item/weapon/twohanded/fireaxe)) + var/obj/item/weapon/twohanded/fireaxe/F = C + if(!F.wielded) + return if(density) - spawn(0) - open() - else - spawn(0) - close() - return - - var/access_granted = 0 - var/users_name - if(!istype(C, /obj)) //If someone hit it with their hand. We need to see if they are allowed. - if(allowed(user)) - access_granted = 1 - if(ishuman(user)) - users_name = FindNameFromID(user) - else - users_name = "Unknown" - - if(ishuman(user) && !stat && (istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda))) - var/obj/item/weapon/card/id/ID = C - - if( istype(C, /obj/item/device/pda) ) - var/obj/item/device/pda/pda = C - ID = pda.id - if(!istype(ID)) - ID = null - - if(ID) - users_name = ID.registered_name - - if(check_access(ID)) - access_granted = 1 - - var/answer = alert(user, "Are you sure you want to [density ? "open" : "close"] \the [src]?","\The [src] confirmation","Yes","No") - if(answer == "No") - return - - if(user.stat || user.stunned || user.weakened || user.paralysis || get_dist(src, user) > 1) - to_chat(user, "Sorry, you must remain able bodied and close to \the [src] in order to use it.") - return - - if(alarmed && density && !access_granted) - to_chat(user, "Access denied. Please wait for authorities to arrive, or for the alert to clear.") - return - - else - user.visible_message("\blue \The [src] [density ? "open" : "close"]s for \the [user].",\ - "\The [src] [density ? "open" : "close"]s.",\ - "You hear a beep, and a door opening.") - // Accountability! - if(!logged_users) - logged_users = list() - logged_users += users_name - - var/needs_to_close = 0 - if(density) - if(alarmed) - needs_to_close = 1 - spawn() open() - else - spawn() + else close() - if(needs_to_close) - spawn(50) - if(alarmed) - nextstate = CLOSED - -/obj/machinery/door/firedoor/attack_ai(mob/user as mob) - if(operating || stat & NOPOWER) - return //Already doing something or depowered. - - if(blocked) - to_chat(user, "\red \The [src] is welded solid!") +/obj/machinery/door/firedoor/attack_hand(mob/user) + add_fingerprint(user) + if(welded || operating || stat & NOPOWER) return - - var/area/A = get_area_master(src) - ASSERT(istype(A)) // This worries me. - var/alarmed = A.air_doors_activated || A.fire - - var/access_granted = 0 - if(isAI(user) || isrobot(user)) - access_granted = 1 - - if(access_granted == 1) - user.visible_message("\blue \The [src] [density ? "open" : "close"]s for \the [user].",\ - "\The [src] [density ? "open" : "close"]s.",\ - "You hear a beep, and a door opening.") - - var/needs_to_close = 0 if(density) - if(alarmed) - needs_to_close = 1 - spawn() - open() + open() else - spawn() - close() + close() + +/obj/machinery/door/firedoor/attack_ai(mob/user) + attack_hand(user) - if(needs_to_close) - spawn(50) - if(alarmed) - nextstate = CLOSED +/obj/machinery/door/firedoor/attack_alien(mob/user) + add_fingerprint(user) + if(welded) + to_chat(user, "[src] refuses to budge!") + return + open() /obj/machinery/door/firedoor/do_animate(animation) switch(animation) @@ -215,32 +115,25 @@ flick("door_opening", src) if("closing") flick("door_closing", src) - return /obj/machinery/door/firedoor/update_icon() overlays.Cut() if(density) icon_state = "door_closed" - if(blocked) + if(welded) overlays += "welded" else icon_state = "door_open" - if(blocked) + if(welded) overlays += "welded_open" - return /obj/machinery/door/firedoor/open() - ..() + . = ..() latetoggle() - return /obj/machinery/door/firedoor/close() - ..() - if(locate(/mob/living) in get_turf(src)) - open() - return + . = ..() latetoggle() - return /obj/machinery/door/firedoor/proc/latetoggle() if(operating || stat & NOPOWER || !nextstate) @@ -252,23 +145,30 @@ if(CLOSED) nextstate = null close() - return - - -/obj/machinery/door/firedoor/border_only + +/obj/machinery/door/firedoor/proc/deconstruct(disassembled = TRUE) + if(can_deconstruct) + var/obj/structure/firelock_frame/F = new assembly_type(get_turf(src)) + if(disassembled) + F.constructionStep = CONSTRUCTION_PANEL_OPEN + else + F.constructionStep = CONSTRUCTION_WIRES_EXPOSED + F.update_icon() + qdel(src) + +/obj/machinery/door/firedoor/border_only icon = 'icons/obj/doors/edge_Doorfire.dmi' flags = ON_BORDER -/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) +/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target, height=0) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - if(air_group) return 0 return !density else return 1 -/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target as turf) +/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target) if(istype(mover) && mover.checkpass(PASSGLASS)) return 1 if(get_dir(loc, target) == dir) @@ -276,8 +176,222 @@ else return 1 -/obj/machinery/door/firedoor/border_only/CanAtmosPass(var/turf/T) +/obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T) if(get_dir(loc, T) == dir) return !density else - return 1 \ No newline at end of file + return 1 + +/obj/machinery/door/firedoor/heavy + name = "heavy firelock" + icon = 'icons/obj/doors/Doorfire.dmi' + glass = 0 + opacity = 1 + assembly_type = /obj/structure/firelock_frame/heavy + +/obj/machinery/door/firedoor/heavy/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + +/obj/item/weapon/firelock_electronics + name = "firelock electronics" + icon = 'icons/obj/doors/door_assembly.dmi' + icon_state = "door_electronics" + desc = "A circuit board used in construction of firelocks." + w_class = 2 + materials = list(MAT_METAL=50, MAT_GLASS=50) + +/obj/structure/firelock_frame + name = "firelock frame" + desc = "A partially completed firelock." + icon = 'icons/obj/doors/Doorfire.dmi' + icon_state = "frame1" + anchored = 0 + density = 1 + var/constructionStep = CONSTRUCTION_NOCIRCUIT + var/reinforced = 0 + +/obj/structure/firelock_frame/heavy + name = "heavy firelock frame" + reinforced = 1 + +/obj/structure/firelock_frame/examine(mob/user) + ..() + switch(constructionStep) + if(CONSTRUCTION_PANEL_OPEN) + to_chat(user, "There is a small metal plate covering the wires.") + if(CONSTRUCTION_WIRES_EXPOSED) + to_chat(user, "Wires are trailing from the maintenance panel.") + if(CONSTRUCTION_GUTTED) + to_chat(user, "The circuit board is visible.") + if(CONSTRUCTION_NOCIRCUIT) + to_chat(user, "There are no electronics in the frame.") + if(reinforced) + to_chat(user, "The frame is reinforced.") + +/obj/structure/firelock_frame/update_icon() + ..() + icon_state = "frame[constructionStep]" + +/obj/structure/firelock_frame/attackby(obj/item/weapon/C, mob/user) + switch(constructionStep) + if(CONSTRUCTION_PANEL_OPEN) + if(istype(C, /obj/item/weapon/crowbar)) + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) + user.visible_message("[user] starts prying something out from [src]...", \ + "You begin prying out the wire cover...") + if(!do_after(user, 50, target = src)) + return + if(constructionStep != CONSTRUCTION_PANEL_OPEN) + return + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + user.visible_message("[user] pries out a metal plate from [src], exposing the wires.", \ + "You remove the cover plate from [src], exposing the wires.") + constructionStep = CONSTRUCTION_WIRES_EXPOSED + update_icon() + return + if(istype(C, /obj/item/weapon/wrench)) + if(locate(/obj/machinery/door/firedoor) in get_turf(src)) + to_chat(user, "There's already a firelock there.") + return + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 50, 1) + user.visible_message("[user] starts bolting down [src]...", \ + "You begin bolting [src]...") + if(!do_after(user, 30, target = src)) + return + if(locate(/obj/machinery/door/firedoor) in get_turf(src)) + return + user.visible_message("[user] finishes the firelock.", \ + "You finish the firelock.") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(reinforced) + new /obj/machinery/door/firedoor/heavy(get_turf(src)) + else + new /obj/machinery/door/firedoor(get_turf(src)) + qdel(src) + return + if(istype(C, /obj/item/stack/sheet/plasteel)) + var/obj/item/stack/sheet/plasteel/P = C + if(reinforced) + to_chat(user, "[src] is already reinforced.") + return + if(P.get_amount() < 2) + to_chat(user, "You need more plasteel to reinforce [src].") + return + user.visible_message("[user] begins reinforcing [src]...", \ + "You begin reinforcing [src]...") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 60, target = src)) + if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P) + return + user.visible_message("[user] reinforces [src].", \ + "You reinforce [src].") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + P.use(2) + reinforced = 1 + return + + if(CONSTRUCTION_WIRES_EXPOSED) + if(istype(C, /obj/item/weapon/wirecutters)) + playsound(get_turf(src), 'sound/items/Wirecutter.ogg', 50, 1) + user.visible_message("[user] starts cutting the wires from [src]...", \ + "You begin removing [src]'s wires...") + if(!do_after(user, 60, target = src)) + return + if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) + return + user.visible_message("[user] removes the wires from [src].", \ + "You remove the wiring from [src], exposing the circuit board.") + var/obj/item/stack/cable_coil/B = new(get_turf(src)) + B.amount = 5 + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return + if(istype(C, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(1, user)) + playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1) + user.visible_message("[user] starts welding a metal plate into [src]...", \ + "You begin welding the cover plate back onto [src]...") + if(!do_after(user, 80, target = src)) + return + if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) + return + playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1) + user.visible_message("[user] welds the metal plate into [src].", \ + "You weld [src]'s cover plate into place, hiding the wires.") + constructionStep = CONSTRUCTION_PANEL_OPEN + update_icon() + return + if(CONSTRUCTION_GUTTED) + if(istype(C, /obj/item/weapon/crowbar)) + user.visible_message("[user] begins removing the circuit board from [src]...", \ + "You begin prying out the circuit board from [src]...") + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) + if(!do_after(user, 50, target = src)) + return + if(constructionStep != CONSTRUCTION_GUTTED) + return + user.visible_message("[user] removes [src]'s circuit board.", \ + "You remove the circuit board from [src].") + new /obj/item/weapon/firelock_electronics(get_turf(src)) + playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1) + constructionStep = CONSTRUCTION_NOCIRCUIT + update_icon() + return + if(istype(C, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/B = C + if(B.get_amount() < 5) + to_chat(user, "You need more wires to add wiring to [src].") + return + user.visible_message("[user] begins wiring [src]...", \ + "You begin adding wires to [src]...") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 60, target = src)) + if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B) + return + user.visible_message("[user] adds wires to [src].", \ + "You wire [src].") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + B.use(5) + constructionStep = CONSTRUCTION_WIRES_EXPOSED + update_icon() + return + if(CONSTRUCTION_NOCIRCUIT) + if(istype(C, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/W = C + if(W.remove_fuel(1,user)) + playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1) + user.visible_message("[user] begins cutting apart [src]'s frame...", \ + "You begin slicing [src] apart...") + if(!do_after(user, 80, target = src)) + return + if(constructionStep != CONSTRUCTION_NOCIRCUIT) + return + user.visible_message("[user] cuts apart [src]!", \ + "You cut [src] into metal.") + playsound(get_turf(src), 'sound/items/Welder2.ogg', 50, 1) + var/turf/T = get_turf(src) + new /obj/item/stack/sheet/metal(T, 3) + if(reinforced) + new /obj/item/stack/sheet/plasteel(T, 2) + qdel(src) + return + if(istype(C, /obj/item/weapon/firelock_electronics)) + user.visible_message("[user] starts adding [C] to [src]...", \ + "You begin adding a circuit board to [src]...") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + if(!do_after(user, 40, target = src)) + return + if(constructionStep != CONSTRUCTION_NOCIRCUIT) + return + user.drop_item() + qdel(C) + user.visible_message("[user] adds a circuit to [src].", \ + "You insert and secure [C].") + playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return + return ..() \ No newline at end of file diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 41952adf355..aa345e29643 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -28,6 +28,7 @@ Possible to do for anyone motivated enough: // 0 = RANGE BASED // 1 = AREA BASED var/const/HOLOPAD_MODE = 0 +var/list/holopads = list() /obj/machinery/hologram/holopad name = "\improper AI holopad" @@ -42,6 +43,7 @@ var/const/HOLOPAD_MODE = 0 /obj/machinery/hologram/holopad/New() ..() + holopads += src component_parts = list() component_parts += new /obj/item/weapon/circuitboard/holopad(null) component_parts += new /obj/item/weapon/stock_parts/capacitor(null) @@ -89,13 +91,15 @@ var/const/HOLOPAD_MODE = 0 if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. user.eyeobj.setLoc(get_turf(src)) else if(!hologram)//If there is no hologram, possibly make one. - activate_holo(user) + activate_holo(user, 0) else if(master == user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing. clear_holo() return -/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user) - if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it. +/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user, var/force = 0) + if(!force && user.eyeobj.loc != src.loc) // allows holopads to pass off holograms to the next holopad in the chain + to_chat(user, "ERROR: Unable to project hologram.") + else if(!(stat & NOPOWER))//If the projector has power if(user.holo) var/obj/machinery/hologram/holopad/current = user.holo current.clear_holo() @@ -163,7 +167,17 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(eye_area != holo_area) return 1 + var/mob/living/silicon/ai/theai = master + var/turf/target_turf = get_turf(master.eyeobj) + var/newdir = hologram.dir clear_holo()//If not, we want to get rid of the hologram. + var/obj/machinery/hologram/holopad/pad_close = get_closest_atom(/obj/machinery/hologram/holopad, holopads, theai.eyeobj) + if(get_dist(pad_close, theai.eyeobj) <= pad_close.holo_range) + if(!(pad_close.stat & NOPOWER) && !pad_close.hologram) + pad_close.activate_holo(theai, 1) + if(pad_close.hologram) + pad_close.hologram.forceMove(target_turf) + pad_close.hologram.dir = newdir return 1 /obj/machinery/hologram/holopad/proc/move_hologram() @@ -221,6 +235,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ return /obj/machinery/hologram/holopad/Destroy() + holopads -= src if(hologram) clear_holo() return ..() diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index b886bc3ff71..9e4e8d5745c 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -7,6 +7,8 @@ var/mob/living/carbon/human/attached = null var/mode = 1 // 1 is injecting, 0 is taking blood. var/obj/item/weapon/reagent_containers/beaker = null + var/transfer_amount = 5 + var/possible_transfer_amounts = list(1,5,10) /obj/machinery/iv_drip/New() ..() @@ -115,10 +117,6 @@ // Give blood if(mode) if(beaker.volume > 0) - var/transfer_amount = 5 - if(istype(beaker, /obj/item/weapon/reagent_containers/blood)) - // speed up transfer on blood packs - transfer_amount = 10 var/fraction = min(transfer_amount/beaker.volume, 1) //the fraction that is transfered of the total volume beaker.reagents.reaction(attached, INGEST, fraction) //make reagents reacts, but don't spam messages beaker.reagents.trans_to(attached, transfer_amount) @@ -238,3 +236,15 @@ to_chat(user, "No chemicals are attached.") to_chat(user, "[attached ? attached : "No one"] is attached.") + +/obj/machinery/iv_drip/verb/set_transfer_rate() + set name = "Set transfer amount" + set category = "Object" + set src in view(1) + + if(usr.incapacitated()) + return + var/default = 5 + var/N = input("Amount per transfer from this:", "[src]", default) as null|anything in possible_transfer_amounts + if(N) + transfer_amount = N \ No newline at end of file diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 60ce5e32a34..e62e54a3a78 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -132,6 +132,22 @@ Class Procs: else fast_processing += src +// gotta go fast +/obj/machinery/proc/makeSpeedProcess() + if(speed_process) + return + speed_process = 1 + machine_processing -= src + fast_processing += src + +// gotta go slow +/obj/machinery/proc/makeNormalProcess() + if(!speed_process) + return + speed_process = 0 + machine_processing += src + fast_processing -= src + /obj/machinery/New() //new machines += src ..() @@ -380,9 +396,7 @@ Class Procs: /obj/machinery/proc/default_deconstruction_crowbar(var/obj/item/weapon/crowbar/C, var/ignore_panel = 0) if(istype(C) && (panel_open || ignore_panel)) playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc) - M.state = 2 - M.icon_state = "box_1" + spawn_frame() for(var/obj/item/I in component_parts) if(I.reliability != 100 && crit_fail) I.crit_fail = 1 @@ -391,6 +405,12 @@ Class Procs: return 1 return 0 + +/obj/machinery/proc/spawn_frame() + var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(loc) + M.state = 2 + M.icon_state = "box_1" + /obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/icon_state_open, var/icon_state_closed, var/obj/item/weapon/screwdriver/S) if(istype(S)) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index db60adb5c9a..f9f1f40264d 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -103,13 +103,12 @@ if(drownee.losebreath > 20) //You've probably got bigger problems than drowning at this point, so we won't add to it until you get that under control. return + add_logs(src, drownee, "drowned", null, null, 0) //log it to their VV, but don't spam the admins' chats with the logs if(drownee.stat) //Mob is in critical. drownee.AdjustLoseBreath(3, bound_lower = 0, bound_upper = 20) - add_logs(src, drownee, "drowned", null, null, 0) //log it to their VV, but don't spam the admins' chats with the logs drownee.visible_message("\The [drownee] appears to be drowning!","You're quickly drowning!") //inform them that they are fucked. else drownee.AdjustLoseBreath(2, bound_lower = 0, bound_upper = 20) //For every time you drown, you miss 2 breath attempts. Hope you catch on quick! - add_logs(src, drownee, "drowned", null, null, 0) //log it to their VV, but don't spam the admins' chats with the logs if(prob(35)) //35% chance to tell them what is going on. They should probably figure it out before then. drownee.visible_message("\The [drownee] flails, almost like they are drowning!","You're lacking air!") //*gasp* *gasp* *gasp* *gasp* *gasp* diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 17fe32f39ec..28b3cfe7132 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -20,7 +20,7 @@ var/health = 80 //the turret's health var/locked = 1 //if the turret's behaviour control access is locked var/controllock = 0 //if the turret responds to control panels - + var/installation = /obj/item/weapon/gun/energy/gun/turret //the type of weapon installed var/gun_charge = 0 //the charge of the gun inserted var/projectile = null //holder for bullettype @@ -56,6 +56,13 @@ var/screen = 0 // Screen 0: main control, screen 1: access levels var/one_access = 0 // Determines if access control is set to req_one_access or req_access + + var/syndicate = 0 //is the turret a syndicate turret? + var/faction = "" + var/emp_vulnerable = 1 // Can be empd + var/scan_range = 7 + var/always_up = 0 //Will stay active + var/has_cover = 1 //Hides the cover /obj/machinery/porta_turret/centcom enabled = 0 @@ -99,7 +106,7 @@ one_access = 0 /obj/machinery/porta_turret/proc/setup() - var/obj/item/weapon/gun/energy/E= new installation //All energy-based weapons are applicable + var/obj/item/weapon/gun/energy/E = new installation //All energy-based weapons are applicable var/obj/item/ammo_casing/shottype = E.ammo_type[1] projectile = shottype.projectile_type @@ -206,10 +213,10 @@ var/list/turret_icons data["screen"] = screen data["locked"] = locked data["enabled"] = enabled - data["is_lethal"] = 1 + data["lethal_control"] = !syndicate ? 1 : 0 data["lethal"] = lethal - if(data["access"]) + if(data["access"] && !syndicate) var/settings[0] settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) @@ -219,18 +226,19 @@ var/list/turret_icons settings[++settings.len] = list("category" = "Check Misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) data["settings"] = settings - data["one_access"] = one_access - var/accesses[0] - var/list/access_list = get_all_accesses() - for(var/access in access_list) - var/name = get_access_desc(access) - var/active - if(one_access) - active = (access in req_one_access) - else - active = (access in req_access) - accesses[++accesses.len] = list("name" = name, "active" = active, "number" = access) - data["accesses"] = accesses + if(!syndicate) + data["one_access"] = one_access + var/accesses[0] + var/list/access_list = get_all_accesses() + for(var/access in access_list) + var/name = get_access_desc(access) + var/active + if(one_access) + active = (access in req_one_access) + else + active = (access in req_access) + accesses[++accesses.len] = list("name" = name, "active" = active, "number" = access) + data["accesses"] = accesses return data /obj/machinery/porta_turret/proc/HasController() @@ -259,6 +267,8 @@ var/list/turret_icons var/value = text2num(href_list["value"]) if(href_list["command"] == "enable") enabled = value + else if(syndicate) + return 1 else if(href_list["command"] == "screen") screen = value else if(href_list["command"] == "lethal") @@ -276,11 +286,12 @@ var/list/turret_icons else if(href_list["command"] == "check_anomalies") check_anomalies = value - if(href_list["one_access"]) - toggle_one_access(href_list["one_access"]) + if(!syndicate) + if(href_list["one_access"]) + toggle_one_access(href_list["one_access"]) - if(href_list["access"]) - toggle_access(href_list["access"]) + if(href_list["access"]) + toggle_access(href_list["access"]) return 1 @@ -311,7 +322,7 @@ var/list/turret_icons req_access += required /obj/machinery/porta_turret/power_change() - if(powered()) + if(powered() || !use_power) stat &= ~NOPOWER update_icon() else @@ -321,7 +332,7 @@ var/list/turret_icons /obj/machinery/porta_turret/attackby(obj/item/I, mob/user) - if(stat & BROKEN) + if((stat & BROKEN) && !syndicate) if(istype(I, /obj/item/weapon/crowbar)) //If the turret is destroyed, you can remove it with a crowbar to //try and salvage its components @@ -438,13 +449,12 @@ var/list/turret_icons return health -= force - if(force > 5 && prob(45)) + if(force > 5 && prob(45) && spark_system) spark_system.start() if(health <= 0) die() //the death process :( /obj/machinery/porta_turret/bullet_act(obj/item/projectile/Proj) - if(Proj.damage_type == STAMINA) return @@ -461,7 +471,7 @@ var/list/turret_icons take_damage(Proj.damage) /obj/machinery/porta_turret/emp_act(severity) - if(enabled) + if(enabled && emp_vulnerable) //if the turret is on, the EMP no matter how severe disables the turret for a while //and scrambles its settings, with a slight chance of having an emag effect check_arrest = prob(50) @@ -494,7 +504,8 @@ var/list/turret_icons /obj/machinery/porta_turret/proc/die() //called when the turret dies, ie, health <= 0 health = 0 stat |= BROKEN //enables the BROKEN bit - spark_system.start() //creates some sparks because they look cool + if(spark_system) + spark_system.start() //creates some sparks because they look cool update_icon() /obj/machinery/porta_turret/process() @@ -503,35 +514,43 @@ var/list/turret_icons set background = BACKGROUND_ENABLED if(stat & (NOPOWER|BROKEN)) - //if the turret has no power or is broken, make the turret pop down if it hasn't already - popDown() + if(!always_up) + //if the turret has no power or is broken, make the turret pop down if it hasn't already + popDown() return if(!enabled) - //if the turret is off, make it pop down - popDown() + if(!always_up) + //if the turret is off, make it pop down + popDown() return var/list/targets = list() //list of primary targets var/list/secondarytargets = list() //targets that are least important - for(var/obj/mecha/ME in view(7,src)) + for(var/obj/mecha/ME in view(scan_range,src)) assess_and_assign(ME.occupant, targets, secondarytargets) - for(var/obj/spacepod/SP in view(7,src)) + for(var/obj/spacepod/SP in view(scan_range,src)) assess_and_assign(SP.pilot, targets, secondarytargets) - for(var/obj/vehicle/T in view(7,src)) + for(var/obj/vehicle/T in view(scan_range,src)) assess_and_assign(T.buckled_mob, targets, secondarytargets) - for(var/mob/living/C in view(7,src)) //loops through all living lifeforms in view + for(var/mob/living/C in view(scan_range,src)) //loops through all living lifeforms in view assess_and_assign(C, targets, secondarytargets) if(!tryToShootAt(targets)) if(!tryToShootAt(secondarytargets)) // if no valid targets, go for secondary targets - spawn() - popDown() // no valid targets, close the cover + if(!always_up) + spawn() + popDown() // no valid targets, close the cover +/obj/machinery/porta_turret/proc/in_faction(mob/living/target) + if(!(faction in target.faction)) + return 0 + return 1 + /obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets) switch(assess_living(L)) if(TURRET_PRIORITY_TARGET) @@ -552,17 +571,20 @@ var/list/turret_icons if(!L) return TURRET_NOT_TARGET - if(!emagged && (issilicon(L) || isbot(L))) // Don't target silica + if(!emagged && !syndicate && (issilicon(L) || isbot(L))) // Don't target silica return TURRET_NOT_TARGET if(L.stat && !emagged) //if the perp is dead/dying, no need to bother really return TURRET_NOT_TARGET //move onto next potential victim! - if(get_dist(src, L) > 7) //if it's too far away, why bother? + if(get_dist(src, L) > scan_range) //if it's too far away, why bother? return TURRET_NOT_TARGET if(emagged) // If emagged not even the dead get a rest return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET + + if(in_faction(L)) + return TURRET_NOT_TARGET if(lethal && locate(/mob/living/silicon/ai) in get_turf(L)) //don't accidentally kill the AI! return TURRET_NOT_TARGET @@ -648,18 +670,19 @@ var/list/turret_icons return ..() -/obj/machinery/porta_turret/proc/set_raised_raising(var/raised, var/raising) - src.raised = raised - src.raising = raising - density = raised || raising +/obj/machinery/porta_turret/proc/set_raised_raising(var/is_raised, var/is_raising) + raised = is_raised + raising = is_raising + density = is_raised || is_raising /obj/machinery/porta_turret/proc/target(var/mob/living/target) if(disabled) return if(target) last_target = target - spawn() - popUp() //pop the turret up if it's not already up. + if(has_cover) + spawn() + popUp() //pop the turret up if it's not already up. dir = get_dir(src, target) //even if you can't shoot, follow the target spawn() shootAt(target) @@ -667,7 +690,7 @@ var/list/turret_icons return /obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) - if(!raised) //the turret has to be raised in order to fire - makes sense, right? + if(!raised && has_cover) //the turret has to be raised in order to fire - makes sense, right? return //any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power! if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate @@ -719,9 +742,9 @@ var/list/turret_icons /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) if(controllock) return - src.enabled = TC.enabled - src.lethal = TC.lethal - src.iconholder = TC.lethal + enabled = TC.enabled + lethal = TC.lethal + iconholder = TC.lethal check_synth = TC.check_synth check_access = TC.check_access @@ -731,7 +754,7 @@ var/list/turret_icons check_anomalies = TC.check_anomalies ailock = TC.ailock - src.power_change() + power_change() /* Portable turret constructions @@ -944,3 +967,87 @@ var/list/turret_icons /atom/movable/porta_turret_cover icon = 'icons/obj/turrets.dmi' + +// Syndicate turrets +/obj/machinery/porta_turret/syndicate + projectile = /obj/item/projectile/bullet + eprojectile = /obj/item/projectile/bullet + shot_sound = 'sound/weapons/Gunshot.ogg' + eshot_sound = 'sound/weapons/Gunshot.ogg' + + icon_state = "syndieturret0" + var/icon_state_initial = "syndieturret0" + var/icon_state_active = "syndieturret1" + var/icon_state_destroyed = "syndieturret2" + + syndicate = 1 + installation = null + always_up = 1 + use_power = 0 + has_cover = 0 + raised = 1 + scan_range = 9 + + faction = "syndicate" + emp_vulnerable = 0 + + lethal = 1 + check_arrest = 0 + check_records = 0 + check_weapons = 0 + check_access = 0 + check_anomalies = 1 + check_synth = 1 + ailock = 1 + +/obj/machinery/porta_turret/syndicate/New() + ..() + if(req_one_access && req_one_access.len) + req_one_access.Cut() + req_access = list(access_syndicate) + one_access = 0 + +/obj/machinery/porta_turret/syndicate/update_icon() + if(stat & BROKEN) + icon_state = icon_state_destroyed + else if(enabled) + icon_state = icon_state_active + else + icon_state = icon_state_initial + +/obj/machinery/porta_turret/syndicate/setup() + return + +/obj/machinery/porta_turret/syndicate/assess_perp(mob/living/carbon/human/perp) + return 10 //Syndicate turrets shoot everything not in their faction + +/obj/machinery/porta_turret/syndicate/pod + health = 40 + projectile = /obj/item/projectile/bullet/weakbullet3 + eprojectile = /obj/item/projectile/bullet/weakbullet3 + +/obj/machinery/porta_turret/syndicate/interior + name = "machine gun turret (.45)" + desc = "Syndicate interior defense turret chambered for .45 rounds. Designed to down intruders without damaging the hull." + projectile = /obj/item/projectile/bullet/midbullet + eprojectile = /obj/item/projectile/bullet/midbullet + +/obj/machinery/porta_turret/syndicate/exterior + name = "machine gun turret (7.62)" + desc = "Syndicate exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets." + projectile = /obj/item/projectile/bullet + eprojectile = /obj/item/projectile/bullet/midbullet + +/obj/machinery/porta_turret/syndicate/grenade + name = "mounted grenade launcher (40mm)" + desc = "Syndicate 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead." + projectile = /obj/item/projectile/bullet/a40mm + eprojectile = /obj/item/projectile/bullet/midbullet + +/obj/machinery/porta_turret/syndicate/assault_pod + name = "machine gun turret (4.6x30mm)" + desc = "Syndicate exterior defense turret chambered for 4.6x30mm rounds. Designed to be fitted to assault pods, it uses low calliber bullets to save space." + health = 100 + projectile = /obj/item/projectile/bullet/weakbullet3 + eprojectile = /obj/item/projectile/bullet/midbullet + diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm new file mode 100644 index 00000000000..809d0a9b09a --- /dev/null +++ b/code/game/machinery/quantum_pad.dm @@ -0,0 +1,148 @@ +/obj/machinery/quantumpad + name = "quantum pad" + desc = "A bluespace quantum-linked telepad used for teleporting objects to other quantum pads." + icon = 'icons/obj/telescience.dmi' + icon_state = "qpad-idle" + anchored = 1 + use_power = 1 + idle_power_usage = 200 + active_power_usage = 5000 + var/teleport_cooldown = 400 //30 seconds base due to base parts + var/teleport_speed = 50 + var/last_teleport //to handle the cooldown + var/teleporting = 0 //if it's in the process of teleporting + var/power_efficiency = 1 + var/obj/machinery/quantumpad/linked_pad = null + +/obj/machinery/quantumpad/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/quantumpad(null) + component_parts += new /obj/item/weapon/ore/bluespace_crystal/artificial(null) + component_parts += new /obj/item/weapon/stock_parts/capacitor(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/stack/cable_coil(null, 1) + RefreshParts() + +/obj/machinery/quantumpad/Destroy() + linked_pad = null + return ..() + +/obj/machinery/quantumpad/RefreshParts() + var/E = 0 + for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) + E += C.rating + power_efficiency = E + E = 0 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + E += M.rating + teleport_speed = initial(teleport_speed) + teleport_speed -= (E*10) + teleport_cooldown = initial(teleport_cooldown) + teleport_cooldown -= (E * 100) + +/obj/machinery/quantumpad/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "pad-idle-o", "qpad-idle", I)) + return + + if(panel_open) + if(ismultitool(I)) + var/obj/item/device/multitool/M = I + M.buffer = src + to_chat(user, "You save the data in the [I.name]'s buffer.") + return 1 + else if(ismultitool(I)) + var/obj/item/device/multitool/M = I + if(istype(M.buffer, /obj/machinery/quantumpad)) + linked_pad = M.buffer + to_chat(user, "You link the [src] to the one in the [I.name]'s buffer.") + return 1 + + if(exchange_parts(user, I)) + return + + if(default_deconstruction_crowbar(I)) + return + + return ..() + +/obj/machinery/quantumpad/attack_hand(mob/user) + if(panel_open) + to_chat(user, "The panel must be closed before operating this machine!") + return + + if(!linked_pad || qdeleted(linked_pad)) + to_chat(user, "There is no linked pad!") + return + + if(world.time < last_teleport + teleport_cooldown) + to_chat(user, "[src] is recharging power. Please wait [round((last_teleport + teleport_cooldown - world.time) / 10)] seconds.") + return + + if(teleporting) + to_chat(user, "[src] is charging up. Please wait.") + return + + if(linked_pad.teleporting) + to_chat(user, "Linked pad is busy. Please wait.") + return + + if(linked_pad.stat & NOPOWER) + to_chat(user, "Linked pad is not responding to ping.") + return + add_fingerprint(user) + doteleport(user) + +/obj/machinery/quantumpad/proc/sparks() + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(5, 1, get_turf(src)) + s.start() + +/obj/machinery/quantumpad/attack_ghost(mob/dead/observer/ghost) + if(linked_pad) + ghost.forceMove(get_turf(linked_pad)) + +/obj/machinery/quantumpad/proc/doteleport(mob/user) + if(linked_pad) + playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1) + teleporting = 1 + + spawn(teleport_speed) + if(!src || qdeleted(src)) + teleporting = 0 + return + if(stat & NOPOWER) + to_chat(user, "[src] is unpowered!") + teleporting = 0 + return + if(!linked_pad || qdeleted(linked_pad) || linked_pad.stat & NOPOWER) + to_chat(user, "Linked pad is not responding to ping. Teleport aborted.") + teleporting = 0 + return + + teleporting = 0 + last_teleport = world.time + + // use a lot of power + use_power(10000 / power_efficiency) + sparks() + linked_pad.sparks() + + flick("qpad-beam", src) + playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) + flick("qpad-beam", linked_pad) + playsound(get_turf(linked_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5) + for(var/atom/movable/ROI in get_turf(src)) + // if is anchored, don't let through + if(ROI.anchored) + if(isliving(ROI)) + var/mob/living/L = ROI + if(L.buckled) + // TP people on office chairs + if(L.buckled.anchored) + continue + else + continue + else if(!isobserver(ROI)) + continue + do_teleport(ROI, get_turf(linked_pad)) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index ac88d755561..343841b639c 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -92,6 +92,12 @@ A.blob_act() qdel(src) +/obj/machinery/recharge_station/narsie_act() + go_out() + new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH! + qdel(src) + + /obj/machinery/recharge_station/attack_animal(var/mob/living/simple_animal/M)//Stop putting hostile mobs in things guise if(M.environment_smash) M.do_attack_animation(src) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 704da886685..476162a27a1 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -8,14 +8,16 @@ //Request Console Screens #define RCS_MAINMENU 0 // Main menu -#define RCS_RQASSIST 1 // Request supplies -#define RCS_RQSUPPLY 2 // Request assistance +#define RCS_RQSUPPLY 1 // Request supplies +#define RCS_RQASSIST 2 // Request assistance #define RCS_SENDINFO 3 // Relay information #define RCS_SENTPASS 4 // Message sent successfully #define RCS_SENTFAIL 5 // Message sent unsuccessfully #define RCS_VIEWMSGS 6 // View messages #define RCS_MESSAUTH 7 // Authentication before sending #define RCS_ANNOUNCE 8 // Send announcement +#define RCS_SHIPPING 9 // Print Shipping Labels/Packages +#define RCS_SHIP_LOG 10 // View Shipping Label Log var/req_console_assistance = list() var/req_console_supplies = list() @@ -52,6 +54,10 @@ var/list/obj/machinery/requests_console/allConsoles = list() var/priority = -1 ; //Priority of the message being sent light_range = 0 var/datum/announcement/announcement = new + var/list/shipping_log = list() + var/ship_tag_name = "" + var/ship_tag_index = 0 + var/print_cooldown = 0 //cooldown on shipping label printer, stores the in-game time of when the printer will next be ready /obj/machinery/requests_console/power_change() ..() @@ -68,7 +74,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() ..() announcement.title = "[department] announcement" - announcement.newscast = 1 + announcement.newscast = 0 name = "[department] Requests Console" allConsoles += src @@ -128,6 +134,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() data["assist_dept"] = req_console_assistance data["supply_dept"] = req_console_supplies data["info_dept"] = req_console_information + data["ship_dept"] = TAGGERLOCATIONS data["message"] = message data["recipient"] = recipient @@ -135,6 +142,8 @@ var/list/obj/machinery/requests_console/allConsoles = list() data["msgStamped"] = msgStamped data["msgVerified"] = msgVerified data["announceAuth"] = announceAuth + data["shipDest"] = ship_tag_name + data["shipping_log"] = shipping_log return data @@ -182,7 +191,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() screen = RCS_SENTPASS message_log += "Message sent to [recipient]
[message]" else - audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) //Handle screen switching if(href_list["setScreen"]) @@ -199,6 +208,26 @@ var/list/obj/machinery/requests_console/allConsoles = list() reset_message() screen = tempScreen + if(href_list["shipSelect"]) + ship_tag_name = href_list["shipSelect"] + ship_tag_index = TAGGERLOCATIONS.Find(ship_tag_name) + + //Handle Shipping Label Printing + if(href_list["printLabel"]) + var/error_message = "" + if(!ship_tag_index) + error_message = "Please select a destination." + else if(!msgVerified) + error_message = "Please verify shipper ID." + else if(world.time < print_cooldown) + error_message = "Please allow the printer time to prepare the next shipping label." + if(error_message) + audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: [error_message]'"),,4) + return + print_label(ship_tag_name, ship_tag_index) + shipping_log += "Shipping Label printed for [ship_tag_name]
[msgVerified]" + reset_message(1) + //Handle silencing the console if(href_list["toggleSilent"]) silent = !silent @@ -245,6 +274,10 @@ var/list/obj/machinery/requests_console/allConsoles = list() reset_message() to_chat(user, "You are not authorized to send announcements.") updateUsrDialog() + if(screen == RCS_SHIPPING) + var/obj/item/weapon/card/id/T = O + msgVerified = text("Sender verified as [T.registered_name] ([T.assignment])") + updateUsrDialog() if(istype(O, /obj/item/weapon/stamp)) if(inoperable(MAINT)) return if(screen == RCS_MESSAUTH) @@ -261,6 +294,8 @@ var/list/obj/machinery/requests_console/allConsoles = list() msgStamped = "" announceAuth = 0 announcement.announcer = "" + ship_tag_name = "" + ship_tag_index = 0 if(mainmenu) screen = RCS_MAINMENU @@ -286,3 +321,9 @@ var/list/obj/machinery/requests_console/allConsoles = list() else // Normal src.message_log += "From: [linkedSender]
[message]" set_light(2) + +/obj/machinery/requests_console/proc/print_label(tag_name, tag_index) + var/obj/item/shippingPackage/sp = new /obj/item/shippingPackage(get_turf(src)) + sp.sortTag = tag_index + sp.update_desc() + print_cooldown = world.time + 600 //1 minute cooldown before you can print another label, but you can still configure the next one during this time diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm deleted file mode 100644 index dbff4722cad..00000000000 --- a/code/game/machinery/seed_extractor.dm +++ /dev/null @@ -1,65 +0,0 @@ -/obj/machinery/seed_extractor - name = "seed extractor" - desc = "Extracts and bags seeds from produce." - icon = 'icons/obj/hydroponics_machines.dmi' - icon_state = "sextractor" - density = 1 - anchored = 1 - -/obj/machinery/seed_extractor/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/seed_extractor(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - RefreshParts() - -/obj/machinery/seed_extractor/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/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - - if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O)) - return - - if(exchange_parts(user, O)) - return - - if(default_unfasten_wrench(user, O)) - return - - default_deconstruction_crowbar(O) - - // Fruits and vegetables. - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown)) - - user.drop_item(O) - - var/datum/seed/new_seed_type - if(istype(O, /obj/item/weapon/grown)) - var/obj/item/weapon/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] - else - var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] - - if(new_seed_type) - to_chat(user, "You extract some seeds from [O].") - var/produce = rand(1,4) - for(var/i = 0;i<=produce;i++) - var/obj/item/seeds/seeds = new(get_turf(src)) - seeds.seed_type = new_seed_type.name - seeds.update_seed() - else - to_chat(user, "[O] doesn't seem to have any usable seeds inside it.") - - qdel(O) - - //Grass. - else if(istype(O, /obj/item/stack/tile/grass)) - var/obj/item/stack/tile/grass/S = O - to_chat(user, "You extract some seeds from the [S.name].") - S.use(1) - new /obj/item/seeds/grassseed(loc) - - return \ No newline at end of file diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 1c6dcf6322e..7775744ba45 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -59,13 +59,13 @@ spawn(25) if(roll == 1) visible_message("[src] says, 'JACKPOT! [usr.name] has won a MILLION CREDITS!'") - command_announcement.Announce("Congratulations to [usr.name] on winning the Jackpot of ONE MILLION CREDITS!", "Jackpot Winner") + event_announcement.Announce("Congratulations to [usr.name] on winning the Jackpot of ONE MILLION CREDITS!", "Jackpot Winner") result = "JACKPOT! You win one million credits!" resultlvl = "highlight" win_money(1000000, 'sound/goonstation/misc/airraid_loop.ogg') else if(roll > 1 && roll <= 5) visible_message("[src] says, 'Big Winner! [usr.name] has won a hundred thousand credits!'") - command_announcement.Announce("Congratulations to [usr.name] on winning a hundred thousand credits!", "Big Winner") + event_announcement.Announce("Congratulations to [usr.name] on winning a hundred thousand credits!", "Big Winner") result = "Big Winner! You win a hundred thousand credits!" resultlvl = "good" win_money(100000, 'sound/goonstation/misc/klaxon.ogg') diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 12404d0574e..614f4d8f53f 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -203,6 +203,10 @@ var/emotion = "Neutral" +/obj/machinery/ai_status_display/attack_ai(mob/living/silicon/ai/user) + if(isAI(user)) + user.ai_statuschange() + /obj/machinery/ai_status_display/process() if(stat & NOPOWER) overlays.Cut() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index bf4300351fa..f9355a98d37 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -257,6 +257,7 @@ var/obj/machinery/syndicatebomb/B = src.loc for(var/i = 0; i < amt_summon; i++) var/atom/movable/X = new summon_path + X.admin_spawned = TRUE X.loc = get_turf(src) if(prob(50)) for(var/j = 1, j <= rand(1, 3), j++) diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 21da8c4159c..ad5aeb5fc61 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -25,6 +25,9 @@ var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg var/ailock = 0 //Silicons cannot use this + + var/syndicate = 0 + var/faction = "" // Turret controls can only access turrets that are in the same faction req_access = list(access_ai_upload) @@ -36,6 +39,23 @@ enabled = 1 lethal = 1 icon_state = "control_kill" + +/obj/machinery/turretid/syndicate + enabled = 1 + lethal = 1 + icon_state = "control_kill" + + lethal = 1 + check_arrest = 0 + check_records = 0 + check_weapons = 0 + check_access = 0 + check_anomalies = 1 + check_synth = 1 + ailock = 1 + + syndicate = 1 + faction = "syndicate" /obj/machinery/turretid/Destroy() if(control_area) @@ -50,7 +70,7 @@ control_area = get_area(src) else if(istext(control_area)) for(var/area/A in world) - if(A.name && A.name==control_area) + if(A.name && A.name == control_area) control_area = A break @@ -130,10 +150,10 @@ data["access"] = !isLocked(user) data["locked"] = locked data["enabled"] = enabled - data["is_lethal"] = 1 + data["lethal_control"] = !syndicate ? 1 : 0 data["lethal"] = lethal - if(data["access"]) + if(data["access"] && !syndicate) var/settings[0] settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) @@ -156,6 +176,8 @@ var/value = text2num(href_list["value"]) if(href_list["command"] == "enable") enabled = value + else if(syndicate) + return 1 else if(href_list["command"] == "lethal") lethal = value else if(href_list["command"] == "check_synth") @@ -188,7 +210,8 @@ if(istype(control_area)) for(var/obj/machinery/porta_turret/aTurret in control_area) - aTurret.setState(TC) + if(faction == aTurret.faction) + aTurret.setState(TC) update_icon() diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm deleted file mode 100644 index da5824b6f17..00000000000 --- a/code/game/machinery/turrets.dm +++ /dev/null @@ -1,580 +0,0 @@ -/area/turret_protected - name = "Turret Protected Area" - var/list/turretTargets = list() - -/area/turret_protected/proc/subjectDied(target) - if( isliving(target) ) - if( !issilicon(target) ) - var/mob/living/L = target - if( L.stat ) - if( L in turretTargets ) - src.Exited(L) - - -/area/turret_protected/Entered(O) - ..() - if( iscarbon(O) ) - turretTargets |= O - else if( istype(O, /obj/mecha) ) - var/obj/mecha/Mech = O - if( Mech.occupant ) - turretTargets |= Mech - else if( istype(O, /obj/spacepod) ) - var/obj/spacepod/Pod = O - if( Pod.pilot ) - turretTargets |= Pod - else if(istype(O,/mob/living/simple_animal)) - turretTargets |= O - return 1 - -/area/turret_protected/Exited(O) - if( ismob(O) && !issilicon(O) ) - turretTargets -= O - else if( istype(O, /obj/mecha) ) - turretTargets -= O - else if( istype(O, /obj/spacepod) ) - turretTargets -= O - ..() - return 1 - - -/obj/machinery/turret - name = "turret" - icon = 'icons/obj/turrets.dmi' - icon_state = "grey_target_prism" - var/raised = 0 - var/enabled = 1 - anchored = 1 - layer = 3 - invisibility = INVISIBILITY_LEVEL_TWO - density = 1 - var/lasers = 0 - var/lasertype = 1 - // 1 = lasers - // 2 = cannons - // 3 = pulse - // 4 = change (HONK) - // 5 = bluetag - // 6 = redtag - var/health = 80 - var/obj/machinery/turretcover/cover = null - var/popping = 0 - var/wasvalid = 0 - var/lastfired = 0 - var/shot_delay = 30 //3 seconds between shots - var/datum/effect/system/spark_spread/spark_system - use_power = 1 - idle_power_usage = 50 - active_power_usage = 300 -// var/list/targets - var/atom/movable/cur_target - var/targeting_active = 0 - var/area/turret_protected/protected_area - - -/obj/machinery/turret/New() - spark_system = new /datum/effect/system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) -// targets = new - ..() - return - -/obj/machinery/turretcover - name = "pop-up turret cover" - icon = 'icons/obj/turrets.dmi' - icon_state = "turretCover" - anchored = 1 - layer = 3.5 - density = 0 - var/obj/machinery/turret/host = null - -/obj/machinery/turret/proc/isPopping() - return (popping!=0) - -/obj/machinery/turret/power_change() - if(stat & BROKEN) - icon_state = "grey_target_prism" - else - if( powered() ) - if(src.enabled) - if(src.lasers) - icon_state = "orange_target_prism" - else - icon_state = "target_prism" - else - icon_state = "grey_target_prism" - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - src.icon_state = "grey_target_prism" - stat |= NOPOWER - -/obj/machinery/turret/proc/setState(var/enabled, var/lethal) - src.enabled = enabled - src.lasers = lethal - src.power_change() - - -/obj/machinery/turret/proc/get_protected_area() - var/area/turret_protected/TP = get_area(src) - if(istype(TP)) - return TP - return - -/obj/machinery/turret/proc/check_target(var/atom/movable/T as mob|obj) - if( T && T in protected_area.turretTargets ) - var/area/area_T = get_area(T) - if( !area_T || (area_T.type != protected_area.type) ) - protected_area.Exited(T) - return 0 //If the guy is somehow not in the turret's area (teleportation), get them out the damn list. --NEO - if( iscarbon(T) ) - var/mob/living/carbon/MC = T - if( !MC.stat ) - if( !MC.lying || lasers ) - return 1 - else if( istype(T, /obj/mecha) ) - var/obj/mecha/ME = T - if( ME.occupant ) - return 1 - else if( istype(T, /obj/spacepod) ) - var/obj/spacepod/SP = T - if( SP.pilot ) - return 1 - else if(istype(T,/mob/living/simple_animal)) - var/mob/living/simple_animal/A = T - if( !A.stat ) - if(lasers) - return 1 - return 0 - -/obj/machinery/turret/proc/get_new_target() - var/list/new_targets = new - var/new_target - for(var/mob/living/carbon/M in protected_area.turretTargets) - if(!M.stat) - if(!M.lying || lasers) - new_targets += M - for(var/obj/mecha/M in protected_area.turretTargets) - if(M.occupant) - new_targets += M - for(var/obj/spacepod/M in protected_area.turretTargets) - if(M.pilot) - new_targets += M.pilot - for(var/mob/living/simple_animal/M in protected_area.turretTargets) - if(!M.stat) - new_targets += M - if(new_targets.len) - new_target = pick(new_targets) - return new_target - - -/obj/machinery/turret/process() - if(stat & (NOPOWER|BROKEN)) - return - if(src.cover==null) - src.cover = new /obj/machinery/turretcover(src.loc) - src.cover.host = src - protected_area = get_protected_area() - if(!enabled || !protected_area || protected_area.turretTargets.len<=0) - if(!isDown() && !isPopping()) - popDown() - return - if(!check_target(cur_target)) //if current target fails target check - cur_target = get_new_target() //get new target - - if(cur_target) //if it's found, proceed -// to_chat(world, "[cur_target]") - if(!isPopping()) - if(isDown()) - popUp() - use_power = 2 - else - spawn() - if(!targeting_active) - targeting_active = 1 - target() - targeting_active = 0 - - if(prob(15)) - if(prob(50)) - playsound(get_turf(src), 'sound/effects/turret/move1.wav', 60, 1) - else - playsound(get_turf(src), 'sound/effects/turret/move2.wav', 60, 1) - - else if(!isPopping())//else, pop down - if(!isDown()) - popDown() - use_power = 1 - return - - -/obj/machinery/turret/proc/target() - while(src && enabled && !stat && check_target(cur_target)) - src.dir = get_dir(src, cur_target) - shootAt(cur_target) - sleep(shot_delay) - return - -/obj/machinery/turret/proc/shootAt(var/atom/movable/target) - var/turf/T = get_turf(src) - var/turf/U = get_turf(target) - if(!T || !U) - return - var/obj/item/projectile/A - if(src.lasers) - switch(lasertype) - if(1) - A = new /obj/item/projectile/beam(loc) - if(2) - A = new /obj/item/projectile/beam/laser/heavylaser(loc) - if(3) - A = new /obj/item/projectile/beam/pulse(loc) - if(4) - A = new /obj/item/projectile/magic/change(loc) - if(5) - A = new /obj/item/projectile/beam/lasertag/bluetag(loc) - if(6) - A = new /obj/item/projectile/beam/lasertag/redtag(loc) - use_power(500) - else - A = new /obj/item/projectile/energy/electrode( loc ) - use_power(200) - if(src.lasers) - playsound(get_turf(src), 'sound/weapons/Laser.ogg', 60, 1) - else - playsound(get_turf(src), 'sound/weapons/Taser.ogg', 60, 1) - A.original = target - A.current = T - A.yo = U.y - T.y - A.xo = U.x - T.x - A.fire() - return A - - -/obj/machinery/turret/proc/isDown() - return (invisibility!=0) - -/obj/machinery/turret/proc/popUp() - if((!isPopping()) || src.popping==-1) - invisibility = 0 - popping = 1 - playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - if(src.cover!=null) - flick("popup", src.cover) - src.cover.icon_state = "openTurretCover" - spawn(10) - if(popping==1) popping = 0 - -/obj/machinery/turret/proc/popDown() - if((!isPopping()) || src.popping==1) - popping = -1 - playsound(get_turf(src), 'sound/effects/turret/open.wav', 60, 1) - if(src.cover!=null) - flick("popdown", src.cover) - src.cover.icon_state = "turretCover" - spawn(10) - if(popping==-1) - invisibility = INVISIBILITY_LEVEL_TWO - popping = 0 - -/obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj) - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - src.health -= Proj.damage - ..() - if(prob(45) && Proj.damage > 0) src.spark_system.start() - qdel(Proj) - if(src.health <= 0) - src.die() - return - -/obj/machinery/turret/attackby(obj/item/weapon/W, mob/user)//I can't believe no one added this before/N - ..() - user.changeNext_move(CLICK_CD_MELEE) - playsound(src.loc, 'sound/weapons/smash.ogg', 60, 1) - src.spark_system.start() - src.health -= W.force * 0.5 - if(src.health <= 0) - src.die() - return - -/obj/machinery/turret/emp_act(severity) - switch(severity) - if(1) - enabled = 0 - lasers = 0 - power_change() - ..() - -/obj/machinery/turret/ex_act(severity) - if(severity < 3) - src.die() - -/obj/machinery/turret/proc/die() - src.health = 0 - src.density = 0 - src.stat |= BROKEN - src.icon_state = "destroyed_target_prism" - if(cover!=null) - qdel(cover) - sleep(3) - flick("explosion", src) - spawn(13) - qdel(src) - - -/obj/machinery/turret/attack_animal(mob/living/simple_animal/M as mob) - M.changeNext_move(CLICK_CD_MELEE) - M.do_attack_animation(src) - if(M.melee_damage_upper == 0) return - if(!(stat & BROKEN)) - visible_message("[M] [M.attacktext] [src]!") - add_logs(src, M, "attacked", admin=0) - //src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") - src.health -= M.melee_damage_upper - if(src.health <= 0) - src.die() - else - to_chat(M, "That object is useless to you.") - return - - - - -/obj/machinery/turret/attack_alien(mob/living/carbon/alien/humanoid/M as mob) - M.changeNext_move(CLICK_CD_MELEE) - M.do_attack_animation(src) - if(!(stat & BROKEN)) - playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1) - visible_message("[M] has slashed at [src]!") - src.health -= 15 - if(src.health <= 0) - src.die() - else - to_chat(M, "\green That object is useless to you.") - return - - - -/obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0) - if(..(href, href_list)) - return 1 - if(src.locked) - if(!istype(usr, /mob/living/silicon)) - to_chat(usr, "Control panel is locked!") - return - if(href_list["toggleOn"]) - src.enabled = !src.enabled - src.updateTurrets() - else if(href_list["toggleLethal"]) - src.lethal = !src.lethal - src.updateTurrets() - if(!nowindow) - src.attack_hand(usr) - -/obj/machinery/turretid/proc/update_icons() - if(src.enabled) - if(src.lethal) - icon_state = "control_kill" - else - icon_state = "control_stun" - else - icon_state = "control_standby" - //CODE FIXED BUT REMOVED -// if(control_area) //USE: updates other controls in the area -// for(var/obj/machinery/turretid/Turret_Control in world) //I'm not sure if this is what it was -// if( Turret_Control.control_area != src.control_area ) continue //supposed to do. Or whether the person -// Turret_Control.icon_state = icon_state //who coded it originally was just tired -// Turret_Control.enabled = enabled //or something. I don't see any situation -// Turret_Control.lethal = lethal //in which this would be used on the current map. - //If he wants it back he can uncomment it - - -/obj/machinery/gun_turret //related to turrets but work way differentely because of being mounted on a moving ship. - name = "machine gun turret" - desc = "Syndicate heavy defense turret. It really packs a bunch." - density = 1 - anchored = 1 - var/state = 0 //Like stat on mobs, 0 is alive, 1 is damaged, 2 is dead - var/faction = "syndicate" - var/atom/cur_target = null - var/scan_range = 9 //You will never see them coming - var/health = 200 //Because it lacks a cover, and is mostly to keep people from touching the syndie shuttle. - var/bullet_type = /obj/item/projectile/bullet - var/firing_sound = 'sound/weapons/Gunshot3.ogg' - var/base_icon = "syndieturret" - icon = 'icons/obj/turrets.dmi' - icon_state = "syndieturret0" - -/obj/machinery/gun_turret/New() - ..() - take_damage(0) //check your health - -/obj/machinery/gun_turret/ex_act(severity) - switch(severity) - if(1) - die() - if(2) - take_damage(100) - if(3) - take_damage(50) - return - -/obj/machinery/gun_turret/emp_act() //Can't emp an mechanical turret. - return - -/obj/machinery/gun_turret/update_icon() - if(state > 2 || state < 0) //someone fucked up the vars so fix them - take_damage(0) - icon_state = "[base_icon]" + "[state]" - return - - -/obj/machinery/gun_turret/proc/take_damage(damage) - health -= damage - var/orig_health = initial(health) - var/health_percent = (health/orig_health) * 100 - - if(health_percent > 50) - state = 0 - else - state = 1 - if(health_percent <= 0) - if(state != 2) - die() - return - state = 2 - - update_icon() - - - - -/obj/machinery/gun_turret/bullet_act(var/obj/item/projectile/Proj) - if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - take_damage(Proj.damage) - return - -/obj/machinery/gun_turret/proc/die() - state = 2 - update_icon() - -/obj/machinery/gun_turret/attack_hand(mob/user) - return - -/obj/machinery/gun_turret/attack_ai(mob/user) - return attack_hand(user) - - -/obj/machinery/gun_turret/attack_alien(mob/living/user as mob) - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(src) - playsound(src.loc, 'sound/weapons/slash.ogg', 25, 1, -1) - user.visible_message("[user] slashes at [src]", "You slash at [src]") - take_damage(15) - return - -/obj/machinery/gun_turret/proc/validate_target(atom/target) - if(get_dist(target, src)>scan_range) - return 0 - if(istype(target, /mob)) - var/mob/M = target - if(!M.stat) - return 1 - else if(istype(target, /obj/mecha)) - var/obj/mecha/M = target - if(M.occupant) - return 1 - else if(istype(target, /obj/spacepod)) - var/obj/spacepod/S = target - if(S.pilot) - return 1 - return 0 - - -/obj/machinery/gun_turret/process() - if(state == 2) - return - if(cur_target && !validate_target(cur_target)) - cur_target = null - if(!cur_target) - cur_target = get_target() - if(cur_target) - fire(cur_target) - return - - -/obj/machinery/gun_turret/proc/get_target() - var/list/pos_targets = list() - var/target = null - for(var/mob/living/M in view(scan_range,src)) - if(M.stat) - continue - if(faction in M.faction) - continue - if(ispAI(M)) - continue - pos_targets += M - for(var/obj/mecha/M in oview(scan_range, src)) - if(M.occupant) - if(faction in M.occupant.faction) - continue - if(!M.occupant) - continue //Don't shoot at empty mechs. - pos_targets += M - for(var/obj/spacepod/M in oview(scan_range, src)) - if(M.pilot) - var/mob/P = M.pilot - if(faction in P.faction) - continue - if(!M.pilot) - continue //Don't shoot at empty pods. - pos_targets += M - if(pos_targets.len) - target = pick(pos_targets) - return target - - -/obj/machinery/gun_turret/proc/fire(atom/target) - if(!target) - cur_target = null - return - src.dir = get_dir(src,target) - var/turf/targloc = get_turf(target) - if(!src) - return - var/turf/curloc = get_turf(src) - if(!targloc || !curloc) - return - if(targloc == curloc) - return - playsound(get_turf(src), firing_sound, 60, 1) - var/obj/item/projectile/A = new bullet_type(curloc) - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - A.fire() - return - - -/obj/machinery/gun_turret/interior - name = "machine gun turret (.45)" - desc = "Syndicate interior defense turret chambered for .45 rounds. Designed to down intruders without damaging the hull." - bullet_type = /obj/item/projectile/bullet/midbullet - -/obj/machinery/gun_turret/exterior - name = "machine gun turret (7.62)" - desc = "Syndicate exterior defense turret chambered for 7.62 rounds. Designed to down intruders with heavy calliber bullets." - bullet_type = /obj/item/projectile/bullet - -/obj/machinery/gun_turret/grenade - name = "mounted grenade launcher (40mm)" - desc = "Syndicate 40mm grenade launcher defense turret. If you've had this much time to look at it, you're probably already dead." - bullet_type = /obj/item/projectile/bullet/a40mm - -/obj/machinery/gun_turret/assault_pod - name = "machine gun turret (4.6x30mm)" - desc = "Syndicate exterior defense turret chambered for 4.6x30mm rounds. Designed to be fitted to assault pods, it uses low calliber bullets to save space." - health = 100 - bullet_type = /obj/item/projectile/bullet/weakbullet3 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 4ec9471a36a..1ba521f1280 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -796,10 +796,21 @@ desc = "A self-serving Chinese food machine, for all your Chinese food needs." product_slogans = "Taste 5000 years of culture!" icon_state = "snack" - products = list(/obj/item/weapon/reagent_containers/food/snacks/chinese/chowmein = 5, /obj/item/weapon/reagent_containers/food/snacks/chinese/tao = 5, /obj/item/weapon/reagent_containers/food/snacks/chinese/newdles = 5, - /obj/item/weapon/reagent_containers/food/snacks/chinese/rice = 5, /obj/item/weapon/reagent_containers/food/snacks/wingfangchu = 5) + products = list(/obj/item/weapon/reagent_containers/food/snacks/chinese/chowmein = 6, /obj/item/weapon/reagent_containers/food/snacks/chinese/tao = 6, /obj/item/weapon/reagent_containers/food/snacks/chinese/newdles = 6, + /obj/item/weapon/reagent_containers/food/snacks/chinese/rice = 6) prices = list(/obj/item/weapon/reagent_containers/food/snacks/chinese/chowmein = 50, /obj/item/weapon/reagent_containers/food/snacks/chinese/tao = 50, /obj/item/weapon/reagent_containers/food/snacks/chinese/newdles = 50, - /obj/item/weapon/reagent_containers/food/snacks/chinese/rice = 50, /obj/item/weapon/reagent_containers/food/snacks/wingfangchu = 50) + /obj/item/weapon/reagent_containers/food/snacks/chinese/rice = 50) + refill_canister = /obj/item/weapon/vending_refill/chinese + +/obj/machinery/vending/chinese/New() + ..() + component_parts = list() + var/obj/item/weapon/circuitboard/vendor/V = new(null) + V.set_type(type) + component_parts += V + component_parts += new /obj/item/weapon/vending_refill/chinese(0) + component_parts += new /obj/item/weapon/vending_refill/chinese(0) + component_parts += new /obj/item/weapon/vending_refill/chinese(0) /obj/machinery/vending/cola name = "\improper Robust Softdrinks" @@ -865,10 +876,10 @@ product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs." vend_delay = 34 icon_state = "cigs" - products = list(/obj/item/weapon/storage/fancy/cigarettes = 5,/obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 3,/obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 2,/obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 3,/obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 1,/obj/item/weapon/storage/fancy/cigarettes/cigpack_random = 2, /obj/item/weapon/reagent_containers/food/pill/patch/nicotine = 10, /obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4,/obj/item/weapon/rollingpaperpack = 5) + products = list(/obj/item/weapon/storage/fancy/cigarettes = 5,/obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 3,/obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 2,/obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 3,/obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 1,/obj/item/weapon/storage/fancy/cigarettes/cigpack_random = 2, /obj/item/weapon/reagent_containers/food/pill/patch/nicotine = 10, /obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4,/obj/item/weapon/storage/fancy/rollingpapers = 5) contraband = list(/obj/item/weapon/lighter/zippo = 4) premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2,/obj/item/weapon/storage/fancy/cigarettes/cigpack_robustgold = 1) - prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_random = 150, /obj/item/weapon/reagent_containers/food/pill/patch/nicotine = 15, /obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60, /obj/item/weapon/rollingpaperpack = 20) + prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_uplift = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_robust = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_carp = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_midori = 60,/obj/item/weapon/storage/fancy/cigarettes/cigpack_random = 150, /obj/item/weapon/reagent_containers/food/pill/patch/nicotine = 15, /obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60, /obj/item/weapon/storage/fancy/rollingpapers = 20) refill_canister = /obj/item/weapon/vending_refill/cigarette /obj/machinery/vending/cigarette/New() @@ -945,7 +956,7 @@ icon_deny = "sec-deny" req_access_txt = "1" products = list(/obj/item/weapon/restraints/handcuffs = 8,/obj/item/weapon/restraints/handcuffs/cable/zipties = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, - /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4,/obj/item/weapon/restraints/legcuffs/bola/energy = 7) + /obj/item/weapon/reagent_containers/food/snacks/donut = 12,/obj/item/weapon/storage/box/evidence = 6,/obj/item/device/flashlight/seclite = 4,/obj/item/weapon/restraints/legcuffs/bola/energy = 7) contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/fancy/donut_box = 2,/obj/item/device/hailer = 5) /obj/machinery/vending/hydronutrients @@ -955,8 +966,8 @@ product_ads = "We like plants!;Don't you want some?;The greenest thumbs ever.;We like big plants.;Soft soil..." icon_state = "nutri" icon_deny = "nutri-deny" - products = list(/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez = 35,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/l4z = 25,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/rh = 15,/obj/item/weapon/plantspray/pests = 20, - /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5) + products = list(/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez = 30,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/l4z = 20,/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh = 10,/obj/item/weapon/reagent_containers/spray/pestspray = 20, + /obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5,/obj/item/weapon/cultivator = 3,/obj/item/weapon/shovel/spade = 3,/obj/item/device/plant_analyzer = 4) contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5) ///obj/item/beezeez = 45, @@ -967,16 +978,16 @@ product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!" product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!" icon_state = "seeds" - products = list(/obj/item/seeds/aloeseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/appleseed = 3,/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3, - /obj/item/seeds/cabbageseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/chantermycelium = 3, - /obj/item/seeds/chiliseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/coffeeaseed = 3,/obj/item/seeds/comfreyseed =3,/obj/item/seeds/cornseed = 3, - /obj/item/seeds/eggplantseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/lemonseed = 3, - /obj/item/seeds/limeseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/potatoseed = 3,/obj/item/seeds/poppyseed = 3, - /obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/replicapod = 3,/obj/item/seeds/riceseed = 3,/obj/item/seeds/soyaseed = 3,/obj/item/seeds/sunflowerseed = 3, - /obj/item/seeds/teaasperaseed = 3,/obj/item/seeds/tobaccoseed = 3,/obj/item/seeds/tomatoseed = 3, - /obj/item/seeds/towermycelium = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/whitebeetseed = 3) - contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2, - /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/random = 2, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/brownmold = 2) + products = list(/obj/item/seeds/aloe =3, /obj/item/seeds/ambrosia = 3,/obj/item/seeds/apple = 3,/obj/item/seeds/banana = 3,/obj/item/seeds/berry = 3, + /obj/item/seeds/cabbage = 3,/obj/item/seeds/carrot = 3,/obj/item/seeds/cherry = 3,/obj/item/seeds/chanter = 3, + /obj/item/seeds/chili = 3,/obj/item/seeds/cocoapod = 3,/obj/item/seeds/coffee = 3, /obj/item/seeds/comfrey =3, /obj/item/seeds/corn = 3, + /obj/item/seeds/nymph =3, /obj/item/seeds/eggplant = 3,/obj/item/seeds/grape = 3,/obj/item/seeds/grass = 3,/obj/item/seeds/lemon = 3, + /obj/item/seeds/lime = 3,/obj/item/seeds/orange = 3, /obj/item/seeds/peanuts = 3, /obj/item/seeds/potato = 3,/obj/item/seeds/poppy = 3, + /obj/item/seeds/pumpkin = 3,/obj/item/seeds/replicapod = 3,/obj/item/seeds/wheat/rice = 3,/obj/item/seeds/soya = 3,/obj/item/seeds/sunflower = 3, + /obj/item/seeds/tea = 3,/obj/item/seeds/tobacco = 3,/obj/item/seeds/tomato = 3, + /obj/item/seeds/tower = 3,/obj/item/seeds/watermelon = 3,/obj/item/seeds/wheat = 3,/obj/item/seeds/whitebeet = 3) + contraband = list(/obj/item/seeds/amanita = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/liberty = 2,/obj/item/seeds/nettle = 2, + /obj/item/seeds/plump = 2,/obj/item/seeds/reishi = 2,/obj/item/seeds/cannabis = 3, /obj/item/seeds/fungus = 3, /obj/item/seeds/random = 2) premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1) /** @@ -1033,8 +1044,10 @@ products = list(/obj/item/clothing/suit/chickensuit = 1,/obj/item/clothing/head/chicken = 1,/obj/item/clothing/under/gladiator = 1, /obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1, /obj/item/clothing/suit/storage/labcoat/mad = 1,/obj/item/clothing/glasses/gglasses = 1,/obj/item/clothing/shoes/jackboots = 1, - /obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/blackskirt = 1,/obj/item/clothing/head/beret = 1, - /obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/accessory/waistcoat = 1, + /obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/blackskirt = 1, + /obj/item/clothing/suit/toggle/owlwings = 1, /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1, + /obj/item/clothing/suit/toggle/owlwings/griffinwings = 1, /obj/item/clothing/under/griffin = 1, /obj/item/clothing/shoes/griffin = 1, /obj/item/clothing/head/griffin = 1, + /obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/accessory/waistcoat = 1, /obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowlerhat = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1, /obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1, /obj/item/clothing/suit/apron = 1,/obj/item/clothing/under/waiter = 1,/obj/item/clothing/suit/jacket/miljacket = 1, @@ -1044,10 +1057,19 @@ /obj/item/clothing/mask/gas/cyborg = 1,/obj/item/clothing/suit/holidaypriest = 1,/obj/item/clothing/head/wizard/marisa/fake = 1, /obj/item/clothing/suit/wizrobe/marisa/fake = 1,/obj/item/clothing/under/sundress = 1,/obj/item/clothing/head/witchwig = 1,/obj/item/weapon/twohanded/staff/broom = 1, /obj/item/clothing/suit/wizrobe/fake = 1,/obj/item/clothing/head/wizard/fake = 1,/obj/item/weapon/twohanded/staff = 3,/obj/item/clothing/mask/gas/sexyclown = 1, - /obj/item/clothing/under/sexyclown = 1,/obj/item/clothing/mask/gas/sexymime = 1,/obj/item/clothing/under/sexymime = 1,/obj/item/clothing/suit/apron/overalls = 1, + /obj/item/clothing/under/sexyclown = 1,/obj/item/clothing/mask/gas/sexymime = 1,/obj/item/clothing/under/sexymime = 1, + /obj/item/clothing/mask/face/bat = 1,/obj/item/clothing/mask/face/bee = 1,/obj/item/clothing/mask/face/bear = 1,/obj/item/clothing/mask/face/raven = 1,/obj/item/clothing/mask/face/jackal = 1,/obj/item/clothing/mask/face/fox = 1,/obj/item/clothing/mask/face/tribal = 1,/obj/item/clothing/mask/face/rat = 1, + /obj/item/clothing/suit/apron/overalls = 1, /obj/item/clothing/head/rabbitears =1, /obj/item/clothing/head/sombrero = 1, /obj/item/clothing/suit/poncho = 1, /obj/item/clothing/suit/poncho/green = 1, /obj/item/clothing/suit/poncho/red = 1, /obj/item/clothing/accessory/blue = 1, /obj/item/clothing/accessory/red = 1, /obj/item/clothing/accessory/black = 1, /obj/item/clothing/accessory/horrible = 1, - /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1, /obj/item/clothing/under/pants/camo = 1, /obj/item/clothing/mask/bandana = 1, /obj/item/clothing/mask/bandana/black = 1) + /obj/item/clothing/under/maid = 1, /obj/item/clothing/under/janimaid = 1, + /obj/item/clothing/under/jester = 1, /obj/item/clothing/head/jester = 1, + /obj/item/clothing/under/pants/camo = 1, /obj/item/clothing/mask/bandana = 1, /obj/item/clothing/mask/bandana/black = 1, + /obj/item/clothing/shoes/singery = 1,/obj/item/clothing/under/singery = 1, + /obj/item/clothing/shoes/singerb = 1,/obj/item/clothing/under/singerb = 1, + /obj/item/clothing/suit/hooded/carp_costume = 1,/obj/item/clothing/suit/hooded/bee_costume = 1, + /obj/item/clothing/suit/snowman = 1,/obj/item/clothing/head/snowman = 1, + /obj/item/clothing/head/cueball = 1,/obj/item/clothing/under/scratch = 1) contraband = list(/obj/item/clothing/suit/judgerobe = 1,/obj/item/clothing/head/powdered_wig = 1,/obj/item/weapon/gun/magic/wand = 1, /obj/item/clothing/mask/balaclava=1, /obj/item/clothing/mask/horsehead = 2) premium = list(/obj/item/clothing/suit/hgpirate = 1, /obj/item/clothing/head/hgpiratecap = 1, /obj/item/clothing/head/helmet/roman = 1, /obj/item/clothing/head/helmet/roman/legionaire = 1, /obj/item/clothing/under/roman = 1, /obj/item/clothing/shoes/roman = 1, /obj/item/weapon/shield/riot/roman = 1) refill_canister = /obj/item/weapon/vending_refill/autodrobe @@ -1106,7 +1128,7 @@ icon_state = "engivend" icon_deny = "engivend-deny" req_access_txt = "11" //Engineering Equipment access - products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/firealarm_electronics = 10,/obj/item/weapon/apc_electronics = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/stock_parts/cell/high = 10,/obj/item/weapon/camera_assembly = 10) + products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/firelock_electronics = 10,/obj/item/weapon/firealarm_electronics = 10,/obj/item/weapon/apc_electronics = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/stock_parts/cell/high = 10,/obj/item/weapon/camera_assembly = 10) contraband = list(/obj/item/weapon/stock_parts/cell/potato = 3) premium = list(/obj/item/weapon/storage/belt/utility = 3) @@ -1163,7 +1185,12 @@ desc = "It doesn't seem the slightest bit unusual. This frustrates you immensely." icon_state = "hats" product_ads = "Warning, not all hats are dog/monkey compatible. Apply forcefully with care.;Apply directly to the forehead.;Who doesn't love spending cash on hats?!;From the people that brought you collectable hat crates, Hatlord!" - products = list(/obj/item/clothing/head/bowlerhat = 10,/obj/item/clothing/head/beaverhat = 10,/obj/item/clothing/head/boaterhat = 10,/obj/item/clothing/head/fedora = 10,/obj/item/clothing/head/fez = 10) + products = list(/obj/item/clothing/head/bowlerhat = 10, + /obj/item/clothing/head/beaverhat = 10, + /obj/item/clothing/head/boaterhat = 10, + /obj/item/clothing/head/fedora = 10, + /obj/item/clothing/head/fez = 10, + /obj/item/clothing/head/beret = 10) contraband = list(/obj/item/clothing/head/bearpelt = 5) premium = list(/obj/item/clothing/head/soft/rainbow = 1) refill_canister = /obj/item/weapon/vending_refill/hatdispenser diff --git a/code/game/magic/Uristrunes.dm b/code/game/magic/Uristrunes.dm index 5cb7dc4127e..ed881c71fb1 100644 --- a/code/game/magic/Uristrunes.dm +++ b/code/game/magic/Uristrunes.dm @@ -17,7 +17,10 @@ var/runetype = "rune" /proc/get_rune(symbol_bits, animated = 0) var/lookup = "[symbol_bits]-[animated]" - if(ticker.mode.cultdat.theme == "fire") + + if(!ticker.mode)//work around for maps with runes and cultdat is not loaded all the way + runetype = "rune" + else if(ticker.mode.cultdat.theme == "fire") runetype = "fire-rune" if(lookup in rune_cache) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index d95570cf88f..13602957de1 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -243,7 +243,6 @@ desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." icon = 'icons/obj/guns/projectile.dmi' icon_state = "syringegun" - flags = NOREACT var/list/syringes var/list/known_reagents var/list/processed_reagents @@ -259,6 +258,7 @@ /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New() ..() create_reagents(max_volume) + reagents.set_reacting(FALSE) syringes = new known_reagents = list("epinephrine"="Epinephrine","charcoal"="Charcoal") processed_reagents = new @@ -273,7 +273,8 @@ /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() ..() - flags &= ~NOREACT + if(reagents) + reagents.set_reacting(TRUE) /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) if(..()) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index fedb792c37d..93a86fbe956 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -111,15 +111,15 @@ if(ismob(A)) var/mob/M = A if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" - firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" + M.create_attack_log("[firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]") + firer.create_attack_log("[firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]") log_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src]") if(!iscarbon(firer)) M.LAssailant = null else M.LAssailant = firer else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" + M.create_attack_log("UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]") log_attack("UNKNOWN shot [M] ([M.ckey]) with a [src]") if(life <= 0) qdel(src) @@ -358,7 +358,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar name = "Banana Mortar" icon_state = "mecha_bananamrtr" - projectile = /obj/item/weapon/bananapeel + projectile = /obj/item/weapon/grown/bananapeel fire_sound = 'sound/items/bikehorn.ogg' projectiles = 15 missile_speed = 1.5 @@ -375,7 +375,7 @@ if(!action_checks(target)) return set_ready_state(0) - var/obj/item/weapon/bananapeel/B = new projectile(chassis.loc) + var/obj/item/weapon/grown/bananapeel/B = new projectile(chassis.loc) playsound(chassis, fire_sound, 60, 1) B.throw_at(target, missile_range, missile_speed, chassis) projectiles-- diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 12dafd891e9..4ec4746a198 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -50,6 +50,7 @@ var/obj/machinery/atmospherics/unary/portables_connector/connected_port = null var/obj/item/device/radio/radio = null + var/list/trackers = list() var/max_temperature = 25000 var/internal_damage_threshold = 50 //health percentage below which internal damage is possible @@ -74,7 +75,7 @@ var/melee_cooldown = 10 var/melee_can_hit = 1 - hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD) + hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) /obj/mecha/New() ..() @@ -93,6 +94,7 @@ processing_objects.Add(src) removeVerb(/obj/mecha/verb/disconnect_from_port) + poi_list |= src log_message("[src] created.") mechas_list += src //global mech list prepare_huds() @@ -101,6 +103,7 @@ diag_hud_set_mechhealth() diag_hud_set_mechcell() diag_hud_set_mechstat() + diag_hud_set_mechtracking() //////////////////////// ////// Helpers ///////// @@ -164,7 +167,7 @@ /obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. return -/obj/mecha/hear_talk(mob/M as mob, text) +/obj/mecha/hear_talk(mob/M, text) if(M == occupant && radio.broadcasting) radio.talk_into(M, text) @@ -464,7 +467,7 @@ qdel(src) return -/obj/mecha/attack_hand(mob/living/user as mob) +/obj/mecha/attack_hand(mob/living/user) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) log_message("Attack by hand/paw. Attacker - [user].",1) @@ -480,7 +483,7 @@ return -/obj/mecha/attack_alien(mob/living/user as mob) +/obj/mecha/attack_alien(mob/living/user) log_message("Attack by alien. Attacker - [user].",1) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) @@ -499,8 +502,10 @@ return -/obj/mecha/attack_animal(mob/living/simple_animal/user as mob) +/obj/mecha/attack_animal(mob/living/simple_animal/user) log_message("Attack by simple animal. Attacker - [user].",1) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(user.melee_damage_upper == 0) user.custom_emote(1, "[user.friendly] [src]") else @@ -510,13 +515,13 @@ take_damage(damage) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) visible_message("[user] [user.attacktext] [src]!") - user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + user.create_attack_log("attacked [name]") else log_append_to_last("Armor saved.") playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1) occupant_message("\blue The [user]'s attack is stopped by the armor.") visible_message("\blue The [user] rebounds off [name]'s armor!") - user.attack_log += text("\[[time_stamp()]\] attacked [name]") + user.create_attack_log("attacked [name]") return /obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper @@ -614,6 +619,7 @@ qdel(internal_tank) processing_objects.Remove(src) + poi_list.Remove(src) equipment.Cut() cell = null internal_tank = null @@ -794,7 +800,9 @@ to_chat(user, "\the [W] is stuck to your hand, you cannot put it in \the [src]") return W.forceMove(src) + trackers += W user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src].") + diag_hud_set_mechtracking() return else if(istype(W, /obj/item/weapon/paintkit)) @@ -829,6 +837,8 @@ /obj/mecha/proc/attacked_by(obj/item/I, mob/user) log_message("Attacked by [I]. Attacker - [user]") + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) var/deflection = deflect_chance var/dam_coeff = 1 for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment) @@ -860,20 +870,35 @@ //////////// AI piloting //////////// ///////////////////////////////////// -/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob) +/obj/mecha/attack_ai(mob/living/silicon/ai/user) if(!isAI(user)) return //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. if(user.can_dominate_mechs) examine(user) //Get diagnostic information! - var/obj/item/mecha_parts/mecha_tracking/B = locate(/obj/item/mecha_parts/mecha_tracking) in src - if(B) //Beacons give the AI more detailed mech information. + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers) to_chat(user, "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:") - to_chat(user, "[B.get_mecha_info()]") + to_chat(user, "[B.get_mecha_info_text()]") + break //Nothing like a big, red link to make the player feel powerful! to_chat(user, "ASSUME DIRECT CONTROL?
") + else + examine(user) + if(occupant) + user << "This exosuit has a pilot and cannot be controlled." + return + var/can_control_mech = FALSE + for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers) + can_control_mech = TRUE + to_chat(user, "[bicon(src)] Status of [name]:\n\ + [A.get_mecha_info_text()]") + break + if(!can_control_mech) + to_chat(user, "You cannot control exosuits without AI control beacons installed.") + return + to_chat(user, "Take control of exosuit?
") -/obj/mecha/transfer_ai(var/interaction, mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) +/obj/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) if(!..()) return @@ -901,12 +926,13 @@ to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") - if(AI_MECH_HACK) //Called by Malf AI mob on the mech. - new /obj/structure/AIcore/deactivated(AI.loc) - if(occupant) //Oh, I am sorry, were you using that? - to_chat(AI, "Pilot detected! Forced ejection initiated!") - to_chat(occupant, "You have been forcibly ejected!") - go_out(1) //IT IS MINE, NOW. SUCK IT, RD! + if(AI_MECH_HACK) //Called by AIs on the mech + AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc) + if(AI.can_dominate_mechs) + if(occupant) //Oh, I am sorry, were you using that? + to_chat(AI, "Pilot detected! Forced ejection initiated!") + to_chat(occupant, "You have been forcibly ejected!") + go_out(1) //IT IS MINE, NOW. SUCK IT, RD! ai_enter_mech(AI, interaction) if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. @@ -926,7 +952,7 @@ ai_enter_mech(AI, interaction) //Hack and From Card interactions share some code, so leave that here for both to use. -/obj/mecha/proc/ai_enter_mech(var/mob/living/silicon/ai/AI, var/interaction) +/obj/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) AI.aiRestorePowerRoutine = 0 AI.loc = src occupant = AI @@ -939,7 +965,7 @@ AI.remote_control = src AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES. - to_chat(AI, "[interaction == AI_MECH_HACK ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \ + to_chat(AI, "[AI.can_dominate_mechs ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \ : "You have been uploaded to a mech's onboard computer."]") to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") @@ -1166,7 +1192,7 @@ to_chat(user, "You stop inserting the MMI.") return 0 -/obj/mecha/proc/mmi_moved_inside(var/obj/item/device/mmi/mmi_as_oc as obj,mob/user as mob) +/obj/mecha/proc/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user) if(mmi_as_oc && user in range(1)) if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client) to_chat(user, "Consciousness matrix not detected.") @@ -1233,7 +1259,7 @@ if(occupant && occupant == M) // The occupant exited the mech without calling go_out() go_out(1, newloc) -/obj/mecha/proc/go_out(var/forced, var/atom/newloc = loc) +/obj/mecha/proc/go_out(forced, atom/newloc = loc) if(!occupant) return var/atom/movable/mob_container @@ -1242,15 +1268,29 @@ if(ishuman(occupant)) mob_container = occupant //RemoveActions(occupant, human_occupant=1) - else if(istype(occupant, /mob/living/carbon/brain)) + else if(isbrain(occupant)) var/mob/living/carbon/brain/brain = occupant //RemoveActions(brain) mob_container = brain.container - else if(isAI(occupant) && forced) //This should only happen if there are multiple AIs in a round, and at least one is Malf. - //RemoveActions(occupant) - occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. - occupant = null - return + else if(isAI(occupant)) + var/mob/living/silicon/ai/AI = occupant + if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. + //RemoveActions(occupant) + occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. + occupant = null + return + else + if(!AI.linked_core || qdeleted(AI.linked_core)) + to_chat(AI, "Inactive core destroyed. Unable to return.") + AI.linked_core = null + return + to_chat(AI, "Returning to core...") + AI.controlled_mech = null + AI.remote_control = null + //RemoveActions(occupant, 1) + mob_container = AI + newloc = get_turf(AI.linked_core) + qdel(AI.linked_core) else return var/mob/living/L = occupant @@ -1433,6 +1473,7 @@ diag_hud_set_mechhealth() diag_hud_set_mechcell() diag_hud_set_mechstat() + diag_hud_set_mechtracking() /obj/mecha/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list()) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 11c940f7971..2bb73e2c636 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -10,10 +10,10 @@ var/screen = 0 var/stored_data -/obj/machinery/computer/mecha/attack_ai(var/mob/user as mob) +/obj/machinery/computer/mecha/attack_ai(mob/user) return attack_hand(user) -/obj/machinery/computer/mecha/attack_hand(var/mob/user as mob) +/obj/machinery/computer/mecha/attack_hand(mob/user) ui_interact(user) /obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) @@ -73,11 +73,12 @@ icon_state = "motion2" w_class = 2 origin_tech = "programming=2;magnets=2" + var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking. /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() if(!in_mecha()) - return 0 - var/obj/mecha/M = src.loc + return FALSE + var/obj/mecha/M = loc var/list/answer[0] answer["reference"] = "\ref[src]" answer["name"] = sanitize(replacetext(M.name,"\"","'")) // Double apostrophes break JSON @@ -101,6 +102,25 @@ return answer +/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info_text() + if(!in_mecha()) + return FALSE + var/obj/mecha/M = loc + var/cell_charge = M.get_charge() + var/area/A = get_area(M) + var/answer = {"Name: [M.name] + Integrity: [M.health/initial(M.health)*100]% + Cell charge: [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"] + Airtank: [M.return_pressure()]kPa + Pilot: [M.occupant||"None"] + Location: [sanitize(A.name)||"Unknown"] + Active equipment: [M.selected||"None"]
"} + if(istype(M, /obj/mecha/working/ripley)) + var/obj/mecha/working/ripley/RM = M + answer += "Used cargo space: [RM.cargo.len/RM.cargo_capacity*100]%
" + + return answer + /obj/item/mecha_parts/mecha_tracking/emp_act() qdel(src) return @@ -110,9 +130,9 @@ return /obj/item/mecha_parts/mecha_tracking/proc/in_mecha() - if(istype(src.loc, /obj/mecha)) - return src.loc - return 0 + if(istype(loc, /obj/mecha)) + return loc + return FALSE /obj/item/mecha_parts/mecha_tracking/proc/shock() var/obj/mecha/M = in_mecha() @@ -121,19 +141,26 @@ qdel(src) /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log() - if(!src.in_mecha()) + if(!in_mecha()) return 0 - var/obj/mecha/M = src.loc + var/obj/mecha/M = loc return M.get_log_html() +/obj/item/mecha_parts/mecha_tracking/ai_control + name = "exosuit AI control beacon" + desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit." + origin_tech = "programming=3;magnets=2;engineering=2" + ai_beacon = TRUE + /obj/item/weapon/storage/box/mechabeacons name = "Exosuit Tracking Beacons" - New() - ..() - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) - new /obj/item/mecha_parts/mecha_tracking(src) + +/obj/item/weapon/storage/box/mechabeacons/New() + ..() + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) + new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index ce28687a9e6..8aee3ef1f4c 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -4,4 +4,4 @@ /obj/mecha/medical/New() ..() - new /obj/item/mecha_parts/mecha_tracking(src) + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index f26e34834fb..bb5e0237c9b 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -110,10 +110,10 @@ //Add ore box to cargo cargo.Add(new /obj/structure/ore_box(src)) - //Attach hydrolic clamp + //Attach hydraulic clamp var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp HC.attach(src) - for(var/obj/item/mecha_parts/mecha_tracking/B in contents)//Deletes the beacon so it can't be found easily + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily qdel(B) var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new /obj/item/mecha_parts/mecha_equipment/mining_scanner diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm index ccbfe2ef21b..e4c001a508a 100644 --- a/code/game/mecha/working/working.dm +++ b/code/game/mecha/working/working.dm @@ -3,4 +3,4 @@ /obj/mecha/working/New() ..() - new /obj/item/mecha_parts/mecha_tracking(src) + trackers += new /obj/item/mecha_parts/mecha_tracking(src) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index ea692339ac3..8ff0d7cfcf4 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -35,11 +35,11 @@ return FALSE //procs that handle the actual buckling and unbuckling -/atom/movable/proc/buckle_mob(mob/living/M) - if(!can_buckle || !istype(M) || (M.loc != loc) || M.buckled || M.buckled_mob || buckled_mob || (buckle_requires_restraints && !M.restrained()) || M == src) +/atom/movable/proc/buckle_mob(mob/living/M, force = 0) + if((!can_buckle && !force)|| !istype(M) || (M.loc != loc) || M.buckled || M.buckled_mob || buckled_mob || (buckle_requires_restraints && !M.restrained()) || M == src) return 0 - if(isslime(M) || isAI(M)) + if((isslime(M) || isAI(M)) && !force) if(M == usr) to_chat(M, "You are unable to buckle yourself to the [src]!") else @@ -54,7 +54,7 @@ M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src) return 1 -/obj/buckle_mob(mob/living/M) +/obj/buckle_mob(mob/living/M, force = 0) . = ..() if(.) if(burn_state == ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 106c451ca09..19cbbd38c5a 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -363,7 +363,8 @@ break /obj/structure/alien/egg/bullet_act(obj/item/projectile/Proj) - health -= Proj.damage + if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + health -= Proj.damage ..() healthcheck() diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 090a7437a5b..434fec620b8 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -18,6 +18,11 @@ var/new_frequency = sanitize_frequency(rand(PUBLIC_LOW_FREQ, PUBLIC_HIGH_FREQ)) aSignal.set_frequency(new_frequency) + poi_list |= src + +/obj/effect/anomaly/Destroy() + poi_list.Remove(src) + return ..() /obj/effect/anomaly/proc/anomalyEffect() if(prob(50)) diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index aad9f5ab4bf..3d6a47a00b9 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -1,4 +1,4 @@ -obj/effect/decal/cleanable/liquid_fuel +/obj/effect/decal/cleanable/liquid_fuel //Liquid fuel is used for things that used to rely on volatile fuels or plasma being contained to a couple tiles. icon = 'icons/effects/effects.dmi' icon_state = "fuel" @@ -6,52 +6,53 @@ obj/effect/decal/cleanable/liquid_fuel anchored = 1 var/amount = 1 //Basically moles. - New(newLoc,amt=1) - src.amount = amt +/obj/effect/decal/cleanable/liquid_fuel/New(newLoc,amt=1) + amount = amt - //Be absorbed by any other liquid fuel in the tile. - for(var/obj/effect/decal/cleanable/liquid_fuel/other in newLoc) - if(other != src) - other.amount += src.amount - spawn other.Spread() - qdel(src) + //Be absorbed by any other liquid fuel in the tile. + for(var/obj/effect/decal/cleanable/liquid_fuel/other in newLoc) + if(other != src) + other.amount += amount + spawn other.Spread() + qdel(src) - Spread() - . = ..() + Spread() + . = ..() - proc/Spread() - //Allows liquid fuels to sometimes flow into other tiles. - if(amount < 0.5) return - var/turf/simulated/S = loc - if(!istype(S)) return - for(var/d in cardinal) - if(rand(25)) - var/turf/simulated/target = get_step(src,d) - var/turf/simulated/origin = get_turf(src) - if(origin.CanPass(null, target, 0, 0) && target.CanPass(null, origin, 0, 0)) - if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in target) - new/obj/effect/decal/cleanable/liquid_fuel(target, amount*0.25) - amount *= 0.75 +/obj/effect/decal/cleanable/liquid_fuel/proc/Spread() + //Allows liquid fuels to sometimes flow into other tiles. + if(amount < 0.5) return + var/turf/simulated/S = loc + if(!istype(S)) return + for(var/d in cardinal) + if(rand(25)) + var/turf/simulated/target = get_step(src, d) + var/turf/simulated/origin = get_turf(src) + if(origin.CanPass(null, target, 0, 0) && target.CanPass(null, origin, 0, 0)) + if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in target) + new/obj/effect/decal/cleanable/liquid_fuel(target, amount*0.25) + amount *= 0.75 - flamethrower_fuel - icon_state = "mustard" - anchored = 0 - New(newLoc, amt = 1, d = 0) - dir = d //Setting this direction means you won't get torched by your own flamethrower. - . = ..() +/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel + icon_state = "mustard" + anchored = 0 - Spread() - //The spread for flamethrower fuel is much more precise, to create a wide fire pattern. - if(amount < 0.1) return - var/turf/simulated/S = loc - if(!istype(S)) return +/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/New(newLoc, amt = 1, d = 0) + dir = d //Setting this direction means you won't get torched by your own flamethrower. + . = ..() - for(var/d in list(turn(dir,90),turn(dir,-90), dir)) - var/turf/simulated/O = get_step(S,d) - if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O) - continue - if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0)) - new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d) - O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately. +/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/Spread() + //The spread for flamethrower fuel is much more precise, to create a wide fire pattern. + if(amount < 0.1) return + var/turf/simulated/S = loc + if(!istype(S)) return - amount *= 0.25 + for(var/d in list(turn(dir,90),turn(dir,-90), dir)) + var/turf/simulated/O = get_step(S,d) + if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O) + continue + if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0)) + new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d) + O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately. + + amount *= 0.25 diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 4c70d0bfa09..ed322d99564 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -24,7 +24,7 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/New() ..() update_icon() - if(ticker && ticker.mode && istype(ticker.mode.name, "cult")) + if(GAMEMODE_IS_CULT) var/datum/game_mode/cult/mode_ticker = ticker.mode var/turf/T = get_turf(src) if(T && (is_station_level(T.z)))//F I V E T I L E S @@ -45,7 +45,7 @@ var/global/list/image/splatter_cache=list() dry() /obj/effect/decal/cleanable/blood/Destroy() - if(ticker.mode && istype(ticker.mode.name, "cult")) + if(GAMEMODE_IS_CULT) var/datum/game_mode/cult/mode_ticker = ticker.mode var/turf/T = get_turf(src) if(T && (is_station_level(T.z))) @@ -118,9 +118,12 @@ var/global/list/image/splatter_cache=list() user.update_inv_gloves(1) user.verbs += /mob/living/carbon/human/proc/bloody_doodle +/obj/effect/decal/cleanable/blood/can_bloodcrawl_in() + return TRUE + /obj/effect/decal/cleanable/blood/splatter - random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") - amount = 2 + random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") + amount = 2 /obj/effect/decal/cleanable/blood/drip name = "drips of blood" diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index 3c0a712a311..1b9880bb79a 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -89,15 +89,20 @@ /obj/effect/decal/cleanable/cobweb/fire_act() qdel(src) -/obj/effect/decal/cleanable/molten_item +/obj/effect/decal/cleanable/molten_object name = "gooey grey mass" desc = "It looks like a melted... something." density = 0 anchored = 1 layer = 3 - icon = 'icons/obj/chemical.dmi' + gender = NEUTER + icon = 'icons/effects/effects.dmi' icon_state = "molten" +/obj/effect/decal/cleanable/molten_object/large + name = "big gooey grey mass" + icon_state = "big_molten" + /obj/effect/decal/cleanable/cobweb2 name = "cobweb" desc = "Somebody should remove that." @@ -145,6 +150,15 @@ icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3") +/obj/effect/decal/cleanable/plant_smudge + name = "plant smudge" + density = 0 + anchored = 1 + layer = 2 + gender = NEUTER + icon = 'icons/effects/tomatodecal.dmi' + random_icon_states = list("smashed_plant") + /obj/effect/decal/cleanable/egg_smudge name = "smashed egg" desc = "Seems like this one won't hatch." @@ -163,16 +177,6 @@ icon = 'icons/effects/tomatodecal.dmi' random_icon_states = list("smashed_pie") -/obj/effect/decal/cleanable/fruit_smudge - name = "smudge" - desc = "Some kind of fruit smear." - density = 0 - anchored = 1 - layer = 2 - icon = 'icons/effects/blood.dmi' - icon_state = "mfloor1" - random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7") - /obj/effect/decal/cleanable/fungus name = "space fungus" desc = "A fungal growth. Looks pretty nasty." diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 16688932b9c..5fc09b6ec34 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -11,6 +11,9 @@ /obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like return + +/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in() + return FALSE /obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions) spawn (0) @@ -42,6 +45,9 @@ desc = "It's black and greasy. Looks like Beepsky made another mess." basecolor="#030303" +/obj/effect/decal/cleanable/blood/oil/can_bloodcrawl_in() + return FALSE + /obj/effect/decal/cleanable/blood/oil/dry() return diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0d6bf3255a5..48a85e7e704 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -3,6 +3,9 @@ var/targeted_by = null // Used so cleanbots can't claim a mess. var/noscoop = 0 //if it has this, don't let it be scooped up var/noclear = 0 //if it has this, don't delete it when its' scooped up + +/obj/effect/decal/cleanable/proc/can_bloodcrawl_in() + return FALSE /obj/effect/decal/cleanable/New() if(random_icon_states && length(src.random_icon_states) > 0) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 90e4c47b276..95ca2d4f4d8 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -425,21 +425,6 @@ steam.start() -- spawns the effect /obj/effect/effect/chem_smoke/Move() ..() - return - -// Spores -/datum/effect/system/chem_smoke_spread/spores - var/datum/seed/seed - -/datum/effect/system/chem_smoke_spread/spores/New(seed_name) - if(seed_name && plant_controller) - seed = plant_controller.seeds[seed_name] - if(!seed) - qdel(src) - ..() - - - /datum/effect/system/chem_smoke_spread/New() ..() chemholder = new/obj() @@ -517,13 +502,6 @@ steam.start() -- spawns the effect var/mob/living/carbon/C = A if(C.can_breathe_gas()) chemholder.reagents.copy_to(C, chemholder.reagents.total_volume) - if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = A - chemholder.reagents.copy_to(tray, chemholder.reagents.total_volume) - if(istype(A, /obj/effect/plant)) - var/obj/effect/plant/plant = A - if(chemholder.reagents.has_reagent("atrazine")) - plant.die_off() qdel(smokeholder) for(i=0, i 20) diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index ec77aa2e3a9..21ff80df749 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -2,32 +2,39 @@ /obj/effect/glowshroom name = "glowshroom" + desc = "Mycena Bregprox, a species of mushroom that glows in the dark." anchored = 1 opacity = 0 density = 0 icon = 'icons/obj/lighting.dmi' - icon_state = "glowshroomf" + icon_state = "glowshroom" //replaced in New layer = 2.1 var/endurance = 30 var/potency = 30 var/delay = 1200 var/floor = 0 var/yield = 3 - var/spreadChance = 40 + var/generation = 1 var/spreadIntoAdjacentChance = 60 - var/evolveChance = 2 - var/lastTick = 0 - var/spreaded = 1 + light_color = "#006622" + +obj/effect/glowshroom/glowcap + name = "glowcap" + icon_state = "glowcap" + light_color = "#8E0300" /obj/effect/glowshroom/single - spreadChance = 0 + yield = 0 + +/obj/effect/glowshroom/examine(mob/user) + . = ..() + to_chat(user, "This is a [generation]\th generation [name]!") /obj/effect/glowshroom/New() - ..() - + set_light(round(potency/10)) dir = CalcDir() - + var/base_icon_state = initial(icon_state) if(!floor) switch(dir) //offset to make it be on the wall rather than on the floor if(NORTH) @@ -38,70 +45,52 @@ pixel_x = 32 if(WEST) pixel_x = -32 - icon_state = "glowshroom[rand(1,3)]" + icon_state = "[base_icon_state][rand(1,3)]" else //if on the floor, glowshroom on-floor sprite - icon_state = "glowshroomf" + icon_state = "[base_icon_state]f" - processing_objects += src + addtimer(src, "Spread", delay) +/obj/effect/glowshroom/proc/Spread() + for(var/i = 1 to yield) + if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2... + var/list/possibleLocs = list() + var/spreadsIntoAdjacent = FALSE - set_light(round(potency/10)) - lastTick = world.timeofday + if(prob(spreadIntoAdjacentChance)) + spreadsIntoAdjacent = TRUE + for(var/turf/simulated/floor/earth in view(3,src)) + if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth)) + possibleLocs += earth + CHECK_TICK -/obj/effect/glowshroom/Destroy() - processing_objects -= src - return ..() + if(!possibleLocs.len) + break -/obj/effect/glowshroom/process() - if(!spreaded) - return + var/turf/newLoc = pick(possibleLocs) - if(((world.timeofday - lastTick) > delay) || ((world.timeofday - lastTick) < 0)) - lastTick = world.timeofday - spreaded = 0 + var/shroomCount = 0 //hacky + var/placeCount = 1 + for(var/obj/effect/glowshroom/shroom in newLoc) + shroomCount++ + for(var/wallDir in cardinal) + var/turf/isWall = get_step(newLoc,wallDir) + if(isWall.density) + placeCount++ + if(shroomCount >= placeCount) + continue - for(var/i=1,i<=yield,i++) - if(prob(spreadChance)) - var/list/possibleLocs = list() - var/spreadsIntoAdjacent = 0 + var/obj/effect/glowshroom/child = new type(newLoc)//The baby mushrooms have different stats :3 + child.potency = max(potency + rand(-3,6), 0) + child.yield = max(yield + rand(-1,2), 0) + child.delay = max(delay + rand(-30,60), 0) + child.endurance = max(endurance + rand(-3,6), 1) + child.generation = generation + 1 - if(prob(spreadIntoAdjacentChance)) - spreadsIntoAdjacent = 1 - - for(var/turf/simulated/floor/plating/airless/asteroid/earth in view(3,src)) - if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth)) - possibleLocs += earth - - if(!possibleLocs.len) - break - - var/turf/newLoc = pick(possibleLocs) - - var/shroomCount = 0 //hacky - var/placeCount = 1 - for(var/obj/effect/glowshroom/shroom in newLoc) - shroomCount++ - for(var/wallDir in cardinal) - var/turf/isWall = get_step(newLoc,wallDir) - if(isWall.density) - placeCount++ - if(shroomCount >= placeCount) - continue - - var/obj/effect/glowshroom/child = new /obj/effect/glowshroom(newLoc) - child.potency = potency - child.yield = yield - child.delay = delay - child.endurance = endurance - - spreaded++ - - if(prob(evolveChance)) //very low chance to evolve on its own - potency += rand(4,6) + CHECK_TICK /obj/effect/glowshroom/proc/CalcDir(turf/location = loc) - //set background = 1 var/direction = 16 for(var/wallDir in cardinal) @@ -133,28 +122,22 @@ floor = 1 return 1 -/obj/effect/glowshroom/attackby(obj/item/weapon/W as obj, mob/user as mob, params) +/obj/effect/glowshroom/attackby(obj/item/I, mob/user) ..() - - endurance -= W.force - - CheckEndurance() + if(I.damtype != STAMINA) + endurance -= I.force + CheckEndurance() /obj/effect/glowshroom/ex_act(severity) switch(severity) - if(1.0) + if(1) qdel(src) - return - if(2.0) + if(2) if(prob(50)) qdel(src) - return - if(3.0) + if(3) if(prob(5)) qdel(src) - return - else - return /obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > 300) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index f46810486ca..7ff80f248da 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -1,252 +1,267 @@ -/obj/effect/landmark - name = "landmark" - icon = 'icons/mob/screen_gen.dmi' - icon_state = "x2" - anchored = 1.0 - unacidable = 1 - -/obj/effect/landmark/New() - - ..() - set_tag() - invisibility = 101 - - switch(name) //some of these are probably obsolete - if("start") - newplayer_start += loc - qdel(src) - - if("wizard") - wizardstart += loc - qdel(src) - - if("JoinLate") - latejoin += loc - qdel(src) - - if("JoinLateGateway") - latejoin_gateway += loc - qdel(src) - - if("JoinLateCryo") - latejoin_cryo += loc - qdel(src) - - if("JoinLateCyborg") - latejoin_cyborg += loc - qdel(src) - - if("prisonwarp") - prisonwarp += loc - qdel(src) +/obj/effect/landmark + name = "landmark" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "x2" + anchored = 1.0 + unacidable = 1 - if("prisonsecuritywarp") - prisonsecuritywarp += loc - qdel(src) +/obj/effect/landmark/New() - if("tdome1") - tdome1 += loc + ..() + set_tag() + invisibility = 101 - if("tdome2") - tdome2 += loc + switch(name) //some of these are probably obsolete + if("start") + newplayer_start += loc + qdel(src) - if("tdomeadmin") - tdomeadmin += loc + if("wizard") + wizardstart += loc + qdel(src) - if("tdomeobserve") - tdomeobserve += loc + if("JoinLate") + latejoin += loc + qdel(src) - if("aroomwarp") - aroomwarp += loc - - if("blobstart") - blobstart += loc - qdel(src) - - if("xeno_spawn") - xeno_spawn += loc - qdel(src) - - if("ninjastart") - ninjastart += loc - qdel(src) - - if("carpspawn") - carplist += loc - - if("voxstart") - raider_spawn += loc - - if("ERT Director") - ertdirector += loc - qdel(src) + if("JoinLateGateway") + latejoin_gateway += loc + qdel(src) - if("Response Team") - emergencyresponseteamspawn += loc - qdel(src) - - landmarks_list += src - return 1 - -/obj/effect/landmark/Destroy() - landmarks_list -= src - ..() - return QDEL_HINT_HARDDEL_NOW - -/obj/effect/landmark/proc/set_tag() - tag = text("landmark*[]", name) - - -/obj/effect/landmark/start - name = "start" - icon = 'icons/mob/screen_gen.dmi' - icon_state = "x" - anchored = 1.0 - -/obj/effect/landmark/start/set_tag() - tag = "start*[name]" - - -//Costume spawner landmarks - -/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears - - var/list/options = typesof(/obj/effect/landmark/costume) - var/PICK= options[rand(1,options.len)] - new PICK(src.loc) - qdel(src) - -//SUBCLASSES. Spawn a bunch of items and disappear likewise -/obj/effect/landmark/costume/chicken/New() - new /obj/item/clothing/suit/chickensuit(src.loc) - new /obj/item/clothing/head/chicken(src.loc) - new /obj/item/weapon/reagent_containers/food/snacks/egg(src.loc) - qdel(src) - -/obj/effect/landmark/costume/gladiator/New() - new /obj/item/clothing/under/gladiator(src.loc) - new /obj/item/clothing/head/helmet/gladiator(src.loc) - qdel(src) - -/obj/effect/landmark/costume/madscientist/New() - new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc) - new /obj/item/clothing/head/flatcap(src.loc) - new /obj/item/clothing/suit/storage/labcoat/mad(src.loc) - new /obj/item/clothing/glasses/gglasses(src.loc) - qdel(src) - -/obj/effect/landmark/costume/elpresidente/New() - new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc) - new /obj/item/clothing/head/flatcap(src.loc) - new /obj/item/clothing/mask/cigarette/cigar/havana(src.loc) - new /obj/item/clothing/shoes/jackboots(src.loc) - qdel(src) - -/obj/effect/landmark/costume/nyangirl/New() - new /obj/item/clothing/under/schoolgirl(src.loc) - new /obj/item/clothing/head/kitty(src.loc) - qdel(src) - -/obj/effect/landmark/costume/maid/New() - new /obj/item/clothing/under/blackskirt(src.loc) - var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears ) - new CHOICE(src.loc) - new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc) - qdel(src) - -/obj/effect/landmark/costume/butler/New() - new /obj/item/clothing/suit/wcoat(src.loc) - new /obj/item/clothing/under/suit_jacket(src.loc) - new /obj/item/clothing/head/that(src.loc) - qdel(src) - -/obj/effect/landmark/costume/scratch/New() - new /obj/item/clothing/gloves/color/white(src.loc) - new /obj/item/clothing/shoes/white(src.loc) - new /obj/item/clothing/under/scratch(src.loc) - if(prob(30)) - new /obj/item/clothing/head/cueball(src.loc) - qdel(src) - -/obj/effect/landmark/costume/highlander/New() - new /obj/item/clothing/under/kilt(src.loc) - new /obj/item/clothing/head/beret(src.loc) - qdel(src) - -/obj/effect/landmark/costume/prig/New() - new /obj/item/clothing/suit/wcoat(src.loc) - new /obj/item/clothing/glasses/monocle(src.loc) - var/CHOICE= pick( /obj/item/clothing/head/bowlerhat, /obj/item/clothing/head/that) - new CHOICE(src.loc) - new /obj/item/clothing/shoes/black(src.loc) - new /obj/item/weapon/cane(src.loc) - new /obj/item/clothing/under/sl_suit(src.loc) - new /obj/item/clothing/mask/fakemoustache(src.loc) - qdel(src) - -/obj/effect/landmark/costume/plaguedoctor/New() - new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc) - new /obj/item/clothing/head/plaguedoctorhat(src.loc) - qdel(src) - -/obj/effect/landmark/costume/nightowl/New() - new /obj/item/clothing/under/owl(src.loc) - new /obj/item/clothing/mask/gas/owl_mask(src.loc) - qdel(src) - -/obj/effect/landmark/costume/waiter/New() - new /obj/item/clothing/under/waiter(src.loc) - var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears) - new CHOICE(src.loc) - new /obj/item/clothing/suit/apron(src.loc) - qdel(src) - -/obj/effect/landmark/costume/pirate/New() - new /obj/item/clothing/under/pirate(src.loc) - new /obj/item/clothing/suit/pirate_black(src.loc) - var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana ) - new CHOICE(src.loc) - new /obj/item/clothing/glasses/eyepatch(src.loc) - qdel(src) - -/obj/effect/landmark/costume/commie/New() - new /obj/item/clothing/under/soviet(src.loc) - new /obj/item/clothing/head/ushanka(src.loc) - qdel(src) - -/obj/effect/landmark/costume/imperium_monk/New() - new /obj/item/clothing/suit/imperium_monk(src.loc) - if(prob(25)) - new /obj/item/clothing/mask/gas/cyborg(src.loc) - qdel(src) - -/obj/effect/landmark/costume/holiday_priest/New() - new /obj/item/clothing/suit/holidaypriest(src.loc) - qdel(src) - -/obj/effect/landmark/costume/marisawizard/fake/New() - new /obj/item/clothing/head/wizard/marisa/fake(src.loc) - new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc) - qdel(src) - -/obj/effect/landmark/costume/cutewitch/New() - new /obj/item/clothing/under/sundress(src.loc) - new /obj/item/clothing/head/witchwig(src.loc) - new /obj/item/weapon/twohanded/staff/broom(src.loc) - qdel(src) - -/obj/effect/landmark/costume/fakewizard/New() - new /obj/item/clothing/suit/wizrobe/fake(src.loc) - new /obj/item/clothing/head/wizard/fake(src.loc) - new /obj/item/weapon/twohanded/staff/(src.loc) - qdel(src) - -/obj/effect/landmark/costume/sexyclown/New() - new /obj/item/clothing/mask/gas/sexyclown(src.loc) - new /obj/item/clothing/under/sexyclown(src.loc) - qdel(src) - -/obj/effect/landmark/costume/sexymime/New() - new /obj/item/clothing/mask/gas/sexymime(src.loc) - new /obj/item/clothing/under/sexymime(src.loc) - qdel(src) + if("JoinLateCryo") + latejoin_cryo += loc + qdel(src) + + if("JoinLateCyborg") + latejoin_cyborg += loc + qdel(src) + + if("prisonwarp") + prisonwarp += loc + qdel(src) + + if("prisonsecuritywarp") + prisonsecuritywarp += loc + qdel(src) + + if("tdome1") + tdome1 += loc + + if("tdome2") + tdome2 += loc + + if("tdomeadmin") + tdomeadmin += loc + + if("tdomeobserve") + tdomeobserve += loc + + if("aroomwarp") + aroomwarp += loc + + if("blobstart") + blobstart += loc + qdel(src) + + if("xeno_spawn") + xeno_spawn += loc + qdel(src) + + if("ninjastart") + ninjastart += loc + qdel(src) + + if("carpspawn") + carplist += loc + + if("voxstart") + raider_spawn += loc + + if("ERT Director") + ertdirector += loc + qdel(src) + + if("Response Team") + emergencyresponseteamspawn += loc + qdel(src) + + landmarks_list += src + return 1 + +/obj/effect/landmark/Destroy() + landmarks_list -= src + ..() + return QDEL_HINT_HARDDEL_NOW + +/obj/effect/landmark/proc/set_tag() + tag = text("landmark*[]", name) + + +/obj/effect/landmark/start + name = "start" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "x" + anchored = 1.0 + +/obj/effect/landmark/start/set_tag() + tag = "start*[name]" + + +//Costume spawner landmarks + +/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears + + var/list/options = typesof(/obj/effect/landmark/costume) + var/PICK= options[rand(1,options.len)] + new PICK(src.loc) + qdel(src) + +//SUBCLASSES. Spawn a bunch of items and disappear likewise +/obj/effect/landmark/costume/chicken/New() + new /obj/item/clothing/suit/chickensuit(src.loc) + new /obj/item/clothing/head/chicken(src.loc) + new /obj/item/weapon/reagent_containers/food/snacks/egg(src.loc) + qdel(src) + +/obj/effect/landmark/costume/gladiator/New() + new /obj/item/clothing/under/gladiator(src.loc) + new /obj/item/clothing/head/helmet/gladiator(src.loc) + qdel(src) + +/obj/effect/landmark/costume/madscientist/New() + new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc) + new /obj/item/clothing/head/flatcap(src.loc) + new /obj/item/clothing/suit/storage/labcoat/mad(src.loc) + new /obj/item/clothing/glasses/gglasses(src.loc) + qdel(src) + +/obj/effect/landmark/costume/elpresidente/New() + new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc) + new /obj/item/clothing/head/flatcap(src.loc) + new /obj/item/clothing/mask/cigarette/cigar/havana(src.loc) + new /obj/item/clothing/shoes/jackboots(src.loc) + qdel(src) + +/obj/effect/landmark/costume/nyangirl/New() + new /obj/item/clothing/under/schoolgirl(src.loc) + new /obj/item/clothing/head/kitty(src.loc) + qdel(src) + +/obj/effect/landmark/costume/maid/New() + new /obj/item/clothing/under/blackskirt(src.loc) + var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears ) + new CHOICE(src.loc) + new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc) + qdel(src) + +/obj/effect/landmark/costume/butler/New() + new /obj/item/clothing/suit/wcoat(src.loc) + new /obj/item/clothing/under/suit_jacket(src.loc) + new /obj/item/clothing/head/that(src.loc) + qdel(src) + +/obj/effect/landmark/costume/scratch/New() + new /obj/item/clothing/gloves/color/white(src.loc) + new /obj/item/clothing/shoes/white(src.loc) + new /obj/item/clothing/under/scratch(src.loc) + if(prob(30)) + new /obj/item/clothing/head/cueball(src.loc) + qdel(src) + +/obj/effect/landmark/costume/highlander/New() + new /obj/item/clothing/under/kilt(src.loc) + new /obj/item/clothing/head/beret(src.loc) + qdel(src) + +/obj/effect/landmark/costume/prig/New() + new /obj/item/clothing/suit/wcoat(src.loc) + new /obj/item/clothing/glasses/monocle(src.loc) + var/CHOICE= pick( /obj/item/clothing/head/bowlerhat, /obj/item/clothing/head/that) + new CHOICE(src.loc) + new /obj/item/clothing/shoes/black(src.loc) + new /obj/item/weapon/cane(src.loc) + new /obj/item/clothing/under/sl_suit(src.loc) + new /obj/item/clothing/mask/fakemoustache(src.loc) + qdel(src) + +/obj/effect/landmark/costume/plaguedoctor/New() + new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc) + new /obj/item/clothing/head/plaguedoctorhat(src.loc) + qdel(src) + +/obj/effect/landmark/costume/nightowl/New() + new /obj/item/clothing/under/owl(src.loc) + new /obj/item/clothing/mask/gas/owl_mask(src.loc) + qdel(src) + +/obj/effect/landmark/costume/waiter/New() + new /obj/item/clothing/under/waiter(src.loc) + var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears) + new CHOICE(src.loc) + new /obj/item/clothing/suit/apron(src.loc) + qdel(src) + +/obj/effect/landmark/costume/pirate/New() + new /obj/item/clothing/under/pirate(src.loc) + new /obj/item/clothing/suit/pirate_black(src.loc) + var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana ) + new CHOICE(src.loc) + new /obj/item/clothing/glasses/eyepatch(src.loc) + qdel(src) + +/obj/effect/landmark/costume/commie/New() + new /obj/item/clothing/under/soviet(src.loc) + new /obj/item/clothing/head/ushanka(src.loc) + qdel(src) + + +/obj/effect/landmark/costume/imperium_monk/New() + new /obj/item/clothing/suit/imperium_monk(src.loc) + if(prob(25)) + new /obj/item/clothing/mask/gas/cyborg(src.loc) + qdel(src) + +/obj/effect/landmark/costume/holiday_priest/New() + new /obj/item/clothing/suit/holidaypriest(src.loc) + qdel(src) + +/obj/effect/landmark/costume/marisawizard/fake/New() + new /obj/item/clothing/head/wizard/marisa/fake(src.loc) + new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc) + qdel(src) + +/obj/effect/landmark/costume/cutewitch/New() + new /obj/item/clothing/under/sundress(src.loc) + new /obj/item/clothing/head/witchwig(src.loc) + new /obj/item/weapon/twohanded/staff/broom(src.loc) + qdel(src) + +/obj/effect/landmark/costume/fakewizard/New() + new /obj/item/clothing/suit/wizrobe/fake(src.loc) + new /obj/item/clothing/head/wizard/fake(src.loc) + new /obj/item/weapon/twohanded/staff/(src.loc) + qdel(src) + +/obj/effect/landmark/costume/sexyclown/New() + new /obj/item/clothing/mask/gas/sexyclown(src.loc) + new /obj/item/clothing/under/sexyclown(src.loc) + qdel(src) + +/obj/effect/landmark/costume/sexymime/New() + new /obj/item/clothing/mask/gas/sexymime(src.loc) + new /obj/item/clothing/under/sexymime(src.loc) + qdel(src) + +/obj/effect/landmark/ruin + var/datum/map_template/ruin/ruin_template + +/obj/effect/landmark/ruin/New(loc, my_ruin_template) + name = "ruin_[ruin_landmarks.len + 1]" + ..(loc) + ruin_template = my_ruin_template + ruin_landmarks |= src + +/obj/effect/landmark/ruin/Destroy() + ruin_landmarks -= src + ruin_template = null + . = ..() diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index c9cb0c62eab..c3facb6ccbe 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -1,94 +1,168 @@ /obj/effect/mine - name = "Mine" + name = "dummy mine" desc = "I Better stay away from that thing." - density = 1 + density = 0 anchored = 1 - layer = 3 icon = 'icons/obj/weapons.dmi' - icon_state = "uglymine" - var/triggerproc = "explode" //name of the proc thats called when the mine is triggered + icon_state = "uglyminearmed" var/triggered = 0 -/obj/effect/mine/New() - icon_state = "uglyminearmed" +/obj/effect/mine/proc/mineEffect(mob/living/victim) + to_chat(victim, "*click*") /obj/effect/mine/Crossed(AM as mob|obj) - Bumped(AM) + if(!isliving(AM)) + return + if(isanimal(AM)) + var/mob/living/simple_animal/SA = AM + if(!SA.flying) + triggermine(SA) + else + triggermine(AM) -/obj/effect/mine/Bumped(mob/M as mob|obj) - - if(triggered) return - - if(istype(M, /mob/living/carbon/human)) - for(var/mob/O in viewers(world.view, src.loc)) - to_chat(O, "[M] triggered the [bicon(src)] [src]") - triggered = 1 - call(src,triggerproc)(M) - -/obj/effect/mine/proc/triggerrad(obj) +/obj/effect/mine/proc/triggermine(mob/living/victim) + if(triggered) + return + visible_message("[victim] sets off \icon[src] [src]!") var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() - obj:radiation += 50 - randmutb(obj) - domutcheck(obj,null) - spawn(0) - qdel(src) + mineEffect(victim) + triggered = 1 + qdel(src) -/obj/effect/mine/proc/triggerstun(obj) - if(ismob(obj)) - var/mob/M = obj - M.Stun(30) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - spawn(0) - qdel(src) +/obj/effect/mine/explosive + name = "explosive mine" + var/range_devastation = 0 + var/range_heavy = 1 + var/range_light = 2 + var/range_flash = 3 -/obj/effect/mine/proc/triggern2o(obj) - atmos_spawn_air(SPAWN_N2O, 360) - spawn(0) - qdel(src) +/obj/effect/mine/explosive/mineEffect(mob/living/victim) + explosion(loc, range_devastation, range_heavy, range_light, range_flash) -/obj/effect/mine/proc/triggerplasma(obj) - atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 360) - spawn(0) - qdel(src) +/obj/effect/mine/stun + name = "stun mine" + var/stun_time = 8 -/obj/effect/mine/proc/triggerkick(obj) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - qdel(obj:client) - spawn(0) - qdel(src) - -/obj/effect/mine/proc/explode(obj) - explosion(loc, 0, 1, 2, 3) - spawn(0) - qdel(src) +/obj/effect/mine/stun/mineEffect(mob/living/victim) + if(isliving(victim)) + victim.Weaken(stun_time) /obj/effect/mine/dnascramble name = "Radiation Mine" - icon_state = "uglymine" - triggerproc = "triggerrad" + var/radiation_amount -/obj/effect/mine/plasma - name = "Plasma Mine" - icon_state = "uglymine" - triggerproc = "triggerplasma" +/obj/effect/mine/dnascramble/mineEffect(mob/living/victim) + victim.apply_effect(radiation_amount, IRRADIATE, 0) + randmutb(victim) + domutcheck(victim ,null) -/obj/effect/mine/kick - name = "Kick Mine" - icon_state = "uglymine" - triggerproc = "triggerkick" +/obj/effect/mine/gas + name = "oxygen mine" + var/gas_amount = 360 + var/gas_type = SPAWN_OXYGEN -/obj/effect/mine/n2o - name = "N2O Mine" - icon_state = "uglymine" - triggerproc = "triggern2o" +/obj/effect/mine/gas/mineEffect(mob/living/victim) + atmos_spawn_air(gas_type, gas_amount) -/obj/effect/mine/stun - name = "Stun Mine" - icon_state = "uglymine" - triggerproc = "triggerstun" +/obj/effect/mine/gas/plasma + name = "plasma mine" + gas_type = SPAWN_HEAT | SPAWN_TOXINS + +/obj/effect/mine/gas/n2o + name = "\improper N2O mine" + gas_type = SPAWN_N2O + +/obj/effect/mine/sound + name = "honkblaster 1000" + var/sound = 'sound/items/bikehorn.ogg' + +/obj/effect/mine/sound/mineEffect(mob/living/victim) + playsound(loc, sound, 100, 1) + +/obj/effect/mine/sound/bwoink + name = "bwoink mine" + sound = 'sound/effects/adminhelp.ogg' + +/obj/effect/mine/pickup + name = "pickup" + desc = "pick me up" + icon = 'icons/effects/effects.dmi' + icon_state = "electricity2" + density = 0 + var/duration = 0 + +/obj/effect/mine/pickup/New() + ..() + animate(src, pixel_y = 4, time = 20, loop = -1) + +/obj/effect/mine/pickup/triggermine(mob/living/victim) + if(triggered) + return + triggered = 1 + invisibility = 101 + mineEffect(victim) + qdel(src) + +/obj/effect/mine/pickup/bloodbath + name = "Red Orb" + desc = "You feel angry just looking at it." + duration = 1200 //2min + color = "red" + +/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim) + if(!istype(victim) || !victim.client) + return + to_chat(victim, "RIP AND TEAR") + victim << 'sound/misc/e1m1.ogg' + var/old_color = victim.client.color + var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0) + var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0) + + spawn(0) + new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0) + + var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc) + chainsaw.flags |= NODROP + victim.drop_l_hand() + victim.drop_r_hand() + victim.put_in_hands(chainsaw) + chainsaw.attack_self(victim) + chainsaw.wield(victim) + victim.reagents.add_reagent("adminordrazine", 25) + + victim.client.color = pure_red + animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT) + spawn(10) + animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT) + spawn(duration) + to_chat(victim, "Your bloodlust seeps back into the bog of your subconscious and you regain self control.") + qdel(chainsaw) + qdel(src) + +/obj/effect/mine/pickup/healing + name = "Blue Orb" + desc = "You feel better just looking at it." + color = "blue" + +/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim) + if(!victim.client || !istype(victim)) + return + to_chat(victim, "You feel great!") + victim.revive() + +/obj/effect/mine/pickup/speed + name = "Yellow Orb" + desc = "You feel faster just looking at it." + color = "yellow" + duration = 300 + +/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim) + if(!victim.client || !istype(victim)) + return + to_chat(victim, "You feel fast!") + victim.status_flags |= GOTTAGOREALLYFAST + spawn(duration) + victim.status_flags &= ~GOTTAGOREALLYFAST + to_chat(victim, "You slow down.") \ No newline at end of file diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 94967f60c95..0bb6278c0bc 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -1,4 +1,3 @@ - /obj/effect/overlay name = "overlay" unacidable = 1 @@ -17,60 +16,9 @@ var/tmp/atom/BeamSource New() ..() - spawn(10) qdel(src) - - -/obj/effect/overlay/temp - anchored = 1 - layer = 4.1 - mouse_opacity = 0 - var/duration = 10 - var/randomdir = 1 - -/obj/effect/overlay/temp/New() - if(randomdir) - dir = pick(cardinal) - spawn(duration) - qdel(src) - -/obj/effect/overlay/temp/revenant - name = "spooky lights" - icon = 'icons/effects/effects.dmi' - icon_state = "purplesparkles" - -/obj/effect/overlay/temp/revenant/cracks - name = "glowing cracks" - icon_state = "purplecrack" - duration = 6 - -/obj/effect/overlay/temp/guardian - randomdir = 0 - -/obj/effect/overlay/temp/guardian/phase - duration = 5 - icon_state = "phasein" - -/obj/effect/overlay/temp/guardian/phase/out - icon_state = "phaseout" - -/obj/effect/overlay/temp/emp - name = "emp sparks" - icon = 'icons/effects/effects.dmi' - icon_state = "empdisable" - -/obj/effect/overlay/temp/emp/pulse - name = "emp pulse" - icon_state = "emp pulse" - duration = 8 - randomdir = 0 - -/obj/effect/overlay/temp/kinetic_blast - name = "kinetic explosion" - icon = 'icons/obj/projectiles.dmi' - icon_state = "kinetic_blast" - layer = 4.1 - duration = 4 - + spawn(10) + qdel(src) + /obj/effect/overlay/palmtree_r name = "Palm tree" icon = 'icons/misc/beach2.dmi' @@ -98,6 +46,164 @@ icon_state = "admin" layer = 4.1 +/obj/effect/overlay/temp + anchored = 1 + layer = 4.1 + mouse_opacity = 0 + var/duration = 10 + var/randomdir = 1 + +/obj/effect/overlay/temp/New() + if(randomdir) + dir = pick(cardinal) + + flick("[icon_state]", src) //Because we might be pulling it from a pool, flick whatever icon it uses so it starts at the start of the icon's animation. + + spawn(duration) + qdel(src) + +/obj/effect/overlay/temp/revenant + name = "spooky lights" + icon = 'icons/effects/effects.dmi' + icon_state = "purplesparkles" + +/obj/effect/overlay/temp/revenant/cracks + name = "glowing cracks" + icon_state = "purplecrack" + duration = 6 + +/obj/effect/overlay/temp/guardian + randomdir = 0 + +/obj/effect/overlay/temp/guardian/phase + duration = 5 + icon_state = "phasein" + +/obj/effect/overlay/temp/guardian/phase/out + icon_state = "phaseout" + +/obj/effect/overlay/temp/emp + name = "emp sparks" + icon = 'icons/effects/effects.dmi' + icon_state = "empdisable" + +/obj/effect/overlay/temp/emp/pulse + name = "emp pulse" + icon_state = "emppulse" + duration = 8 + randomdir = 0 + +/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed + name = "healing glow" + icon = 'icons/effects/effects.dmi' + icon_state = "heal" + duration = 15 + +/obj/effect/overlay/temp/heal/New(loc, colour) + ..() + pixel_x = rand(-12, 12) + pixel_y = rand(-9, 0) + if(colour) + color = colour + +/obj/effect/overlay/temp/kinetic_blast + name = "kinetic explosion" + icon = 'icons/obj/projectiles.dmi' + icon_state = "kinetic_blast" + layer = 4.1 + duration = 4 + +/obj/effect/overlay/temp/explosion + name = "explosion" + icon = 'icons/effects/96x96.dmi' + icon_state = "explosion" + pixel_x = -32 + pixel_y = -32 + duration = 8 + +/obj/effect/overlay/temp/explosion/fast + icon_state = "explosionfast" + duration = 4 + +/obj/effect/overlay/temp/decoy + desc = "It's a decoy!" + duration = 15 + +/obj/effect/overlay/temp/decoy/New(loc, atom/mimiced_atom) + ..() + alpha = initial(alpha) + if(mimiced_atom) + name = mimiced_atom.name + appearance = mimiced_atom.appearance + dir = mimiced_atom.dir + mouse_opacity = 0 + +/obj/effect/overlay/temp/decoy/fading/New(loc, atom/mimiced_atom) + ..() + animate(src, alpha = 0, time = duration) + +/obj/effect/overlay/temp/cult + icon = 'icons/effects/effects.dmi' + randomdir = 0 + duration = 10 + +/obj/effect/overlay/temp/cult/sparks + randomdir = 1 + name = "blood sparks" + icon_state = "bloodsparkles" + +/obj/effect/overlay/temp/dir_setting + randomdir = FALSE + +/obj/effect/overlay/temp/dir_setting/New(loc, set_dir) + if(set_dir) + dir = set_dir + ..() + +/obj/effect/overlay/temp/dir_setting/bloodsplatter + icon = 'icons/effects/blood.dmi' + duration = 5 + randomdir = FALSE + layer = MOB_LAYER - 0.1 + var/splatter_type = "splatter" + +/obj/effect/overlay/temp/dir_setting/bloodsplatter/New(loc, set_dir) + if(set_dir in diagonals) + icon_state = "[splatter_type][pick(1, 2, 6)]" + else + icon_state = "[splatter_type][pick(3, 4, 5)]" + ..() + var/target_pixel_x = 0 + var/target_pixel_y = 0 + switch(set_dir) + if(NORTH) + target_pixel_y = 16 + if(SOUTH) + target_pixel_y = -16 + layer = MOB_LAYER + 0.1 + if(EAST) + target_pixel_x = 16 + if(WEST) + target_pixel_x = -16 + if(NORTHEAST) + target_pixel_x = 16 + target_pixel_y = 16 + if(NORTHWEST) + target_pixel_x = -16 + target_pixel_y = 16 + if(SOUTHEAST) + target_pixel_x = 16 + target_pixel_y = -16 + layer = MOB_LAYER + 0.1 + if(SOUTHWEST) + target_pixel_x = -16 + target_pixel_y = -16 + layer = MOB_LAYER + 0.1 + animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration) + +/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter + splatter_type = "xsplatter" + /obj/effect/overlay/wall_rot name = "Wallrot" desc = "Ick..." diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 0293231c60e..b9804e7d9a5 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -103,8 +103,8 @@ /obj/item/weapon/hand_labeler = 10, /obj/item/weapon/paper/crumpled = 10, /obj/item/weapon/pen = 10, - /obj/item/weapon/minihoe = 10, - /obj/item/weapon/plantspray/pests = 10, + /obj/item/weapon/cultivator = 10, + /obj/item/weapon/reagent_containers/spray/pestspray = 10, /obj/item/weapon/stock_parts/cell = 30, /obj/item/weapon/storage/belt/utility = 20, /obj/item/weapon/storage/box = 20, @@ -122,13 +122,13 @@ /obj/item/weapon/wrench = 40, /obj/item/weapon/relic = 35, /obj/item/clothing/shoes/brown = 30, - /obj/item/seeds/ambrosiadeusseed = 10, - /obj/item/seeds/ambrosiavulgarisseed = 20, + /obj/item/seeds/ambrosia/deus = 10, + /obj/item/seeds/ambrosia = 20, /obj/item/clothing/under/color/black = 30, /obj/item/stack/tape_roll = 10, ////////////////CONTRABAND STUFF////////////////// /obj/item/weapon/grenade/clown_grenade = 3, - /obj/item/seeds/ambrosiavulgarisseed/cruciatus = 3, + /obj/item/seeds/ambrosia/cruciatus = 3, /obj/item/weapon/gun/projectile/automatic/pistol/empty = 1, /obj/item/ammo_box/magazine/m10mm = 4, /obj/item/weapon/soap/syndie = 7, @@ -194,6 +194,6 @@ /obj/item/weapon/stock_parts/scanning_module = 1, /obj/item/weapon/spacecash/c200 = 1, /obj/item/weapon/airlock_electronics = 1, - /obj/item/weapon/gun/energy/kinetic_accelerator/super = 1, + /obj/item/weapon/gun/energy/kinetic_accelerator = 1, /obj/item/pizzabox = 3, ) diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 9d1fb75d25e..8443ac90f17 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -201,7 +201,7 @@ if(player_spiders && !selecting_player) selecting_player = 1 spawn() - var/list/candidates = pollCandidates("Do you want to play as a spider?", ROLE_ALIEN, 1) + var/list/candidates = pollCandidates("Do you want to play as a spider?", ROLE_GSPIDER, 1) if(candidates.len) var/mob/C = pick(candidates) diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 198c6ce45aa..3cc0f9b6023 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -53,7 +53,7 @@ By submitting this form, you accept any fines, fees, or personal injury/death that may occur during construction." w_class = 1 -/obj/item/areaeditor/permit/attack_self(mob/user as mob) +/obj/item/areaeditor/permit/attack_self(mob/user) . = ..() var/area/A = get_area() if(get_area_type() == AREA_STATION) @@ -85,7 +85,7 @@ return ..() -/obj/item/areaeditor/blueprints/attack_self(mob/user as mob) +/obj/item/areaeditor/blueprints/attack_self(mob/user) . = ..() var/area/A = get_area() if(get_area_type() == AREA_STATION) @@ -153,7 +153,7 @@ /obj/item/areaeditor/proc/get_area_type(var/area/A = get_area()) - if(istype(A,/area/space)) + if(A.outdoors) return AREA_SPACE var/list/SPECIALS = list( /area/shuttle, @@ -305,3 +305,10 @@ return ROOM_ERR_SPACE found+=T return found + +//Blueprint Subtypes + +/obj/item/areaeditor/blueprints/cyborg + name = "station schematics" + desc = "A digital copy of the station blueprints stored in your memory." + fluffnotice = "Intellectual Property of Nanotrasen. For use in engineering cyborgs only. Wipe from memory upon departure from the station." diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 065392a9222..d805105a906 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -87,7 +87,8 @@ temp = "graffiti" to_chat(user, "You start drawing a [temp] on the [target.name].") if(instant || do_after(user, 50, target = target)) - new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp) + var/obj/effect/decal/cleanable/crayon/C = new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp) + C.add_hiddenprint(user) to_chat(user, "You finish drawing [temp].") if(uses) uses-- diff --git a/code/game/objects/items/devices/debugger.dm b/code/game/objects/items/devices/debugger.dm deleted file mode 100644 index 0984b437155..00000000000 --- a/code/game/objects/items/devices/debugger.dm +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Multitool -- A multitool is used for hacking electronic devices. - * TO-DO -- Using it as a power measurement tool for cables etc. Nannek. - * - */ - -/obj/item/device/debugger - icon = 'icons/obj/hacktool.dmi' - name = "debugger" - desc = "Used to debug electronic equipment." - icon_state = "hacktool-g" - flags = CONDUCT - force = 5.0 - w_class = 2 - throwforce = 5.0 - throw_range = 15 - throw_speed = 3 - desc = "You can use this on airlocks or APCs to try to hack them without cutting wires." - materials = list(MAT_METAL=50, MAT_GLASS=20) - origin_tech = "magnets=1;engineering=1" - var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage - -/obj/item/device/debugger/is_used_on(obj/O, mob/user) - if(istype(O, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = O - if(A.emagged || A.malfhack) - to_chat(user, "\red There is a software error with the device.") - else - to_chat(user, "\blue The device's software appears to be fine.") - return 1 - if(istype(O, /obj/machinery/door)) - var/obj/machinery/door/D = O - if(D.operating == -1) - to_chat(user, "\red There is a software error with the device.") - else - to_chat(user, "\blue The device's software appears to be fine.") - return 1 - else if(istype(O, /obj/machinery)) - var/obj/machinery/A = O - if(A.emagged) - to_chat(user, "\red There is a software error with the device.") - else - to_chat(user, "\blue The device's software appears to be fine.") - return 1 \ No newline at end of file diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 7806982a627..216c37e7a51 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -54,8 +54,8 @@ return var/mob/living/carbon/human/H = M //mob has protective eyewear - if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) - to_chat(user, "You're going to need to remove that [(H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask": "glasses"] first.") + if(istype(H) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES))) + to_chat(user, "You're going to need to remove that [(H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask" : "glasses"] first.") return if(M == user) //they're using it on themselves @@ -70,12 +70,13 @@ user.visible_message("[user] directs [src] to [M]'s eyes.", \ "You direct [src] to [M]'s eyes.") - if(istype(M, /mob/living/carbon/human)) //robots and aliens are unaffected - if(M.stat == DEAD || M.disabilities & BLIND) //mob is dead or fully blind - to_chat(user, "[M] pupils does not react to the light!") - else if(XRAY in M.mutations) //mob has X-RAY vision - to_chat(user, "[M] pupils give an eerie glow!") - else //they're okay! + if(istype(H)) //robots and aliens are unaffected + var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) + if(M.stat == DEAD || !eyes || M.disabilities & BLIND) //mob is dead or fully blind + to_chat(user, "[M]'s pupils are unresponsive to the light!") + else if((XRAY in M.mutations) || (eyes.colourblind_darkview && eyes.colourblind_darkview == eyes.get_dark_view())) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms). + to_chat(user, "[M]'s pupils glow eerily!") + else //they're okay! if(M.flash_eyes(visual = 1)) to_chat(user, "[M]'s pupils narrow.") else diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 172cee5ad94..deb677b23dd 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -128,8 +128,8 @@ to_chat(S, "Your sensors were overloaded by a laser!") outmsg = "You overload [S] by shining [src] at their sensors." - S.attack_log += text("\[[time_stamp()]\] Has had a laser pointer shone in their eyes by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Shone a laser pointer in the eyes of [S.name] ([S.ckey])") + S.create_attack_log("Has had a laser pointer shone in their eyes by [user.name] ([user.ckey])") + user.create_attack_log("Shone a laser pointer in the eyes of [S.name] ([S.ckey])") log_attack("[user.name] ([user.ckey]) Shone a laser pointer in the eyes of [S.name] ([S.ckey])") else outmsg = "You fail to overload [S] by shining [src] at their sensors." @@ -142,7 +142,7 @@ outmsg = "You hit the lens of [C] with [src], temporarily disabling the camera!" log_admin("\[[time_stamp()]\] [user.name] ([user.ckey]) EMPd a camera with a laser pointer") - user.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) EMPd a camera with a laser pointer") + user.create_attack_log("[user.name] ([user.ckey]) EMPd a camera with a laser pointer") else outmsg = "You missed the lens of [C] with [src]." diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index ecb1c38d9d7..30e02824cd1 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -63,18 +63,16 @@ return RADIO_CONNECTION_FAIL return ..() - -/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0) - if(aiOverride) - return ..(freq, level) + +/obj/item/device/radio/headset/is_listening() 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 + return ..() + else if(isanimal(loc) || isAI(loc)) + return ..() + + return FALSE /obj/item/device/radio/headset/alt name = "bowman headset" @@ -304,10 +302,10 @@ var/myAi = null // Atlantis: Reference back to the AI which has this radio. var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu. -/obj/item/device/radio/headset/heads/ai_integrated/receive_range(freq, level) +/obj/item/device/radio/headset/heads/ai_integrated/is_listening() if(disabledAi) - return -1 //Transciever Disabled. - return ..(freq, level, 1) + return FALSE + return ..() /obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob) user.set_machine(src) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 502a5da02b3..12b12c14406 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -120,15 +120,13 @@ attack_self(user) /obj/item/device/radio/intercom/receive_range(freq, level) - if(!on) + if(!is_listening()) return -1 if(!(0 in level)) var/turf/position = get_turf(src) // TODO: Integrate radio with the space manager if(isnull(position) || !(position.z in level)) return -1 - if(!src.listening) - return -1 if(freq in ANTAG_FREQS) if(!(src.syndie)) return -1//Prevents broadcast of messages over devices lacking the encryption diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index f4f95559ad9..e144c5d3c50 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -71,6 +71,7 @@ var/global/list/default_medbay_channels = list( initialize() internal_channels = default_internal_channels.Copy() + global_radios |= src /obj/item/device/radio/Destroy() qdel(wires) @@ -80,6 +81,7 @@ var/global/list/default_medbay_channels = list( for(var/ch_name in channels) radio_controller.remove_object(src, radiochannels[ch_name]) patch_link = null + global_radios -= src return ..() @@ -532,19 +534,15 @@ var/global/list/default_medbay_channels = list( // what the range is in which mobs will hear the radio // returns: -1 if can't receive, range otherwise - if(!wires || wires.IsIndexCut(WIRE_RECEIVE)) - return -1 - if(!listening) + if(!is_listening()) return -1 if(!(0 in level)) var/turf/position = get_turf(src) if(!position || !(position.z in level)) return -1 if(freq in ANTAG_FREQS) - if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys + if(!(syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys return -1 - if(!on) - return -1 if(!freq) //recieved on main frequency if(!listening) return -1 @@ -561,11 +559,26 @@ var/global/list/default_medbay_channels = list( return canhear_range /obj/item/device/radio/proc/send_hear(freq, level) - var/range = receive_range(freq, level) if(range > -1) return get_mobs_in_view(canhear_range, src) + +/obj/item/device/radio/proc/is_listening() + var/is_listening = TRUE + if(!on) + is_listening = FALSE + if(!wires || wires.IsIndexCut(WIRE_RECEIVE)) + is_listening = FALSE + if(!listening) + is_listening = FALSE + return is_listening + +/obj/item/device/radio/proc/send_announcement() + if(is_listening()) + return get_mobs_in_view(canhear_range, src) + + return null /obj/item/device/radio/examine(mob/user, var/distance = -1) . = ..(user, distance) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index f126910bcbb..ba62169b886 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -2,11 +2,12 @@ icon = 'icons/obj/assemblies.dmi' name = "tank transfer valve" icon_state = "valve_1" + item_state = "ttv" desc = "Regulates the transfer of air between two tanks" - var/obj/item/weapon/tank/tank_one - var/obj/item/weapon/tank/tank_two - var/obj/item/device/attached_device - var/mob/attacher = null + var/obj/item/weapon/tank/tank_one = null + var/obj/item/weapon/tank/tank_two = null + var/obj/item/device/assembly/attached_device = null + var/mob/living/attacher = null var/valve_open = 0 var/toggle = 1 origin_tech = "materials=1;engineering=1" @@ -21,75 +22,79 @@ if(attached_device) qdel(attached_device) attached_device = null + attacher = null return ..() -/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D) - /obj/item/device/transfer_valve/IsAssemblyHolder() return 1 -/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params) - if(istype(item, /obj/item/weapon/tank)) +/obj/item/device/transfer_valve/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/tank)) if(tank_one && tank_two) to_chat(user, "There are already two tanks attached, remove one first.") return if(!tank_one) - tank_one = item - user.drop_item() - item.loc = src + if(!user.unEquip(I)) + return + tank_one = I + I.forceMove(src) to_chat(user, "You attach the tank to the transfer valve.") + if(I.w_class > w_class) + w_class = I.w_class else if(!tank_two) - tank_two = item - user.drop_item() - item.loc = src + if(!user.unEquip(I)) + return + tank_two = I + I.forceMove(src) to_chat(user, "You attach the tank to the transfer valve.") + if(I.w_class > w_class) + w_class = I.w_class update_icon() nanomanager.update_uis(src) // update all UIs attached to src //TODO: Have this take an assemblyholder - else if(isassembly(item)) - var/obj/item/device/assembly/A = item + else if(isassembly(I)) + var/obj/item/device/assembly/A = I if(A.secured) to_chat(user, "The device is secured.") return if(attached_device) to_chat(user, "There is already a device attached to the valve, remove it first.") return - user.remove_from_mob(item) + user.remove_from_mob(A) attached_device = A - A.loc = src - to_chat(user, "You attach the [item] to the valve controls and secure it.") + A.forceMove(src) + to_chat(user, "You attach the [A] to the valve controls and secure it.") A.holder = src A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - bombers += "[key_name(user)] attached a [item] to a transfer valve." - msg_admin_attack("[key_name_admin(user)]attached [item] to a transfer valve.") - log_game("[key_name_admin(user)] attached [item] to a transfer valve.") + bombers += "[key_name(user)] attached a [A] to a transfer valve." + msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.") + log_game("[key_name_admin(user)] attached [A] to a transfer valve.") attacher = user nanomanager.update_uis(src) // update all UIs attached to src - return -/obj/item/device/transfer_valve/HasProximity(atom/movable/AM as mob|obj) - if(!attached_device) return +/obj/item/device/transfer_valve/HasProximity(atom/movable/AM) + if(!attached_device) + return attached_device.HasProximity(AM) - return -/obj/item/device/transfer_valve/hear_talk(mob/living/M as mob, msg) +/obj/item/device/transfer_valve/hear_talk(mob/living/M, msg) ..() for(var/obj/O in contents) O.hear_talk(M, msg) -/obj/item/device/transfer_valve/hear_message(mob/living/M as mob, msg) +/obj/item/device/transfer_valve/hear_message(mob/living/M, msg) ..() for(var/obj/O in contents) O.hear_message(M, msg) -/obj/item/device/transfer_valve/attack_self(mob/user as mob) +/obj/item/device/transfer_valve/attack_self(mob/user) ui_interact(user) -/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) @@ -113,36 +118,40 @@ /obj/item/device/transfer_valve/Topic(href, href_list) ..() - if( usr.stat || usr.restrained() ) + if(usr.incapacitated()) return 0 - if(src.loc != usr) + if(loc != usr) return 0 if(tank_one && href_list["tankone"]) split_gases() valve_open = 0 - tank_one.loc = get_turf(src) + tank_one.forceMove(get_turf(src)) tank_one = null update_icon() + if((!tank_two || tank_two.w_class < 4) && (w_class > 3)) + w_class = 3 else if(tank_two && href_list["tanktwo"]) split_gases() valve_open = 0 - tank_two.loc = get_turf(src) + tank_two.forceMove(get_turf(src)) tank_two = null update_icon() + if((!tank_one || tank_one.w_class < 4) && (w_class > 3)) + w_class = 3 else if(href_list["open"]) toggle_valve() else if(attached_device) if(href_list["rem_device"]) - attached_device.loc = get_turf(src) - attached_device:holder = null + attached_device.forceMove(get_turf(src)) + attached_device.holder = null attached_device = null update_icon() if(href_list["device"]) attached_device.attack_self(usr) - src.add_fingerprint(usr) + add_fingerprint(usr) return 1 // Returning 1 sends an update to attached UIs -/obj/item/device/transfer_valve/process_activation(var/obj/item/device/D) +/obj/item/device/transfer_valve/proc/process_activation(obj/item/device/D) if(toggle) toggle = 0 toggle_valve() @@ -188,7 +197,7 @@ */ /obj/item/device/transfer_valve/proc/toggle_valve() - if(valve_open==0 && (tank_one && tank_two)) + if(!valve_open && tank_one && tank_two) valve_open = 1 var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) @@ -206,17 +215,12 @@ log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") merge_gases() spawn(20) // In case one tank bursts - for(var/i=0,i<5,i++) - src.update_icon() + for(var/i in 1 to 5) + update_icon() sleep(10) - src.update_icon() + update_icon() - else if(valve_open==1 && (tank_one && tank_two)) + else if(valve_open && tank_one && tank_two) split_gases() valve_open = 0 - src.update_icon() - -// this doesn't do anything but the timer etc. expects it to be here -// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs -/obj/item/device/transfer_valve/proc/c_state() - return + update_icon() \ No newline at end of file diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm index a27cfe68476..589e1ba87e0 100644 --- a/code/game/objects/items/robot/ai_upgrades.dm +++ b/code/game/objects/items/robot/ai_upgrades.dm @@ -5,7 +5,7 @@ /obj/item/device/malf_upgrade name = "combat software upgrade" desc = "A highly illegal, highly dangerous upgrade for artificial intelligence units, granting them a variety of powers as well as the ability to hack APCs." - icon = 'icons/obj/cloning.dmi' + icon = 'icons/obj/module.dmi' icon_state = "datadisk3" @@ -26,7 +26,7 @@ /obj/item/device/surveillance_upgrade name = "surveillance software upgrade" desc = "A software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading." - icon = 'icons/obj/cloning.dmi' + icon = 'icons/obj/module.dmi' icon_state = "datadisk3" /obj/item/device/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index eae834731a9..0e9d9a0ac09 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -34,51 +34,3 @@ name = "Overdrive" icon = 'icons/obj/decals.dmi' icon_state = "shock" - -/********************************************************************** - HUD/SIGHT things -***********************************************************************/ -/obj/item/borg/sight - icon = 'icons/obj/decals.dmi' - icon_state = "securearea" - var/sight_mode = null - -/obj/item/borg/sight/xray - name = "X-ray Vision" - sight_mode = BORGXRAY - -/obj/item/borg/sight/thermal - name = "Thermal Vision" - sight_mode = BORGTHERM - icon_state = "thermal" - icon = 'icons/obj/clothing/glasses.dmi' - -/obj/item/borg/sight/meson - name = "Meson Vision" - sight_mode = BORGMESON - icon_state = "meson" - icon = 'icons/obj/clothing/glasses.dmi' - -/obj/item/borg/sight/hud - name = "Hud" - var/obj/item/clothing/glasses/hud/hud = null - -/obj/item/borg/sight/hud/med - name = "medical hud" - icon_state = "healthhud" - icon = 'icons/obj/clothing/glasses.dmi' - -/obj/item/borg/sight/hud/med/New() - ..() - hud = new /obj/item/clothing/glasses/hud/health(src) - return - -/obj/item/borg/sight/hud/sec - name = "security hud" - icon_state = "securityhud" - icon = 'icons/obj/clothing/glasses.dmi' - -/obj/item/borg/sight/hud/sec/New() - ..() - hud = new /obj/item/clothing/glasses/hud/security(src) - return diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index ffb1d31faa8..40cc65da34a 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -35,6 +35,7 @@ R.uneq_all() R.hands.icon_state = "nomod" R.icon_state = "robot" + R.module.remove_subsystems_and_actions(R) qdel(R.module) R.module = null @@ -195,25 +196,6 @@ return 1 -/obj/item/borg/upgrade/hyperka - name = "mining cyborg hyper-kinetic accelerator" - desc = "A satchel of holding replacement for mining cyborg's ore satchel module." - icon_state = "cyborg_upgrade3" - require_module = 1 - module_type = /obj/item/weapon/robot_module/miner - -/obj/item/borg/upgrade/hyperka/action(mob/living/silicon/robot/R) - if(..()) - return - - for(var/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) - qdel(H) - - R.module.modules += new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg(R.module) - R.module.rebuild() - - return 1 - /obj/item/borg/upgrade/syndicate name = "illegal equipment module" desc = "Unlocks the hidden, deadlier functions of a cyborg" @@ -328,4 +310,4 @@ to_chat(cyborg, "Self-repair is active in [msgmode] mode.") msg_cooldown = world.time else - deactivate() \ No newline at end of file + deactivate() diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 2c6d04b9c06..1555e9a697f 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -152,8 +152,6 @@ icon_state = "burnkit" heal_burn = 25 - - //Medical Herbs// @@ -161,8 +159,8 @@ name = "\improper Comfrey leaf" singular_name = "Comfrey leaf" desc = "A soft leaf that is rubbed on bruises." - icon = 'icons/obj/hydroponics_products.dmi' - icon_state = "alien3-product" + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "tea_aspera_leaves" color = "#378C61" heal_brute = 12 @@ -171,13 +169,12 @@ name = "\improper Aloe Vera leaf" singular_name = "Aloe Vera leaf" desc = "A cold leaf that is rubbed on burns." - icon = 'icons/obj/hydroponics_products.dmi' - icon_state = "ambrosia-product" + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "ambrosiavulgaris" color = "#4CC5C7" heal_burn = 12 - //Splits// diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 4678d18a2f3..46f7b3fb469 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -102,19 +102,49 @@ var/global/list/datum/stack_recipe/human_recipes = list( \ icon_state = "sheet-leather" origin_tech = "materials=2" +/obj/item/stack/sheet/sinew + name = "watcher sinew" + icon = 'icons/obj/mining.dmi' + desc = "Long stringy filaments which presumably came from a watcher's wings." + singular_name = "watcher sinew" + icon_state = "sinew" + origin_tech = "biotech=4" + +var/global/list/datum/stack_recipe/sinew_recipes = list ( \ + new/datum/stack_recipe("sinew restraints", /obj/item/weapon/restraints/handcuffs/sinew, 1, on_floor = 1), \ + ) +/obj/item/stack/sheet/sinew/New(var/loc, var/amount=null) + recipes = sinew_recipes + return ..() + +/obj/item/stack/sheet/animalhide/goliath_hide + name = "goliath hide plates" + desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna." + icon = 'icons/obj/mining.dmi' + icon_state = "goliath_hide" + singular_name = "hide plate" + flags = NOBLUDGEON + w_class = 3 + layer = MOB_LAYER +/obj/item/stack/sheet/animalhide/ashdrake + name = "ash drake hide" + desc = "The strong, scaled hide of an ash drake." + icon = 'icons/obj/mining.dmi' + icon_state = "dragon_hide" + singular_name = "drake plate" + flags = NOBLUDGEON + w_class = 3 + layer = MOB_LAYER + //Step one - dehairing. /obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if( istype(W, /obj/item/weapon/kitchen/knife) || \ - istype(W, /obj/item/weapon/twohanded/fireaxe) || \ - istype(W, /obj/item/weapon/hatchet) ) - - //visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message) - usr.visible_message("\blue \the [usr] starts cutting hair off \the [src]", "\blue You start cutting the hair off \the [src]", "You hear the sound of a knife rubbing against flesh") + if(W.sharp) + user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]...", "You hear the sound of a knife rubbing against flesh.") if(do_after(user,50, target = src)) - to_chat(usr, "\blue You cut the hair from this [src.singular_name]") + to_chat(user, "You cut the hair from this [src.singular_name].") //Try locating an exisitng stack on the tile and add to there if possible for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc) if(HS.amount < 50) @@ -128,7 +158,6 @@ var/global/list/datum/stack_recipe/human_recipes = list( \ else ..() - //Step two - washing..... it's actually in washing machine code. //Step three - drying diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index 4d8b27a6690..9ca562b50ce 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -3,6 +3,7 @@ gender = PLURAL singular_name = "wired glass floor tile" desc = "A glass tile, which is wired, somehow." + icon = 'icons/obj/tiles.dmi' icon_state = "glass_wire" w_class = 3 force = 3.0 diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 3afb9b21eab..7612d3a88ad 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -12,35 +12,43 @@ Mineral Sheets - Tranqillite - Enriched Uranium - Platinum - - Metallic Hydrogen - - Tritium - - Osmium */ var/global/list/datum/stack_recipe/sandstone_recipes = list ( \ - new/datum/stack_recipe("pile of dirt", /obj/machinery/portable_atmospherics/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \ ) var/global/list/datum/stack_recipe/silver_recipes = list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \ ) var/global/list/datum/stack_recipe/diamond_recipes = list ( \ new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \ ) var/global/list/datum/stack_recipe/uranium_recipes = list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \ ) var/global/list/datum/stack_recipe/gold_recipes = list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \ + null, \ new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \ ) var/global/list/datum/stack_recipe/plasma_recipes = list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \ ) var/global/list/datum/stack_recipe/plastic_recipes = list ( \ @@ -61,13 +69,24 @@ var/global/list/datum/stack_recipe/plastic_recipes = list ( \ ) var/global/list/datum/stack_recipe/bananium_recipes = list ( \ + new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ + null, \ new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("bananium grenade casing", /obj/item/weapon/grenade/bananade/casing, 4, on_floor = 1), \ ) var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ - new/datum/stack_recipe("silent tile", /obj/item/stack/tile/silent, 1, 4, 20), \ new/datum/stack_recipe("invisible wall", /obj/structure/barricade/mime, 5, one_per_turf = 1, on_floor = 1, time = 50), \ + null, \ + new/datum/stack_recipe("silent tile", /obj/item/stack/tile/mineral/tranquillite, 1, 4, 20), \ + ) + +var/global/list/datum/stack_recipe/abductor_recipes = list ( \ + new/datum/stack_recipe("alien bed", /obj/structure/stool/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("alien table frame", /obj/structure/abductor_tableframe, 1, time = 15, one_per_turf = 1, on_floor = 1), \ + null, \ + new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \ ) /obj/item/stack/sheet/mineral @@ -100,11 +119,11 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/diamond name = "diamond" icon_state = "sheet-diamond" + singular_name = "diamond" origin_tech = "materials=6" sheettype = "diamond" materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) - /obj/item/stack/sheet/mineral/diamond/New() ..() recipes = diamond_recipes @@ -112,6 +131,7 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/uranium name = "uranium" icon_state = "sheet-uranium" + singular_name = "uranium sheet" origin_tech = "materials=5" sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) @@ -123,6 +143,7 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/plasma name = "solid plasma" icon_state = "sheet-plasma" + singular_name = "plasma sheet" origin_tech = "plasmatech=2;materials=2" sheettype = "plasma" materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) @@ -161,6 +182,7 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/gold name = "gold" icon_state = "sheet-gold" + singular_name = "gold bar" origin_tech = "materials=4" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) @@ -172,6 +194,7 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/silver name = "silver" icon_state = "sheet-silver" + singular_name = "silver bar" origin_tech = "materials=3" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) @@ -183,23 +206,24 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ /obj/item/stack/sheet/mineral/bananium name = "bananium" icon_state = "sheet-clown" + singular_name = "bananium sheet" origin_tech = "materials=4" sheettype = "bananium" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) -/obj/item/stack/sheet/mineral/bananium/New(var/loc, var/amount=null) +/obj/item/stack/sheet/mineral/bananium/New(loc, amount=null) ..() recipes = bananium_recipes /obj/item/stack/sheet/mineral/tranquillite name = "tranquillite" - singular_name = "beret" icon_state = "sheet-mime" + singular_name = "beret" origin_tech = "materials=4" sheettype = "tranquillite" materials = list(MAT_TRANQUILLITE=MINERAL_MATERIAL_AMOUNT) -/obj/item/stack/sheet/mineral/tranquillite/New(var/loc, var/amount=null) +/obj/item/stack/sheet/mineral/tranquillite/New(loc, amount=null) ..() recipes = tranquillite_recipes @@ -209,9 +233,7 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ origin_tech = "materials=6" materials = list(MAT_URANIUM=3000) -/* - * Alien Alloy - */ +//Alien Alloy /obj/item/stack/sheet/mineral/abductor name = "alien alloy" icon = 'icons/obj/abductor.dmi' @@ -225,14 +247,6 @@ var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \ origin_tech = "materials=6;abductor=1" sheettype = "abductor" -var/global/list/datum/stack_recipe/abductor_recipes = list ( \ - new/datum/stack_recipe("alien bed", /obj/structure/stool/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("alien table frame", /obj/structure/abductor_tableframe, 1, time = 15, one_per_turf = 1, on_floor = 1), \ - null, \ - new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \ - ) - -/obj/item/stack/sheet/mineral/abductor/New(var/loc, var/amount=null) +/obj/item/stack/sheet/mineral/abductor/New(loc, amount=null) recipes = abductor_recipes ..() \ No newline at end of file diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 509d6adb0a7..4e822d3ce12 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -53,6 +53,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list( new /datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("machine frame", /obj/machinery/constructable_frame/machine_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("turret frame", /obj/machinery/porta_turret_construct, 5, time = 25, one_per_turf = 1, on_floor = 1), + new /datum/stack_recipe("firelock frame", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = 1, on_floor = 1), \ new /datum/stack_recipe("meatspike frame", /obj/structure/kitchenspike_frame, 5, time = 25, one_per_turf = 1, on_floor = 1), null, new /datum/stack_recipe_list("airlock assemblies", list( @@ -63,7 +64,6 @@ var/global/list/datum/stack_recipe/metal_recipes = list( new /datum/stack_recipe("mining airlock assembly", /obj/structure/door_assembly/door_assembly_min, 4, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("atmospherics airlock assembly", /obj/structure/door_assembly/door_assembly_atmo, 4, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("research airlock assembly", /obj/structure/door_assembly/door_assembly_research, 4, time = 50, one_per_turf = 1, on_floor = 1), -/* new /datum/stack_recipe("science airlock assembly", /obj/structure/door_assembly/door_assembly_science, 4, time = 50, one_per_turf = 1, on_floor = 1), */ new /datum/stack_recipe("medical airlock assembly", /obj/structure/door_assembly/door_assembly_med, 4, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("maintenance airlock assembly", /obj/structure/door_assembly/door_assembly_mai, 4, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("external airlock assembly", /obj/structure/door_assembly/door_assembly_ext, 4, time = 50, one_per_turf = 1, on_floor = 1), @@ -145,6 +145,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list( new /datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1), + new /datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), new /datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), new /datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), @@ -170,13 +171,42 @@ var/global/list/datum/stack_recipe/wood_recipes = list( /* * Cloth */ +var/global/list/datum/stack_recipe/cloth_recipes = list ( \ + new/datum/stack_recipe("grey jumpsuit", /obj/item/clothing/under/color/grey, 3), \ + new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/black, 2), \ + null, \ + new/datum/stack_recipe("backpack", /obj/item/weapon/storage/backpack, 4), \ + new/datum/stack_recipe("dufflebag", /obj/item/weapon/storage/backpack/duffel, 6), \ + null, \ + new/datum/stack_recipe("plant bag", /obj/item/weapon/storage/bag/plants, 4), \ + new/datum/stack_recipe("book bag", /obj/item/weapon/storage/bag/books, 4), \ + new/datum/stack_recipe("mining satchel", /obj/item/weapon/storage/bag/ore, 4), \ + new/datum/stack_recipe("chemistry bag", /obj/item/weapon/storage/bag/chemistry, 4), \ + new/datum/stack_recipe("bio bag", /obj/item/weapon/storage/bag/bio, 4), \ + null, \ + new/datum/stack_recipe("rag", /obj/item/weapon/reagent_containers/glass/rag, 1), \ + new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 3), \ + null, \ + new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \ + new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \ + ) + /obj/item/stack/sheet/cloth name = "cloth" - desc = "This roll of cloth is made from only the finest chemicals and bunny rabbits." + desc = "Is it cotton? Linen? Denim? Burlap? Canvas? You can't tell." singular_name = "cloth roll" icon_state = "sheet-cloth" origin_tech = "materials=2" burn_state = FLAMMABLE + force = 0 + throwforce = 0 + +/obj/item/stack/sheet/cloth/New(loc, amount=null) + recipes = cloth_recipes + ..() + +/obj/item/stack/sheet/cloth/ten + amount = 10 /* * Cardboard @@ -240,3 +270,19 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \ /obj/item/stack/sheet/runed_metal/New(var/loc, var/amount=null) recipes = runed_metal_recipes return ..() + +/* + * Bones + */ +/obj/item/stack/sheet/bone + name = "bones" + icon = 'icons/obj/mining.dmi' + icon_state = "bone" + singular_name = "bone" + desc = "Someone's been drinking their milk." + force = 7 + throwforce = 5 + w_class = 3 + throw_speed = 1 + throw_range = 3 + origin_tech = "materials=2;biotech=2" \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm index 7e6d5459dbf..7f9c6b6535b 100644 --- a/code/game/objects/items/stacks/tiles/tile_mineral.dm +++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm @@ -1,3 +1,68 @@ +/obj/item/stack/tile/mineral/plasma + name = "plasma tile" + singular_name = "plasma floor tile" + desc = "A tile made out of highly flammable plasma. This can only end well." + icon_state = "tile_plasma" + origin_tech = "plasmatech=1" + turf_type = /turf/simulated/floor/mineral/plasma + mineralType = "plasma" + materials = list(MAT_PLASMA=500) + +/obj/item/stack/tile/mineral/uranium + name = "uranium tile" + singular_name = "uranium floor tile" + desc = "A tile made out of uranium. You feel a bit woozy." + icon_state = "tile_uranium" + turf_type = /turf/simulated/floor/mineral/uranium + mineralType = "uranium" + materials = list(MAT_URANIUM=500) + +/obj/item/stack/tile/mineral/gold + name = "gold tile" + singular_name = "gold floor tile" + desc = "A tile made out of gold, the swag seems strong here." + icon_state = "tile_gold" + turf_type = /turf/simulated/floor/mineral/gold + mineralType = "gold" + materials = list(MAT_GOLD=500) + +/obj/item/stack/tile/mineral/silver + name = "silver tile" + singular_name = "silver floor tile" + desc = "A tile made out of silver, the light shining from it is blinding." + icon_state = "tile_silver" + turf_type = /turf/simulated/floor/mineral/silver + mineralType = "silver" + materials = list(MAT_SILVER=500) + +/obj/item/stack/tile/mineral/diamond + name = "diamond tile" + singular_name = "diamond floor tile" + desc = "A tile made out of diamond. Wow, just, wow." + icon_state = "tile_diamond" + origin_tech = "materials=2" + turf_type = /turf/simulated/floor/mineral/diamond + mineralType = "diamond" + materials = list(MAT_DIAMOND=500) + +/obj/item/stack/tile/mineral/bananium + name = "bananium tile" + singular_name = "bananium floor tile" + desc = "A tile made out of bananium, HOOOOOOOOONK!" + icon_state = "tile_bananium" + turf_type = /turf/simulated/floor/mineral/bananium + mineralType = "bananium" + materials = list(MAT_BANANIUM=500) + +/obj/item/stack/tile/mineral/tranquillite + name = "silent tile" + singular_name = "silent floor tile" + desc = "A tile made out of tranquillite, SHHHHHHHHH!" + icon_state = "tile_tranquillite" + turf_type = /turf/simulated/floor/mineral/tranquillite + mineralType = "tranquillite" + materials = list(MAT_TRANQUILLITE=500) + /obj/item/stack/tile/mineral/abductor name = "alien floor tile" singular_name = "alien floor tile" diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index f5b3650c5bb..afa38da7721 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -1,19 +1,8 @@ -/* Different misc types of tiles - * Contains: - * Grass - * Wood - * Carpet - * Plasteel - * Light - * Fakespace - * High-traction - \\ If you don't update the contains list, I'm going to shank you - */ /obj/item/stack/tile name = "broken tile" singular_name = "broken tile" desc = "A broken tile. This should not exist." - icon = 'icons/obj/items.dmi' + icon = 'icons/obj/tiles.dmi' icon_state = "tile" item_state = "tile" w_class = 3 @@ -23,12 +12,64 @@ throw_range = 20 max_amount = 60 flags = CONDUCT + origin_tech = "materials=1" var/turf_type = null var/mineralType = null -/* - * Grass - */ +/obj/item/stack/tile/New(loc, amount) + ..() + pixel_x = rand(-3, 3) + pixel_y = rand(-3, 3) //randomize a little + +/obj/item/stack/tile/attackby(obj/item/W, mob/user, params) + if(iswelder(W)) + var/obj/item/weapon/weldingtool/WT = W + + if(is_hot(W) && !mineralType) + to_chat(user, "You can not reform this!") + return + + if(get_amount() < 4) + to_chat(user, "You need at least four tiles to do this!") + return + + if(WT.remove_fuel(0,user)) + + if(mineralType == "plasma") + atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 5) + user.visible_message("[user.name] sets the plasma tiles on fire!", \ + "You set the plasma tiles on fire!") + qdel(src) + return + + if (mineralType == "metal") + var/obj/item/stack/sheet/metal/new_item = new(user.loc) + user.visible_message("[user.name] shaped [src] into metal with the welding tool.", \ + "You shaped [src] into metal with the welding tool.", \ + "You hear welding.") + var/obj/item/stack/rods/R = src + src = null + var/replace = (user.get_inactive_hand()==R) + R.use(4) + if(!R && replace) + user.put_in_hands(new_item) + + else + var/sheet_type = text2path("/obj/item/stack/sheet/mineral/[mineralType]") + var/obj/item/stack/sheet/mineral/new_item = new sheet_type(user.loc) + user.visible_message("[user.name] shaped [src] into a sheet with the welding tool.", \ + "You shaped [src] into a sheet with the welding tool.", \ + "You hear welding.") + var/obj/item/stack/rods/R = src + src = null + var/replace = (user.get_inactive_hand()==R) + R.use(4) + if (!R && replace) + user.put_in_hands(new_item) + else + return ..() + +//Grass /obj/item/stack/tile/grass name = "grass tiles" gender = PLURAL @@ -39,21 +80,18 @@ turf_type = /turf/simulated/floor/grass burn_state = FLAMMABLE -/* - * Wood - */ +//Wood /obj/item/stack/tile/wood name = "wood floor tiles" gender = PLURAL singular_name = "wood floor tile" desc = "an easy to fit wood floor tile" icon_state = "tile-wood" + origin_tech = "biotech=1" turf_type = /turf/simulated/floor/wood burn_state = FLAMMABLE -/* - * Carpets - */ +//Carpets /obj/item/stack/tile/carpet name = "carpet" singular_name = "carpet" @@ -62,9 +100,7 @@ turf_type = /turf/simulated/floor/carpet burn_state = FLAMMABLE -/* - * Plasteel - */ +//Plasteel /obj/item/stack/tile/plasteel name = "floor tiles" gender = PLURAL @@ -80,9 +116,7 @@ turf_type = /turf/simulated/floor/plasteel mineralType = "metal" -/* - * Light - */ +//Light /obj/item/stack/tile/light name = "light tiles" gender = PLURAL @@ -94,9 +128,7 @@ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed") turf_type = /turf/simulated/floor/light -/* - * Fakespace - */ +//Fakespace /obj/item/stack/tile/fakespace name = "astral carpet" singular_name = "astral carpet" @@ -120,16 +152,6 @@ /obj/item/stack/tile/noslip/loaded amount = 20 -/obj/item/stack/tile/silent - name = "silent tile" - singular_name = "silent floor tile" - desc = "A tile made out of tranquillite, SHHHHHHHHH!" - icon_state = "tile-silent" - origin_tech = "materials=1" - turf_type = /turf/simulated/floor/silent - mineralType = "tranquillite" - materials = list(MAT_TRANQUILLITE=500) - //Pod floor /obj/item/stack/tile/pod name = "pod floor tile" diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 69f03730ce2..feb681e47c2 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -43,14 +43,20 @@ /obj/item/toy/balloon/attack(mob/living/carbon/human/M as mob, mob/user as mob) return -/obj/item/toy/balloon/afterattack(atom/A as mob|obj, mob/user as mob, proximity) - if(!proximity) return - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) - A.reagents.trans_to(src, 10) - to_chat(user, "You fill the balloon with the contents of [A].") - desc = "A translucent balloon with some form of liquid sloshing around in it." - update_icon() - return +/obj/item/toy/balloon/afterattack(atom/A, mob/user, proximity) + if(!proximity) + return + if(istype(A, /obj/structure/reagent_dispensers)) + var/obj/structure/reagent_dispensers/RD = A + if(RD.reagents.total_volume <= 0) + to_chat(user, "[RD] is empty.") + else if(reagents.total_volume >= 10) + to_chat(user, "[src] is full.") + else + A.reagents.trans_to(src, 10) + to_chat(user, "You fill the balloon with the contents of [A].") + desc = "A translucent balloon with some form of liquid sloshing around in it." + update_icon() /obj/item/toy/balloon/wash(mob/user, atom/source) if(reagents.total_volume < 10) @@ -877,7 +883,7 @@ obj/item/toy/cards/deck/syndicate/black /obj/item/toy/minimeteor name = "Mini-Meteor" - desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor™" + desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor." icon = 'icons/obj/toy.dmi' icon_state = "minimeteor" w_class = 2 diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 088c26f06c2..0bacbaa161e 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -18,7 +18,7 @@ RCD throw_speed = 3 throw_range = 5 w_class = 3 - materials = list(MAT_METAL=100000) + materials = list(MAT_METAL = 30000) origin_tech = "engineering=4;materials=2" var/datum/effect/system/spark_spread/spark_system var/max_matter = 100 diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm index c487af03cd6..922f4004714 100644 --- a/code/game/objects/items/weapons/alien_specific.dm +++ b/code/game/objects/items/weapons/alien_specific.dm @@ -64,10 +64,3 @@ desc = "Useful for taking pictures, making friends and flash-frying chips." icon = 'icons/mob/alien.dmi' icon_state = "borg-flash" - -//heat vision - -/obj/item/borg/sight/thermal/alien - name = "thermal module" - icon = 'icons/mob/alien.dmi' - icon_state = "borg-extra-vision" \ No newline at end of file diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm index 8a15bc7f517..7d2b718da82 100644 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ b/code/game/objects/items/weapons/bee_briefcase.dm @@ -46,13 +46,10 @@ to_chat(user, "The buzzing inside the briefcase swells momentarily, then returns to normal. Guess it was too cramped...") S.reagents.clear_reagents() S.update_icon() - else if(istype(I, /obj/item/weapon/plantspray)) - var/obj/item/weapon/plantspray/PS = I - user.drop_item(PS) - bees_left = max(0, (bees_left - PS.pest_kill_str)) - to_chat(user, "You spray [PS] into \the [src].") + else if(istype(I, /obj/item/weapon/reagent_containers/spray/pestspray)) + bees_left = max(0, (bees_left - 6)) + to_chat(user, "You spray [I] into [src].") playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) - qdel(PS) /obj/item/weapon/bee_briefcase/attack_self(mob/user as mob) if(!bees_left) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index d1721c5c247..4a600fe188f 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -397,6 +397,7 @@ "medical", "HoS", "research", + "cargo", "engineering", "CMO", "RD", @@ -757,7 +758,7 @@ override_name = 1 /proc/get_station_card_skins() - return list("data","id","gold","silver","security","medical","research","engineering","HoS","CMO","RD","CE","clown","mime","rainbow","prisoner") + return list("data","id","gold","silver","security","medical","research","cargo","engineering","HoS","CMO","RD","CE","clown","mime","rainbow","prisoner") /proc/get_centcom_card_skins() return list("centcom","centcom_old","nanotrasen","ERT_leader","ERT_empty","ERT_security","ERT_engineering","ERT_medical","ERT_janitorial","deathsquad","commander","syndie","TDred","TDgreen") @@ -769,6 +770,8 @@ switch(skin) if("id") return "Standard" + if("cargo") + return "Supply" if("HoS") return "Head of Security" if("CMO") diff --git a/code/game/objects/items/weapons/cigs.dm b/code/game/objects/items/weapons/cigs.dm index 8449e17a9db..f0c4f1e60d6 100644 --- a/code/game/objects/items/weapons/cigs.dm +++ b/code/game/objects/items/weapons/cigs.dm @@ -42,11 +42,13 @@ LIGHTERS ARE IN LIGHTERS.DM /obj/item/clothing/mask/cigarette/New() ..() - flags |= NOREACT // so it doesn't react until you light it create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 30 + reagents.set_reacting(FALSE) // so it doesn't react until you light it /obj/item/clothing/mask/cigarette/Destroy() - qdel(reagents) + if(reagents) + qdel(reagents) + processing_objects -= src return ..() /obj/item/clothing/mask/cigarette/attack(var/mob/living/M, var/mob/living/user, def_zone) @@ -135,7 +137,7 @@ LIGHTERS ARE IN LIGHTERS.DM M.unEquip(src, 1) qdel(src) return - flags &= ~NOREACT // allowing reagents to react after being lit + reagents.set_reacting(TRUE) reagents.handle_reactions() icon_state = icon_on item_state = icon_on @@ -205,9 +207,9 @@ LIGHTERS ARE IN LIGHTERS.DM var/random_reagent = pick("fuel","saltpetre","synaptizine","green_vomit","potass_iodide","msg","lexorin","mannitol","spaceacillin","cryoxadone","holywater","tea","egg","haloperidol","mutagen","omnizine","carpet","aranesp","cryostylane","chocolate","bilk","cheese","rum","blood","charcoal","coffee","ectoplasm","space_drugs","milk","mutadone","antihol","teporone","insulin","salbutamol","toxin") reagents.add_reagent(random_reagent, 10) -/obj/item/clothing/mask/cigarette/joint - name = "joint" - desc = "A roll of ambrosium vulgaris wrapped in a thin paper. Dude." +/obj/item/clothing/mask/cigarette/rollie + name = "rollie" + desc = "A roll of dried plant matter wrapped in thin paper." icon_state = "spliffoff" icon_on = "spliffon" icon_off = "spliffoff" @@ -217,35 +219,21 @@ LIGHTERS ARE IN LIGHTERS.DM smoketime = 180 chem_volume = 50 -/obj/item/clothing/mask/cigarette/joint/New() +/obj/item/clothing/mask/cigarette/rollie/New() ..() - var/list/jointnames = list("joint","doobie","spliff","blunt") - name = pick(jointnames) - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) -/obj/item/clothing/mask/cigarette/joint/deus - desc = "A roll of ambrosium deus wrapped in a thin paper. Dude." /obj/item/weapon/cigbutt/roach name = "roach" - desc = "A manky old roach." + desc = "A manky old roach, or for non-stoners, a used rollup." icon_state = "roach" /obj/item/weapon/cigbutt/roach/New() ..() - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - -/obj/item/clothing/mask/cigarette/handroll - name = "hand-rolled cigarette" - desc = "A roll of tobacco and nicotine, freshly rolled by hand." - icon_state = "hr_cigoff" - item_state = "hr_cigoff" - icon_on = "hr_cigon" //Note - these are in masks.dmi not in cigarette.dmi - icon_off = "hr_cigoff" - type_butt = /obj/item/weapon/cigbutt - chem_volume = 50 + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) //////////// // CIGARS // @@ -386,51 +374,30 @@ LIGHTERS ARE IN LIGHTERS.DM /////////// //ROLLING// /////////// -obj/item/weapon/rollingpaper +/obj/item/weapon/rollingpaper name = "rolling paper" desc = "A thin piece of paper used to make fine smokeables." icon = 'icons/obj/cigarettes.dmi' icon_state = "cig_paper" w_class = 1 - -obj/item/weapon/rollingpaperpack - name = "rolling paper pack" - desc = "A pack of Nanotrasen brand rolling papers." - icon = 'icons/obj/cigarettes.dmi' - icon_state = "cig_paper_pack" - w_class = 1 - var/papers = 25 - -obj/item/weapon/rollingpaperpack/attack_self(mob/user) - if(papers > 1) - var/obj/item/weapon/rollingpaper/P = new /obj/item/weapon/rollingpaper() - user.put_in_inactive_hand(P) - to_chat(user, "You take a paper out of the pack.") - papers -- - else - var/obj/item/weapon/rollingpaper/P = new /obj/item/weapon/rollingpaper() - user.put_in_inactive_hand(P) - to_chat(user, "You take the last paper out of the pack, and throw the pack away.") - qdel(src) - -/obj/item/weapon/rollingpaperpack/MouseDrop(atom/over_object) - var/mob/M = usr - if(M.restrained() || M.stat) +/obj/item/weapon/rollingpaper/afterattack(atom/target, mob/user, proximity) + if(!proximity) return - - if(over_object == M) - M.put_in_hands(src) - - else if(istype(over_object, /obj/screen)) - switch(over_object.name) - if("r_hand") - M.unEquip(src) - M.put_in_r_hand(src) - if("l_hand") - M.unEquip(src) - M.put_in_l_hand(src) - -/obj/item/weapon/rollingpaperpack/examine(mob/user) - ..(user) - to_chat(user, "There are [src.papers] left") + if(istype(target, /obj/item/weapon/reagent_containers/food/snacks/grown)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/O = target + if(O.dry) + user.unEquip(target, 1) + user.unEquip(src, 1) + var/obj/item/clothing/mask/cigarette/rollie/R = new /obj/item/clothing/mask/cigarette/rollie(user.loc) + R.chem_volume = target.reagents.total_volume + target.reagents.trans_to(R, R.chem_volume) + user.put_in_active_hand(R) + to_chat(user, "You roll the [target.name] into a rolling paper.") + R.desc = "Dried [target.name] rolled up in a thin piece of paper." + qdel(target) + qdel(src) + else + to_chat(user, "You need to dry this first!") + else + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index aea1ebd3e1b..db6035bddbe 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -5,26 +5,6 @@ * Bike Horns */ -/* - * Banana Peals - */ - -/obj/item/weapon/bananapeel - name = "banana peel" - desc = "A peel from a banana." - icon = 'icons/obj/items.dmi' - icon_state = "banana_peel" - item_state = "banana_peel" - w_class = 1 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/bananapeel/Crossed(AM as mob|obj) - if(istype(AM, /mob/living/carbon)) - var/mob/living/carbon/M = AM - M.slip("banana peel", 4, 2) - /* * Soap */ diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index eda6d74b296..924b5e3d590 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -424,6 +424,7 @@ else if(ghost) user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.") to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") + window_flash(ghost.client) ghost << sound('sound/effects/genetics.ogg') else user.visible_message("[defib] buzzes: Resuscitation failed.") @@ -546,6 +547,7 @@ else if(ghost) user.visible_message("[user] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.") to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") + window_flash(ghost.client) ghost << sound('sound/effects/genetics.ogg') else user.visible_message("[user] buzzes: Resuscitation failed.") diff --git a/code/game/objects/items/weapons/disks.dm b/code/game/objects/items/weapons/disks.dm index 1458dab9945..2c3f71f5cf3 100644 --- a/code/game/objects/items/weapons/disks.dm +++ b/code/game/objects/items/weapons/disks.dm @@ -1,3 +1,5 @@ /obj/item/weapon/disk - name = "disk" - icon = 'icons/obj/items.dmi' + icon = 'icons/obj/module.dmi' + w_class = 1 + item_state = "card-id" + icon_state = "datadisk0" diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 45aabc2c073..edf3c737787 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -115,8 +115,8 @@ if(!user.IsAdvancedToolUser()) return 0 - M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [M.name] ([M.ckey])") + M.create_attack_log("Has been injected with [name] by [user.name] ([user.ckey])") + user.create_attack_log("Used the [name] to inject [M.name] ([M.ckey])") log_attack("[user.name] ([user.ckey]) used the [name] to inject [M.name] ([M.ckey])") if(!iscarbon(user)) diff --git a/code/game/objects/items/weapons/garrote.dm b/code/game/objects/items/weapons/garrote.dm index 22b589c7517..a48bc19d512 100644 --- a/code/game/objects/items/weapons/garrote.dm +++ b/code/game/objects/items/weapons/garrote.dm @@ -107,6 +107,12 @@ return /obj/item/weapon/twohanded/garrote/process() + if(!strangling) + // Our mark got gibbed or similar + update_icon() + processing_objects.Remove(src) + return + if(!istype(loc, /mob/living/carbon/human)) strangling = null diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index d503ca04a8f..4f9830890d4 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -71,7 +71,7 @@ /obj/item/weapon/pen/invisible, /obj/item/weapon/lipstick/random, /obj/item/weapon/grenade/smokebomb, - /obj/item/weapon/corncob, + /obj/item/weapon/grown/corncob, /obj/item/weapon/contraband/poster, /obj/item/weapon/bikehorn, /obj/item/weapon/beach_ball, @@ -85,8 +85,8 @@ /obj/random/mech, /obj/item/toy/spinningtoy, /obj/item/toy/sword, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, /obj/item/device/paicard, /obj/item/device/violin, /obj/item/device/guitar, diff --git a/code/game/objects/items/weapons/grenades/bananade.dm b/code/game/objects/items/weapons/grenades/bananade.dm index 189b4eb77c0..580cb993a63 100644 --- a/code/game/objects/items/weapons/grenades/bananade.dm +++ b/code/game/objects/items/weapons/grenades/bananade.dm @@ -9,7 +9,7 @@ var/turf/T icon_state = "banana" item_state = "flashbang" var/deliveryamt = 8 - var/spawner_type = /obj/item/weapon/bananapeel + var/spawner_type = /obj/item/weapon/grown/bananapeel /obj/item/weapon/grenade/bananade/prime() if(spawner_type && deliveryamt) @@ -38,7 +38,7 @@ var/turf/T /obj/item/weapon/grenade/bananade/casing/attackby(var/obj/item/I, mob/user as mob, params) - if(istype(I, /obj/item/weapon/bananapeel)) + if(istype(I, /obj/item/weapon/grown/bananapeel)) if(fillamt < 9) to_chat(usr, "You add another banana peel to the assembly.") fillamt += 1 diff --git a/code/game/objects/items/weapons/grenades/clowngrenade.dm b/code/game/objects/items/weapons/grenades/clowngrenade.dm index 1ce46b44957..a77bd6301b6 100644 --- a/code/game/objects/items/weapons/grenades/clowngrenade.dm +++ b/code/game/objects/items/weapons/grenades/clowngrenade.dm @@ -23,7 +23,7 @@ for(var/direction in alldirs) for(i = 0; i < 2; i++) number++ - var/obj/item/weapon/bananapeel/traitorpeel/peel = new /obj/item/weapon/bananapeel/traitorpeel(get_turf(src.loc)) + var/obj/item/weapon/grown/bananapeel/traitorpeel/peel = new /obj/item/weapon/grown/bananapeel/traitorpeel(get_turf(src.loc)) /* var/direction = pick(alldirs) var/spaces = pick(1;150, 2) var/a = 0 @@ -35,7 +35,7 @@ step(peel,direction) else step(peel,direction) - new /obj/item/weapon/bananapeel/traitorpeel(get_turf(src.loc)) + new /obj/item/weapon/grown/bananapeel/traitorpeel(get_turf(src.loc)) qdel(src) return /* @@ -46,40 +46,32 @@ return if(locate(/obj/structure/window) in T) return - new /obj/item/weapon/bananapeel/traitorpeel(T) + new /obj/item/weapon/grown/bananapeel/traitorpeel(T) */ -/obj/item/weapon/bananapeel/traitorpeel - name = "banana peel" - desc = "A peel from a banana." - icon = 'icons/obj/items.dmi' - icon_state = "banana_peel" - item_state = "banana_peel" - w_class = 1 - throwforce = 0 - throw_speed = 4 - throw_range = 20 +/obj/item/weapon/grown/bananapeel/traitorpeel - Crossed(AM as mob|obj) - var/burned = rand(2,5) - if(istype(AM, /mob/living/carbon)) - var/mob/living/carbon/M = AM - if(ishuman(M)) - if(isobj(M:shoes)) - if((M:shoes.flags&NOSLIP) || (M:species.bodyflags & FEET_NOSLIP)) - return - else - to_chat(M, "\red Your feet feel like they're on fire!") - M.take_overall_damage(0, max(0, (burned - 2))) - if(!istype(M, /mob/living/carbon/slime) && !isrobot(M)) - M.slip("banana peel!", 0, 7, 4) - M.take_organ_damage(2) // Was 5 -- TLE - M.take_overall_damage(0, burned) +/obj/item/weapon/grown/bananapeel/traitorpeel/Crossed(AM as mob|obj) + var/burned = rand(2,5) + if(istype(AM, /mob/living/carbon)) + var/mob/living/carbon/M = AM + if(ishuman(M)) + if(isobj(M:shoes)) + if((M:shoes.flags&NOSLIP) || (M:species.bodyflags & FEET_NOSLIP)) + return + else + to_chat(M, "\red Your feet feel like they're on fire!") + M.take_overall_damage(0, max(0, (burned - 2))) - throw_impact(atom/hit_atom) - var/burned = rand(1,3) - if(istype(hit_atom ,/mob/living)) - var/mob/living/M = hit_atom - M.take_organ_damage(0, burned) - return ..() \ No newline at end of file + if(!istype(M, /mob/living/carbon/slime) && !isrobot(M)) + M.slip("banana peel!", 0, 7, 4) + M.take_organ_damage(2) // Was 5 -- TLE + M.take_overall_damage(0, burned) + +/obj/item/weapon/grown/bananapeel/traitorpeel/throw_impact(atom/hit_atom) + var/burned = rand(1,3) + if(istype(hit_atom ,/mob/living)) + var/mob/living/M = hit_atom + M.take_organ_damage(0, burned) + return ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/clusterbuster.dm b/code/game/objects/items/weapons/grenades/clusterbuster.dm index 851c625b765..e238e3bda25 100644 --- a/code/game/objects/items/weapons/grenades/clusterbuster.dm +++ b/code/game/objects/items/weapons/grenades/clusterbuster.dm @@ -170,7 +170,7 @@ /obj/item/weapon/grenade/clusterbuster/honk name = "Mega Honk Grenade" - payload = /obj/item/weapon/bananapeel + payload = /obj/item/weapon/grown/bananapeel /obj/item/weapon/grenade/clusterbuster/honk_evil name = "Evil Mega Honk Grenade" diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index e93437fbe76..fe3cb3a0c12 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -20,6 +20,7 @@ for(var/i=1, i<=deliveryamt, i++) var/atom/movable/x = new spawner_type + x.admin_spawned = admin_spawned x.loc = T if(prob(50)) for(var/j = 1, j <= rand(1, 3), j++) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index d7e4b3b7b23..7b1187bcc50 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -62,6 +62,15 @@ target.update_handcuffed() return +/obj/item/weapon/restraints/handcuffs/sinew + name = "sinew restraints" + desc = "A pair of restraints fashioned from long strands of flesh." + icon = 'icons/obj/mining.dmi' + icon_state = "sinewcuff" + item_state = "sinewcuff" + breakouttime = 300 //Deciseconds = 30s + cuffsound = 'sound/weapons/cablecuff.ogg' + /obj/item/weapon/restraints/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index be74349f8ca..d82ec9fdf00 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -189,7 +189,7 @@ sharp = 1 edge = 1 attack_verb = list("chopped", "sliced", "cut", "reaped") - hitsound = 'sound/weapons/bladeslice.ogg' + hitsound = 'sound/weapons/rapierhit.ogg' /obj/item/weapon/nullrod/scythe/vibro name = "high frequency blade" @@ -197,6 +197,14 @@ item_state = "hfrequency1" desc = "Bad references are the DNA of the soul." attack_verb = list("chopped", "sliced", "cut", "zandatsu'd") + +/obj/item/weapon/nullrod/scythe/spellblade + icon_state = "spellblade" + item_state = "spellblade" + icon = 'icons/obj/guns/magic.dmi' + name = "dormant spellblade" + desc = "The blade grants the wielder nearly limitless power...if they can figure out how to turn it on, that is." + hitsound = 'sound/weapons/rapierhit.ogg' /obj/item/weapon/nullrod/scythe/talking name = "possessed blade" @@ -204,7 +212,7 @@ item_state = "talking_sword" desc = "When the station falls into chaos, it's nice to have a friend by your side." attack_verb = list("chopped", "sliced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' + hitsound = 'sound/weapons/rapierhit.ogg' var/possessed = FALSE /obj/item/weapon/nullrod/scythe/talking/attack_self(mob/living/user) @@ -453,6 +461,51 @@ if(prob(10)) to_chat(H, "Being in the presence of [holder]'s [src] is interfering with your powers!") +/obj/item/weapon/nullrod/salt + name = "Holy Salt" + icon = 'icons/obj/food/containers.dmi' + icon_state = "saltshakersmall" + desc = "While commonly used to repel some ghosts, it appears others are downright attracted to it." + force = 0 + throwforce = 0 + var/ghostcall_CD = 0 + + +/obj/item/weapon/nullrod/salt/attack_self(mob/user) + + if(!user.mind || user.mind.assigned_role != "Chaplain") + to_chat(user, "You are not close enough with [ticker.Bible_deity_name] to use [src].") + return + + if(!(ghostcall_CD > world.time)) + ghostcall_CD = world.time + 3000 //deciseconds..5 minutes + user.visible_message("[user] kneels and begins to utter a prayer to [ticker.Bible_deity_name] while drawing a circle with salt!", \ + "You kneel and begin a prayer to [ticker.Bible_deity_name] while drawing a circle!") + notify_ghosts("The Chaplain is calling ghosts to [get_area(src)] with [name]!", source = src) + else + to_chat(user, "You need to wait before using [src] again.") + return + + +/obj/item/weapon/nullrod/rosary/bread + name = "prayer bread" + icon = 'icons/obj/food/food.dmi' + icon_state = "baguette" + desc = "a staple of worshipers of the Silentfather, this holy mime artifact has an odd effect on clowns." + +/obj/item/weapon/nullrod/rosary/bread/process() + if(ishuman(loc)) + var/mob/living/carbon/human/holder = loc + //would like to make the holder mime if they have it in on thier person in general + if(src == holder.l_hand || src == holder.r_hand) // Holding this in your hand will + for(var/mob/living/carbon/human/H in range(5)) + if(H.mind.assigned_role == "Clown") + H.Silence(10) + animate_fade_grayscale(H,20) + if(prob(10)) + to_chat(H, "Being in the presence of [holder]'s [src] is interfering with your honk!") + + /obj/item/weapon/nullrod/missionary_staff name = "holy staff" desc = "It has a mysterious, protective aura." diff --git a/code/game/objects/items/weapons/implants/implant_storage.dm b/code/game/objects/items/weapons/implants/implant_storage.dm index 454c08f9df1..fba9c1377ef 100644 --- a/code/game/objects/items/weapons/implants/implant_storage.dm +++ b/code/game/objects/items/weapons/implants/implant_storage.dm @@ -49,6 +49,10 @@ return ..() +/obj/item/weapon/implant/storage/proc/get_contents() //Used for swiftly returning a list of the implant's contents i.e. for checking a theft objective's completion. + if(storage && storage.contents) + return storage.contents + /obj/item/weapon/implanter/storage name = "implanter (storage)" diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 183f07bb21c..069bf06ddfb 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -152,6 +152,17 @@ origin_tech = "materials=2;combat=4" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut") +/obj/item/weapon/kitchen/knife/carrotshiv + name = "carrot shiv" + icon_state = "carrotshiv" + item_state = "carrotshiv" + desc = "Unlike other carrots, you should probably keep this far away from your eyes." + force = 8 + throwforce = 12 //fuck git + materials = list() + origin_tech = "biotech=3;combat=2" + attack_verb = list("shanked", "shivved") + /* * Rolling Pins */ diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index f4b7946d0ca..7a05ca00cb6 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -35,7 +35,7 @@ edge = 1 origin_tech = "combat=5" attack_verb = list("lunged at", "stabbed") - hitsound = 'sound/weapons/slash.ogg' + hitsound = 'sound/weapons/rapierhit.ogg' materials = list(MAT_METAL = 1000) /obj/item/weapon/melee/rapier/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index 92bb7ac4c07..005ef313a4f 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -18,6 +18,25 @@ var/minor_fault = 0 //If not 100% reliable, it will build up faults. var/chargerate = 1000 //how much power is given every tick in a recharger var/self_recharge = 0 //does it self recharge, over time, or not? + var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. + +/obj/item/weapon/stock_parts/cell/New() + ..() + processing_objects.Add(src) + charge = maxcharge + updateicon() + +/obj/item/weapon/stock_parts/cell/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/weapon/stock_parts/cell/on_varedit(modified_var) + if(modified_var == "self_recharge") + if(self_recharge) + processing_objects.Add(src) + else + processing_objects.Remove(src) + ..() /obj/item/weapon/stock_parts/cell/suicide_act(mob/user) to_chat(viewers(user), "[user] is licking the electrodes of the [src.name]! It looks like \he's trying to commit suicide.") @@ -29,6 +48,17 @@ else return PROCESS_KILL +/obj/item/weapon/stock_parts/cell/proc/updateicon() + overlays.Cut() + if(grown_battery) + overlays += image('icons/obj/power.dmi', "grown_wires") + if(charge < 0.01) + return + else if(charge/maxcharge >=0.995) + overlays += image('icons/obj/power.dmi', "cell-o2") + else + overlays += image('icons/obj/power.dmi', "cell-o1") + /obj/item/weapon/stock_parts/cell/crap name = "\improper Nanotrasen brand rechargable AA battery" desc = "You can't top the plasma top." //TOTALLY TRADEMARK INFRINGEMENT @@ -119,14 +149,15 @@ /obj/item/weapon/stock_parts/cell/potato name = "potato battery" desc = "A rechargable starch based power cell." - origin_tech = "powerstorage=1" - icon = 'icons/obj/power.dmi' //'icons/obj/harvest.dmi' - icon_state = "potato_cell" //"potato_battery" + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "potato" + origin_tech = "powerstorage=1;biotech=1" charge = 100 maxcharge = 3000 - rating = 1 materials = list() + rating = 1 minor_fault = 1 + grown_battery = TRUE //it has the overlays for wires /obj/item/weapon/stock_parts/cell/high/slime name = "charged slime core" diff --git a/code/game/objects/items/weapons/powerfist.dm b/code/game/objects/items/weapons/powerfist.dm index eefd3b7d0f6..0167ab589be 100644 --- a/code/game/objects/items/weapons/powerfist.dm +++ b/code/game/objects/items/weapons/powerfist.dm @@ -87,7 +87,7 @@ target.apply_damage(force * fisto_setting, BRUTE) target.visible_message("[user]'s powerfist lets out a loud hiss as they punch [target.name]!", \ "You cry out in pain as [user]'s punch flings you backwards!") - new/obj/effect/kinetic_blast(target.loc) + new /obj/effect/overlay/temp/kinetic_blast(target.loc) playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1) playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1) diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index ef0cdfc329b..49ba664619f 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -159,52 +159,34 @@ // ----------------------------- /obj/item/weapon/storage/bag/plants - icon = 'icons/obj/hydroponics.dmi' + name = "plant bag" + icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "plantbag" - name = "Plant Bag" - storage_slots = 50; //the number of plant pieces it can carry. - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class + storage_slots = 100 //the number of plant pieces it can carry. + max_combined_w_class = 100 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class max_w_class = 3 w_class = 1 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/grown","/obj/item/seeds","/obj/item/weapon/grown", "/obj/item/stack/tile/grass","/obj/item/stack/medical/ointment/aloe","/obj/item/stack/medical/bruise_pack/comfrey", "/obj/item/weapon/reagent_containers/honeycomb") + can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/grown","/obj/item/seeds","/obj/item/weapon/grown","/obj/item/weapon/reagent_containers/food/snacks/ash_flora") burn_state = FLAMMABLE /obj/item/weapon/storage/bag/plants/portaseeder name = "portable seed extractor" desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." icon_state = "portaseeder" + origin_tech = "biotech=3;engineering=2" /obj/item/weapon/storage/bag/plants/portaseeder/verb/dissolve_contents() set name = "Activate Seed Extraction" set category = "Object" set desc = "Activate to convert your plants into plantable seeds." - if(usr.stat || !usr.canmove || usr.restrained()) + + if(usr.incapacitated()) return for(var/obj/item/O in contents) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown) || istype(O, /obj/item/weapon/grown)) - - var/datum/seed/new_seed_type - if(istype(O, /obj/item/weapon/grown)) - var/obj/item/weapon/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] - else - var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O - new_seed_type = plant_controller.seeds[F.plantname] - - if(new_seed_type) - var/obj/item/seeds/seeds = new(O.loc, O) - seeds.seed_type = new_seed_type.name - seeds.update_seed() - qdel(O) - - if(istype(O, /obj/item/stack/tile/grass)) - var/obj/item/stack/tile/grass/S = O - S.use(1) - new /obj/item/seeds/grassseed(O.loc, O) - + seedify(O, 1) for(var/mob/M in range(1)) if(M.s_active == src) - src.close(M) + close(M) // ----------------------------- diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index fc5318bff2f..fe29ba5c23a 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -139,8 +139,8 @@ item_state = "botany" use_item_overlays = 1 can_hold = list( - "/obj/item/device/analyzer/plant_analyzer", - "/obj/item/weapon/minihoe", + "/obj/item/device/plant_analyzer", + "/obj/item/weapon/cultivator", "/obj/item/weapon/hatchet", "/obj/item/weapon/reagent_containers/glass/bottle", "/obj/item/weapon/plantspray", @@ -175,8 +175,7 @@ "/obj/item/clothing/glasses", "/obj/item/ammo_casing/shotgun", "/obj/item/ammo_box", - "/obj/item/weapon/reagent_containers/food/snacks/donut/normal", - "/obj/item/weapon/reagent_containers/food/snacks/donut/jelly", + "/obj/item/weapon/reagent_containers/food/snacks/donut", "/obj/item/weapon/kitchen/knife/combat", "/obj/item/weapon/melee/baton", "/obj/item/weapon/melee/classic_baton", @@ -567,7 +566,7 @@ to_chat(user, "Planting explosives...") user.visible_message("[user.name] is fiddling with their toolbelt.") if(ismob(target)) - user.attack_log += "\[[time_stamp()]\] [user.real_name] tried planting [name] on [target:real_name] ([target:ckey])" + user.create_attack_log(" [user.real_name] tried planting [name] on [target:real_name] ([target:ckey])") log_attack(" [user.real_name] ([user.ckey]) tried planting [name] on [target:real_name] ([target:ckey])") user.visible_message("\red [user.name] is trying to strap a belt to [target.name]!") @@ -579,7 +578,7 @@ var/location if(isturf(target)) location = target if(ismob(target)) - target:attack_log += "\[[time_stamp()]\] Had the [name] planted on them by [user.real_name] ([user.ckey])" + target:create_attack_log(" Had the [name] planted on them by [user.real_name] ([user.ckey])") user.visible_message("\red [user.name] finished planting an explosive on [target.name]!") target.overlays += image('icons/obj/assemblies.dmi', "plastic-explosive2") to_chat(user, "You sacrifice your belt for the sake of justice. Timer counting down from 15.") diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 8a9b86d4e81..21731113466 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -44,8 +44,8 @@ chaplain = 1 - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") + M.create_attack_log("Has been attacked with [src.name] by [user.name] ([user.ckey])") + user.create_attack_log("Used the [src.name] to attack [M.name] ([M.ckey])") log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") if(!iscarbon(user)) @@ -100,7 +100,9 @@ if(istype(A, /turf/simulated/floor)) to_chat(user, "You hit the floor with the bible.") if(user.mind && (user.mind.assigned_role == "Chaplain")) - call(/obj/effect/rune/proc/talismanreveal)(src) + for(var/obj/effect/rune/R in A) + if(R.invisibility) + R.talismanreveal() if(user.mind && (user.mind.assigned_role == "Chaplain")) if(A.reagents && A.reagents.has_reagent("water")) //blesses all the water in the holder to_chat(user, "You bless [A].") @@ -115,4 +117,4 @@ /obj/item/weapon/storage/bible/attackby(obj/item/weapon/W as obj, mob/user as mob, params) playsound(src.loc, "rustle", 50, 1, -5) - ..() \ No newline at end of file + ..() diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index bfdc3a80727..88820290a48 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -391,59 +391,32 @@ icon_state = "monkeycubebox" storage_slots = 7 can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube") - New() - ..() - for(var/i = 1; i <= 5; i++) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped(src) -/obj/item/weapon/storage/box/farwacubes + var/monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube + +/obj/item/weapon/storage/box/monkeycubes/New() + ..() + for(var/i in 1 to 5) + new monkey_cube_type(src) + +/obj/item/weapon/storage/box/monkeycubes/farwacubes name = "farwa cube box" desc = "Drymate brand farwa cubes. Just add water!" - icon = 'icons/obj/food/food.dmi' - icon_state = "monkeycubebox" - storage_slots = 7 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube") - New() - ..() - for(var/i = 1; i <= 5; i++) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube(src) + monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube -/obj/item/weapon/storage/box/stokcubes +/obj/item/weapon/storage/box/monkeycubes/stokcubes name = "stok cube box" desc = "Drymate brand stok cubes. Just add water!" - icon = 'icons/obj/food/food.dmi' - icon_state = "monkeycubebox" - storage_slots = 7 - can_hold = list("/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube") - New() - ..() - for(var/i = 1; i <= 5; i++) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube(src) + monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube -/obj/item/weapon/storage/box/neaeracubes +/obj/item/weapon/storage/box/monkeycubes/neaeracubes name = "neaera cube box" desc = "Drymate brand neaera cubes. Just add water!" - icon = 'icons/obj/food/food.dmi' - icon_state = "monkeycubebox" - storage_slots = 7 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube") - New() - ..() - for(var/i = 1; i <= 5; i++) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube(src) + monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube - -/obj/item/weapon/storage/box/wolpincubes +/obj/item/weapon/storage/box/monkeycubes/wolpincubes name = "wolpin cube box" desc = "Drymate brand wolpin cubes. Just add water!" - icon = 'icons/obj/food/food.dmi' - icon_state = "monkeycubebox" - storage_slots = 7 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube") - New() - ..() - for(var/i = 1; i <= 5; i++) - new /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube(src) - + monkey_cube_type = /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wolpincube /obj/item/weapon/storage/box/permits name = "box of construction permits" diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index c4488216b12..168196f0480 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -53,9 +53,8 @@ /obj/item/weapon/storage/fancy/donut_box/New() ..() - for(var/i=1; i <= storage_slots; i++) - new /obj/item/weapon/reagent_containers/food/snacks/donut/normal(src) - return + for(var/i = 1 to storage_slots) + new /obj/item/weapon/reagent_containers/food/snacks/donut(src) /* * Egg Box @@ -177,8 +176,8 @@ /obj/item/weapon/storage/fancy/cigarettes/New() ..() - flags |= NOREACT create_reagents(30 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one + reagents.set_reacting(FALSE) for(var/i = 1 to storage_slots) var/obj/item/clothing/mask/cigarette/C = new cigarette_type(src) unlaced_cigarettes += C @@ -316,6 +315,26 @@ item_state = "cigpacket" cigarette_type = /obj/item/clothing/mask/cigarette/random +/obj/item/weapon/storage/fancy/rollingpapers + name = "rolling paper pack" + desc = "A pack of NanoTrasen brand rolling papers." + w_class = 1 + icon = 'icons/obj/cigarettes.dmi' + icon_state = "cig_paper_pack" + storage_slots = 10 + icon_type = "rolling paper" + can_hold = list("/obj/item/weapon/rollingpaper") + +/obj/item/weapon/storage/fancy/rollingpapers/New() + ..() + for(var/i in 1 to storage_slots) + new /obj/item/weapon/rollingpaper(src) + +/obj/item/weapon/storage/fancy/rollingpapers/update_icon() + overlays.Cut() + if(!contents.len) + overlays += "[icon_state]_empty" + /* * Vial Box */ diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 40f56f7000f..cdf123f2982 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -298,7 +298,7 @@ usr.update_icons() //update our overlays if(silent) prevent_warning = 1 - W.loc = src + W.forceMove(src) W.on_enter_storage(src) if(usr) if(usr.client && usr.s_active != src) @@ -344,9 +344,9 @@ else W.layer = initial(W.layer) W.plane = initial(W.plane) - W.loc = new_location + W.forceMove(new_location) else - W.loc = get_turf(src) + W.forceMove(get_turf(src)) if(usr) src.orient2hud(usr) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 61d8d4fef91..f2bd9cafedf 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -29,11 +29,6 @@ bcell = null return ..() -/obj/item/weapon/melee/baton/CheckParts(list/parts_list) - ..() - bcell = locate(/obj/item/weapon/stock_parts/cell) in contents - update_icon() - /obj/item/weapon/melee/baton/loaded/New() //this one starts with a cell pre-installed. ..() bcell = new(src) @@ -200,8 +195,18 @@ desc = "An improvised stun baton." icon_state = "stunprod_nocell" item_state = "prod" + w_class = 3 force = 3 throwforce = 5 stunforce = 5 hitcost = 3750 - slot_flags = null + slot_flags = SLOT_BACK + var/obj/item/device/assembly/igniter/sparkler = 0 + +/obj/item/weapon/melee/baton/cattleprod/New() + ..() + sparkler = new (src) + +/obj/item/weapon/melee/baton/cattleprod/baton_stun() + if(sparkler.activate()) + ..() diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 176108b8f08..b7f5e370b95 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -266,22 +266,9 @@ else return ..() -/obj/item/weapon/weldingtool/afterattack(obj/O as obj, mob/user as mob, proximity) - if(!proximity) return - if(istype(O, /obj/structure/reagent_dispensers/fueltank) && in_range(src, O)) - if(!welding) - O.reagents.trans_to(src, max_fuel) - to_chat(user, "[src] refueled.") - playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6) - update_icon() - return - else - message_admins("[key_name_admin(user)] triggered a fueltank explosion.") - log_game("[key_name(user)] triggered a fueltank explosion.") - to_chat(user, "That was stupid of you.") - O.ex_act() - return - +/obj/item/weapon/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) + return if(welding) remove_fuel(1) var/turf/location = get_turf(user) @@ -289,7 +276,9 @@ if(isliving(O)) var/mob/living/L = O - L.IgniteMob() + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") /obj/item/weapon/weldingtool/attack_self(mob/user) toggle(user) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 8e9424c4997..5c66759dc52 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -431,6 +431,7 @@ icon_state = "gchainsaw_off" flags = CONDUCT force = 13 + var/force_on = 21 w_class = 5 throwforce = 13 throw_speed = 2 @@ -449,8 +450,8 @@ to_chat(user, "As you pull the starting cord dangling from [src], [on ? "it begins to whirr." : "the chain stops moving."]") if(on) playsound(loc, 'sound/weapons/chainsawstart.ogg', 50, 1) - force = on ? 21 : 13 - throwforce = on ? 21 : 13 + force = on ? force_on : initial(force) + throwforce = on ? force_on : initial(force) icon_state = "gchainsaw_[on ? "on" : "off"]" if(hitsound == "swing_hit") @@ -469,6 +470,14 @@ name = "OOOH BABY" desc = "VRRRRRRR!!!" armour_penetration = 100 + force_on = 30 + +/obj/item/weapon/twohanded/required/chainsaw/doomslayer/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(attack_type == PROJECTILE_ATTACK) + owner.visible_message("Ranged attacks just make [owner] angrier!") + playsound(src, pick('sound/weapons/bulletflyby.ogg','sound/weapons/bulletflyby2.ogg','sound/weapons/bulletflyby3.ogg'), 75, 1) + return 1 + return 0 ///CHAINSAW/// diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm index a6a53b03606..3fb54c16609 100644 --- a/code/game/objects/items/weapons/vending_items.dm +++ b/code/game/objects/items/weapons/vending_items.dm @@ -82,3 +82,8 @@ machine_name = "CritterCare" icon_state = "refill_pet" charges = 31// of 94 + +/obj/item/weapon/vending_refill/chinese + machine_name = "MrChangs" + charges = 8// of 24 + diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index b9c946c6210..3c8a25ca739 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -23,18 +23,14 @@ slot_flags = SLOT_BELT force = 2 throwforce = 1 - sharp = 1 - edge = 1 w_class = 3 + hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - suicide_act(mob/user) - to_chat(viewers(user), "[user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide.") - return(BRUTELOSS) - -/obj/item/weapon/sord/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return ..() +/obj/item/weapon/sord/suicide_act(mob/user) + user.visible_message("[user] is trying to impale themself with [src]! It might be a suicide attempt if it weren't so shitty.", \ + "You try to impale yourself with [src], but it's USELESS...") + return SHAME /obj/item/weapon/claymore name = "claymore" @@ -105,10 +101,10 @@ obj/item/weapon/wirerod force = 9 throwforce = 10 w_class = 3 - materials = list(MAT_METAL=1000) + materials = list(MAT_METAL=1150, MAT_GLASS=75) attack_verb = list("hit", "bludgeoned", "whacked", "bonked") -obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) +obj/item/weapon/wirerod/attackby(obj/item/I, mob/user, params) ..() if(istype(I, /obj/item/weapon/shard)) var/obj/item/weapon/twohanded/spear/S = new /obj/item/weapon/twohanded/spear @@ -122,7 +118,7 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) qdel(I) qdel(src) - else if(istype(I, /obj/item/weapon/wirecutters)) + else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags & NODROP)) var/obj/item/weapon/melee/baton/cattleprod/P = new /obj/item/weapon/melee/baton/cattleprod if(!remove_item_from_storage(user)) @@ -130,7 +126,7 @@ obj/item/weapon/wirerod/attackby(var/obj/item/I, mob/user as mob, params) user.unEquip(I) user.put_in_hands(P) - to_chat(user, "You fasten the wirecutters to the top of the rod with the cable, prongs outward.") + to_chat(user, "You fasten [I] to the top of the rod with the cable.") qdel(I) qdel(src) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 9a75e9e3950..24fdc2e43ce 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -61,8 +61,6 @@ nanomanager.close_uis(src) return ..() -/obj/item/proc/is_used_on(obj/O, mob/user) - /obj/proc/process() set waitfor = 0 processing_objects.Remove(src) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 26908f69180..e213c555c43 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -16,6 +16,7 @@ var/cutting_sound = 'sound/items/Welder.ogg' var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients. var/material_drop = /obj/item/stack/sheet/metal + var/material_drop_amount = 2 /obj/structure/closet/New() ..() @@ -49,28 +50,13 @@ return 1 /obj/structure/closet/proc/dump_contents() - //Cham Projector Exception - for(var/obj/effect/dummy/chameleon/AD in src) - AD.forceMove(loc) - - for(var/obj/I in src) - I.forceMove(loc) - - for(var/mob/M in src) - moveMob(M, loc) - -/obj/structure/closet/proc/moveMob(var/mob/M, var/atom/destination) - loc.Exited(M) - M.loc = destination - M.reset_perspective(destination) - if(isturf(loc)) - loc.Entered(M, src, ignoreRest = 1) - else - loc.Entered(M, src) - for(var/atom/movable/AM in loc) - if(istype(AM, /obj/item)) - continue - AM.Crossed(M) + var/turf/T = get_turf(src) + for(var/atom/movable/AM in src) + AM.forceMove(T) + if(throwing) // you keep some momentum when getting out of a thrown closet + step(AM, dir) + if(throwing) + throwing = 0 /obj/structure/closet/proc/open() if(src.opened) @@ -120,7 +106,7 @@ if(M.buckled) continue - moveMob(M, src) + M.forceMove(src) itemcount++ src.icon_state = src.icon_closed @@ -271,7 +257,7 @@ "You cut \the [src] apart with \the [WT].", "You hear welding.") var/turf/T = get_turf(src) - new material_drop(T) + new material_drop(T, material_drop_amount) qdel(src) return if(isrobot(user)) @@ -425,4 +411,4 @@ /obj/structure/closet/get_remote_view_fullscreens(mob/user) if(user.stat == DEAD || !(user.sight & (SEEOBJS|SEEMOBS))) - user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) + user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm index c18fd1a9b74..a5c125a8b35 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -9,18 +9,18 @@ icon_off = "hydrosecureoff" - New() - ..() - switch(rand(1,2)) - if(1) - new /obj/item/clothing/suit/apron(src) - if(2) - new /obj/item/clothing/suit/apron/overalls(src) - new /obj/item/weapon/storage/bag/plants/portaseeder(src) - new /obj/item/clothing/under/rank/hydroponics(src) - new /obj/item/device/analyzer/plant_analyzer(src) - new /obj/item/device/radio/headset/headset_service(src) - new /obj/item/device/radio/headset/headset_service(src) - new /obj/item/clothing/mask/bandana/botany(src) - new /obj/item/weapon/minihoe(src) - new /obj/item/weapon/hatchet(src) \ No newline at end of file +/obj/structure/closet/secure_closet/hydroponics/New() + ..() + switch(rand(1,2)) + if(1) + new /obj/item/clothing/suit/apron(src) + if(2) + new /obj/item/clothing/suit/apron/overalls(src) + new /obj/item/weapon/storage/bag/plants/portaseeder(src) + new /obj/item/clothing/under/rank/hydroponics(src) + new /obj/item/device/plant_analyzer(src) + new /obj/item/device/radio/headset/headset_service(src) + new /obj/item/clothing/mask/bandana/botany(src) + new /obj/item/weapon/cultivator(src) + new /obj/item/weapon/hatchet(src) + new /obj/item/weapon/storage/box/disks_plantgene(src) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm index 936201cf75f..11cfc6a7dd5 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/miscjobs.dm @@ -18,7 +18,7 @@ new /obj/item/weapon/bikehorn(src) new /obj/item/weapon/reagent_containers/spray/waterflower(src) new /obj/item/toy/crayon/rainbow(src) - new /obj/item/seeds/bananaseed(src) + new /obj/item/seeds/banana(src) diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index c330ad11a01..3c198e4dd08 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -57,10 +57,9 @@ qdel(src) /obj/structure/closet/statue/dump_contents() - - if(istype(src.loc, /mob/living/simple_animal/hostile/statue)) - var/mob/living/simple_animal/hostile/statue/S = src.loc - src.loc = S.loc + if(istype(loc, /mob/living/simple_animal/hostile/statue)) + var/mob/living/simple_animal/hostile/statue/S = loc + forceMove(S.loc) if(S.mind) for(var/mob/M in contents) S.mind.transfer_to(M) @@ -68,21 +67,16 @@ break qdel(S) - - for(var/obj/O in src) - O.loc = src.loc - for(var/mob/living/M in src) M.forceMove(loc) M.disabilities -= MUTE M.take_overall_damage((M.health - health - 100),0) //any new damage the statue incurred is transfered to the mob - + + ..() /obj/structure/closet/statue/open() return - - /obj/structure/closet/statue/open() return @@ -158,4 +152,4 @@ obj/structure/statue/angel icon_state = "angelseen" obj/structure/statue/corgi - icon_state = "corgi" + icon_state = "corgi" \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index bf74c11ee84..9bc6d5fec8f 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -568,9 +568,42 @@ new /obj/item/weapon/wirecutters(src) new /obj/item/weapon/shovel/spade(src) new /obj/item/weapon/shovel/spade(src) - new /obj/item/weapon/storage/box/botanydisk(src) - new /obj/item/weapon/storage/box/botanydisk(src) new /obj/item/weapon/storage/box/beakers(src) new /obj/item/weapon/storage/box/beakers(src) new /obj/item/weapon/hand_labeler(src) new /obj/item/weapon/hand_labeler(src) + +/obj/structure/closet/crate/sci + name = "science crate" + desc = "A science crate." + icon_state = "scicrate" + icon_opened = "scicrateopen" + icon_closed = "scicrate" + +/obj/structure/closet/crate/secure/scisec + name = "secure science crate" + desc = "A crate with a lock on it, painted in the scheme of the station's scientists." + icon_state = "scisecurecrate" + icon_opened = "scisecurecrateopen" + icon_closed = "scisecurecrate" + +/obj/structure/closet/crate/engineering + name = "engineering crate" + desc = "An engineering crate." + icon_state = "engicrate" + icon_opened = "engicrateopen" + icon_closed = "engicrate" + +/obj/structure/closet/crate/secure/engineering + name = "secure engineering crate" + desc = "A crate with a lock on it, painted in the scheme of the station's engineers." + icon_state = "engisecurecrate" + icon_opened = "engisecurecrateopen" + icon_closed = "engisecurecrate" + +/obj/structure/closet/crate/engineering/electrical + name = "electrical engineering crate" + desc = "An electrical engineering crate." + icon_state = "electricalcrate" + icon_opened = "electricalcrateopen" + icon_closed = "electricalcrate" diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index 9d7bbc96e1b..104fac7fd69 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -27,7 +27,7 @@ ..() /obj/structure/curtain/proc/toggle() - opacity = !opacity + set_opacity(!opacity) if(opacity) icon_state = "closed" layer = SHOWER_CLOSED_LAYER diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 6b732653a64..30e7031db2f 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -266,6 +266,9 @@ var/global/list/captain_display_cases = list() to_chat(user, "It's locked, you can't put anything into it.") return if(!occupant) + if(!user.drop_item()) + to_chat(user, "[W] is stuck to you. You cannot put it in [src]!") + return to_chat(user, "You insert \the [W] into \the [src], and it floats as the hoverfield activates.") user.drop_item() W.forceMove(src) @@ -312,4 +315,4 @@ var/global/list/captain_display_cases = list() "You hear someone streaking glass with their greasy hands.") #undef DISPLAYCASE_FRAME_CIRCUIT -#undef DISPLAYCASE_FRAME_SCREWDRIVER \ No newline at end of file +#undef DISPLAYCASE_FRAME_SCREWDRIVER diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 9dddd902740..dc7152bbd5f 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -1,4 +1,4 @@ -obj/structure/door_assembly +/obj/structure/door_assembly icon = 'icons/obj/doors/door_assembly.dmi' name = "Airlock Assembly" @@ -14,119 +14,114 @@ obj/structure/door_assembly var/glass = 0 // 0 = glass can be installed. -1 = glass can't be installed. 1 = glass is already installed. Text = mineral plating is installed instead. var/created_name = null - New() - update_state() +/obj/structure/door_assembly/New() + update_state() -obj/structure/door_assembly/door_assembly_com +/obj/structure/door_assembly/door_assembly_com base_icon_state = "com" base_name = "Command Airlock" glass_type = "/glass_command" airlock_type = "/command" -obj/structure/door_assembly/door_assembly_sec +/obj/structure/door_assembly/door_assembly_sec base_icon_state = "sec" base_name = "Security Airlock" glass_type = "/glass_security" airlock_type = "/security" -obj/structure/door_assembly/door_assembly_eng +/obj/structure/door_assembly/door_assembly_eng base_icon_state = "eng" base_name = "Engineering Airlock" glass_type = "/glass_engineering" airlock_type = "/engineering" -obj/structure/door_assembly/door_assembly_min +/obj/structure/door_assembly/door_assembly_min base_icon_state = "min" base_name = "Mining Airlock" glass_type = "/glass_mining" airlock_type = "/mining" -obj/structure/door_assembly/door_assembly_atmo +/obj/structure/door_assembly/door_assembly_atmo base_icon_state = "atmo" base_name = "Atmospherics Airlock" glass_type = "/glass_atmos" airlock_type = "/atmos" -obj/structure/door_assembly/door_assembly_research +/obj/structure/door_assembly/door_assembly_research base_icon_state = "res" base_name = "Research Airlock" glass_type = "/glass_research" airlock_type = "/research" -obj/structure/door_assembly/door_assembly_science +/obj/structure/door_assembly/door_assembly_science base_icon_state = "sci" base_name = "Science Airlock" glass_type = "/glass_science" airlock_type = "/science" -obj/structure/door_assembly/door_assembly_med +/obj/structure/door_assembly/door_assembly_med base_icon_state = "med" base_name = "Medical Airlock" glass_type = "/glass_medical" airlock_type = "/medical" -obj/structure/door_assembly/door_assembly_mai +/obj/structure/door_assembly/door_assembly_mai base_icon_state = "mai" base_name = "Maintenance Airlock" airlock_type = "/maintenance" glass = -1 -obj/structure/door_assembly/door_assembly_ext +/obj/structure/door_assembly/door_assembly_ext base_icon_state = "ext" base_name = "External Airlock" airlock_type = "/external" glass = -1 -obj/structure/door_assembly/door_assembly_fre +/obj/structure/door_assembly/door_assembly_fre base_icon_state = "fre" base_name = "Freezer Airlock" airlock_type = "/freezer" glass = -1 -obj/structure/door_assembly/door_assembly_hatch +/obj/structure/door_assembly/door_assembly_hatch base_icon_state = "hatch" base_name = "Airtight Hatch" airlock_type = "/hatch" glass = -1 -obj/structure/door_assembly/door_assembly_mhatch +/obj/structure/door_assembly/door_assembly_mhatch base_icon_state = "mhatch" base_name = "Maintenance Hatch" airlock_type = "/maintenance_hatch" glass = -1 - -obj/structure/door_assembly/door_assembly_highsecurity // Borrowing this until WJohnston makes sprites for the assembly + +/obj/structure/door_assembly/door_assembly_highsecurity // Borrowing this until WJohnston makes sprites for the assembly base_icon_state = "highsec" base_name = "High Security Airlock" airlock_type = "/highsecurity" glass = -1 -obj/structure/door_assembly/door_assembly_shuttle +/obj/structure/door_assembly/door_assembly_shuttle base_icon_state = "shuttle" base_name = "shuttle airlock" airlock_type = "/shuttle" glass = -1 -obj/structure/door_assembly/multi_tile +/obj/structure/door_assembly/multi_tile icon = 'icons/obj/doors/door_assembly2x1.dmi' dir = EAST var/width = 1 -/*Temporary until we get sprites. - glass_type = "/multi_tile/glass" - airlock_type = "/multi_tile/maint" - glass = 1*/ base_icon_state = "g" //Remember to delete this line when reverting "glass" var to 1. airlock_type = "/multi_tile/glass" glass = -1 //To prevent bugs in deconstruction process. - /obj/structure/door_assembly/door_assembly_cult base_name = "cult airlock assembly" icon = 'icons/obj/doors/Doorcult.dmi' base_icon_state ="construction" airlock_type = "/cult" -obj/structure/door_assembly/multi_tile/New() +/obj/structure/door_assembly/multi_tile/New() if(dir in list(EAST, WEST)) bound_width = width * world.icon_size bound_height = world.icon_size @@ -135,7 +130,7 @@ obj/structure/door_assembly/multi_tile/New() bound_height = width * world.icon_size update_state() -obj/structure/door_assembly/multi_tile/Move() +/obj/structure/door_assembly/multi_tile/Move() . = ..() if(dir in list(EAST, WEST)) bound_width = width * world.icon_size diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index b449e8f4f73..a10d5add7fb 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -25,6 +25,18 @@ /turf/simulated/wall/rust, /turf/simulated/wall/r_wall/rust) smooth = SMOOTH_TRUE + +/obj/structure/falsewall/New(loc) + ..() + air_update_turf(1) + +/obj/structure/falsewall/Destroy() + density = 0 + air_update_turf(1) + return ..() + +/obj/structure/falsewall/CanAtmosPass(turf/T) + return !density /obj/structure/falsewall/attack_hand(mob/user) if(opening) @@ -47,6 +59,7 @@ sleep(4) set_opacity(1) update_icon() + air_update_turf(1) opening = 0 /obj/structure/falsewall/proc/do_the_flick() diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 11a0bae8849..4d03bfcdb27 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -36,6 +36,14 @@ ..() icon_state = "tree_[rand(1, 6)]" +/obj/structure/flora/tree/palm + icon = 'icons/misc/beach2.dmi' + icon_state = "palm1" + +/obj/structure/flora/tree/palm/New() + ..() + icon_state = pick("palm1","palm2") + pixel_x = 0 //grass /obj/structure/flora/grass diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index b9af7b2d032..824759b35cb 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -191,7 +191,7 @@ Close() ..() - opacity = 0 + set_opacity(0) /obj/structure/mineral_door/transparent/plasma mineralType = "plasma" @@ -228,7 +228,7 @@ flick("[mineralType]opening",src) sleep(10) density = 0 - opacity = 0 + set_opacity(0) state = 1 update_icon() isSwitchingStates = 0 @@ -239,7 +239,7 @@ flick("[mineralType]closing",src) sleep(10) density = 1 - opacity = 1 + set_opacity(1) state = 0 update_icon() isSwitchingStates = 0 @@ -265,7 +265,7 @@ flick("[mineralType]opening",src) sleep(10) density = 0 - opacity = 0 + set_opacity(0) state = 1 update_icon() isSwitchingStates = 0 @@ -280,7 +280,7 @@ flick("[mineralType]closing",src) sleep(10) density = 1 - opacity = 1 + set_opacity(1) state = 0 update_icon() isSwitchingStates = 0 diff --git a/code/game/objects/structures/misc.dm b/code/game/objects/structures/misc.dm index 3e9fba93105..1958cead39c 100644 --- a/code/game/objects/structures/misc.dm +++ b/code/game/objects/structures/misc.dm @@ -57,3 +57,19 @@ return else to_chat(user, "FĆAL �Rr�R: ŧer nt recgnized, c-cntr-r䣧-ç äcked.") + +/obj/structure/respawner + name = "\improper Long-Distance Cloning Machine" + desc = "Top-of-the-line Nanotrasen technology allows for cloning of crew members from off-station upon bluespace request." + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "borgcharger1(old)" + anchored = 1 + density = 1 + +/obj/structure/respawner/attack_ghost(mob/dead/observer/user as mob) + var/response = alert(user, "Are you sure you want to spawn like this?\n(If you do this, you won't be able to be cloned!)","Respawn?","Yes","No") + if(response == "Yes") + user.forceMove(get_turf(src)) + log_admin("[key_name(user)] was incarnated by a respawner machine.") + message_admins("[key_name_admin(user)] was incarnated by a respawner machine.") + user.incarnate_ghost() \ No newline at end of file diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 2a22ffd563c..69a4520ea5d 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -382,8 +382,8 @@ if(M.stat!=2) M.emote("scream") if(istype(user)) - M.attack_log += "\[[time_stamp()]\] Has been cremated by [user.name] ([user.ckey])" - user.attack_log +="\[[time_stamp()]\] Cremated [M.name] ([M.ckey])" + M.create_attack_log("Has been cremated by [user.name] ([user.ckey])") + user.create_attack_log("Cremated [M.name] ([M.ckey])") log_attack("[user.name] ([user.ckey]) cremated [M.name] ([M.ckey])") M.death(1) if(!M || !isnull(M.gcDestroyed)) diff --git a/code/game/objects/structures/spirit_board.dm b/code/game/objects/structures/spirit_board.dm index 25fe7f4a134..253f93dc7ae 100644 --- a/code/game/objects/structures/spirit_board.dm +++ b/code/game/objects/structures/spirit_board.dm @@ -55,11 +55,10 @@ //lighting check var/light_amount = 0 var/turf/T = get_turf(src) - var/atom/movable/lighting_overlay/LO = locate(/atom/movable/lighting_overlay) in T - if(LO) - light_amount = LO.get_clamped_lum(0.5)*10 + if(T) + light_amount = T.get_lumcount(0.5) * 10 else - light_amount = 10 + light_amount = 10 if(light_amount > 2) to_chat(M, "It's too bright here to use [src.name]!") diff --git a/code/game/response_team.dm b/code/game/response_team.dm index a4ca220e5dd..6cf81f70180 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -331,17 +331,17 @@ var/ert_request_answered = 0 M.equip_to_slot_or_del(pda, slot_wear_pda) /datum/response_team/proc/cannot_send_team() - command_announcement.Announce("[station_name()], we are unfortunately unable to send you an Emergency Response Team at this time.", "ERT Unavailable") + event_announcement.Announce("[station_name()], we are unfortunately unable to send you an Emergency Response Team at this time.", "ERT Unavailable") /datum/response_team/proc/announce_team() - command_announcement.Announce("Attention, [station_name()]. We are sending a team of highly trained assistants to aid(?) you. Standby.", "ERT En-Route") + event_announcement.Announce("Attention, [station_name()]. We are sending a team of highly trained assistants to aid(?) you. Standby.", "ERT En-Route") // -- AMBER TEAM -- /datum/response_team/amber /datum/response_team/amber/announce_team() - command_announcement.Announce("Attention, [station_name()]. We are sending a code AMBER light Emergency Response Team. Standby.", "ERT En-Route") + event_announcement.Announce("Attention, [station_name()]. We are sending a code AMBER light Emergency Response Team. Standby.", "ERT En-Route") /datum/response_team/amber/equip_officer(var/officer_type, var/mob/living/carbon/human/M) ..() @@ -413,7 +413,7 @@ var/ert_request_answered = 0 /datum/response_team/red /datum/response_team/red/announce_team() - command_announcement.Announce("Attention, [station_name()]. We are sending a code RED Emergency Response Team. Standby.", "ERT En-Route") + event_announcement.Announce("Attention, [station_name()]. We are sending a code RED Emergency Response Team. Standby.", "ERT En-Route") /datum/response_team/red/equip_officer(var/officer_type, var/mob/living/carbon/human/M) ..() @@ -498,7 +498,7 @@ var/ert_request_answered = 0 /datum/response_team/gamma /datum/response_team/gamma/announce_team() - command_announcement.Announce("Attention, [station_name()]. We are sending a code GAMMA elite Emergency Response Team. Standby.", "ERT En-Route") + event_announcement.Announce("Attention, [station_name()]. We are sending a code GAMMA elite Emergency Response Team. Standby.", "ERT En-Route") /datum/response_team/gamma/equip_officer(var/officer_type, var/mob/living/carbon/human/M) ..() diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index a328769d8dc..b09ef2c168e 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -43,7 +43,35 @@ new /obj/item/weapon/ore/glass(src) new /obj/item/weapon/ore/glass(src) //Make some sand if you shovel grass to_chat(user, "You shovel the grass.") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) make_plating() + +// NEEDS TO BE UPDATED +/turf/simulated/floor/basalt //By your powers combined, I am captain planet + name = "volcanic floor" + icon = 'icons/turf/floors.dmi' + icon_state = "basalt0" + oxygen = 14 + nitrogen = 23 + temperature = 300 + +/turf/simulated/floor/basalt/attackby(obj/item/W, mob/user, params) + if(..()) + return + if(istype(W, /obj/item/weapon/shovel)) + new /obj/item/weapon/ore/glass/basalt(src) + new /obj/item/weapon/ore/glass/basalt(src) + user.visible_message("[user] digs up [src].", "You uproot [src].") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + make_plating() + +/turf/simulated/floor/basalt/New() + ..() + if(prob(15)) + icon_state = "basalt[rand(0, 12)]" + switch(icon_state) + if("basalt1", "basalt2", "basalt3") + set_light(1, 1) /turf/simulated/floor/carpet name = "Carpet" diff --git a/code/game/turfs/simulated/floor/mineral.dm b/code/game/turfs/simulated/floor/mineral.dm index 9ef70522ec4..f4f67b9007b 100644 --- a/code/game/turfs/simulated/floor/mineral.dm +++ b/code/game/turfs/simulated/floor/mineral.dm @@ -1,10 +1,18 @@ +/* In this file: + * + * Plasma floor + * Gold floor + * Silver floor + * Bananium floor + * Diamond floor + * Uranium floor + */ + /turf/simulated/floor/mineral name = "mineral floor" icon_state = "" var/list/icons = list() - - /turf/simulated/floor/mineral/New() ..() broken_states = list("[initial(icon_state)]_dam") @@ -13,9 +21,145 @@ if(!..()) return 0 if(!broken && !burnt) - if( !(icon_state in icons) ) + if(!(icon_state in icons)) icon_state = initial(icon_state) +//PLASMA +/turf/simulated/floor/mineral/plasma + name = "plasma floor" + icon_state = "plasma" + floor_tile = /obj/item/stack/tile/mineral/plasma + icons = list("plasma","plasma_dam") + +/turf/simulated/floor/mineral/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300) + PlasmaBurn() + +/turf/simulated/floor/mineral/plasma/attackby(obj/item/weapon/W, mob/user, params) + if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite + message_admins("Plasma flooring was ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) + log_game("Plasma flooring was ignited by [key_name(user)] in ([x],[y],[z])") + ignite(is_hot(W)) + return + ..() + +/turf/simulated/floor/mineral/plasma/proc/PlasmaBurn() + make_plating() + atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 20) + +/turf/simulated/floor/mineral/plasma/proc/ignite(exposed_temperature) + if(exposed_temperature > 300) + PlasmaBurn() + +//GOLD +/turf/simulated/floor/mineral/gold + name = "gold floor" + icon_state = "gold" + floor_tile = /obj/item/stack/tile/mineral/gold + icons = list("gold","gold_dam") + +//SILVER +/turf/simulated/floor/mineral/silver + name = "silver floor" + icon_state = "silver" + floor_tile = /obj/item/stack/tile/mineral/silver + icons = list("silver","silver_dam") + +//BANANIUM +/turf/simulated/floor/mineral/bananium + name = "bananium floor" + icon_state = "bananium" + floor_tile = /obj/item/stack/tile/mineral/bananium + icons = list("bananium","bananium_dam") + var/spam_flag = 0 + +/turf/simulated/floor/mineral/bananium/Entered(mob/AM) + .=..() + if(!.) + if(istype(AM)) + squeek() + +/turf/simulated/floor/mineral/bananium/attackby(obj/item/weapon/W, mob/user, params) + .=..() + if(!.) + honk() + +/turf/simulated/floor/mineral/bananium/attack_hand(mob/user) + .=..() + if(!.) + honk() + +/turf/simulated/floor/mineral/bananium/proc/honk() + if(!spam_flag) + spam_flag = 1 + playsound(src, 'sound/items/bikehorn.ogg', 50, 1) + spawn(20) + spam_flag = 0 + +/turf/simulated/floor/mineral/bananium/proc/squeek() + if(!spam_flag) + spam_flag = 1 + playsound(src, "clownstep", 50, 1) + spawn(10) + spam_flag = 0 + +/turf/simulated/floor/mineral/bananium/airless + oxygen = 0.01 + nitrogen = 0.01 + temperature = TCMB + +//TRANQUILLITE +/turf/simulated/floor/mineral/tranquillite + name = "silent floor" + icon_state = "tranquillite" + floor_tile = /obj/item/stack/tile/mineral/tranquillite + shoe_running_volume = 0 + shoe_walking_volume = 0 + +//DIAMOND +/turf/simulated/floor/mineral/diamond + name = "diamond floor" + icon_state = "diamond" + floor_tile = /obj/item/stack/tile/mineral/diamond + icons = list("diamond","diamond_dam") + +//URANIUM +/turf/simulated/floor/mineral/uranium + name = "uranium floor" + icon_state = "uranium" + floor_tile = /obj/item/stack/tile/mineral/uranium + icons = list("uranium","uranium_dam") + var/last_event = 0 + var/active = null + +/turf/simulated/floor/mineral/uranium/Entered(mob/AM) + .=..() + if(!.) + if(istype(AM)) + radiate() + +/turf/simulated/floor/mineral/uranium/attackby(obj/item/weapon/W, mob/user, params) + .=..() + if(!.) + radiate() + +/turf/simulated/floor/mineral/uranium/attack_hand(mob/user) + .=..() + if(!.) + radiate() + +/turf/simulated/floor/mineral/uranium/proc/radiate() + if(!active) + if(world.time > last_event+15) + active = 1 + for(var/mob/living/L in range(3,src)) + L.apply_effect(1,IRRADIATE,0) + for(var/turf/simulated/floor/mineral/uranium/T in orange(1,src)) + T.radiate() + last_event = world.time + active = 0 + return + // ALIEN ALLOY /turf/simulated/floor/mineral/abductor name = "alien floor" @@ -36,7 +180,6 @@ /turf/simulated/floor/mineral/abductor/make_plating() return ChangeTurf(/turf/simulated/floor/plating/abductor2) - /turf/simulated/floor/plating/abductor2 name = "alien plating" icon_state = "alienplating" diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 1a307361341..3491f4d529a 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -66,10 +66,3 @@ /turf/simulated/floor/noslip/MakeSlippery() return - -/turf/simulated/floor/silent - name = "silent floor" - icon_state = "silent" - floor_tile = /obj/item/stack/tile/silent - shoe_running_volume = 0 - shoe_walking_volume = 0 \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm index f5aa6198467..cbb5647f283 100644 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ b/code/game/turfs/simulated/floor/plasteel_floor.dm @@ -10,6 +10,16 @@ if(!broken && !burnt) icon_state = icon_regular_floor +/turf/simulated/floor/plasteel/airless + name = "airless floor" + oxygen = 0.01 + nitrogen = 0.01 + temperature = TCMB + +/turf/simulated/floor/plasteel/airless/New() + ..() + name = "floor" + /turf/simulated/floor/plasteel/goonplaque icon_state = "plaque" name = "Commemorative Plaque" diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index c6b51a05067..e9770536b73 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -76,12 +76,6 @@ ..() name = "plating" -/turf/simulated/floor/plating/airless/catwalk - icon = 'icons/turf/catwalks.dmi' - icon_state = "Floor3" - name = "catwalk" - desc = "Cats really don't like these things." - /turf/simulated/floor/engine name = "reinforced floor" icon_state = "engine" @@ -294,16 +288,6 @@ /turf/simulated/floor/plating/metalfoam/proc/smash() ChangeTurf(/turf/space) -/turf/simulated/floor/plasteel/airless - name = "airless floor" - oxygen = 0.01 - nitrogen = 0.01 - temperature = TCMB - -/turf/simulated/floor/plasteel/airless/New() - ..() - name = "floor" - /turf/simulated/floor/plating/abductor name = "alien floor" icon_state = "alienpod1" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index fa67573307c..69b0df22ae3 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -4,6 +4,7 @@ luminosity = 1 var/intact = 1 + var/turf/baseturf = /turf/space var/slowdown = 0 //negative for faster, positive for slower //Properties for open tiles (/floor) @@ -23,8 +24,6 @@ var/PathNode/PNode = null //associated PathNode in the A* algorithm - var/dynamic_lighting = 1 - flags = 0 var/image/obscured //camerachunks @@ -160,10 +159,11 @@ return src var/old_opacity = opacity var/old_dynamic_lighting = dynamic_lighting - var/list/old_affecting_lights = affecting_lights + var/old_affecting_lights = affecting_lights var/old_lighting_overlay = lighting_overlay var/old_blueprint_data = blueprint_data var/old_obscured = obscured + var/old_corners = corners BeforeChange() if(air_master) @@ -177,16 +177,19 @@ for(var/turf/space/S in range(W,1)) S.update_starlight() - lighting_overlay = old_lighting_overlay + recalc_atom_opacity() - affecting_lights = old_affecting_lights - if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting)) - reconsider_lights() - if(dynamic_lighting != old_dynamic_lighting) - if(dynamic_lighting) - lighting_build_overlays() - else - lighting_clear_overlays() + if(lighting_overlays_initialised) + lighting_overlay = old_lighting_overlay + affecting_lights = old_affecting_lights + corners = old_corners + if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting)) + reconsider_lights() + if(dynamic_lighting != old_dynamic_lighting) + if(dynamic_lighting) + lighting_build_overlay() + else + lighting_clear_overlay() obscured = old_obscured @@ -383,11 +386,6 @@ if(ticker) cameranet.updateVisibility(src) -/turf/proc/get_lumcount() //Gets the lighting level of a given turf. - if(lighting_overlay) - return lighting_overlay.get_clamped_lum() - return 1 - /turf/attackby(obj/item/C, mob/user, params) if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/coil = C diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index 38abe4b5fd0..e3bb99d52fe 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -79,6 +79,9 @@ var/global/admin_ooc_colour = "#b82e00" else display_name = holder.fakekey + if(!config.disable_ooc_emoji) + msg = "[msg]" + to_chat(C, "OOC: [display_name]: [msg]") /proc/toggle_ooc() diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index 31c8c322596..896bd2b850d 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -77,6 +77,10 @@ if(held_item) var/damagetype = held_item.suicide_act(src) if(damagetype) + if(damagetype & SHAME) + adjustStaminaLoss(200) + suiciding = 0 + return do_suicide(damagetype, held_item) return diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 88a0c7708f0..cb00562be9c 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -614,6 +614,19 @@ var/global/nologevent = 0 message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1) feedback_add_details("admin_verb","TDOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/toggleemoji() + set category = "Server" + set desc = "Toggle OOC Emoji" + set name = "Toggle OOC Emoji" + + if(!check_rights(R_ADMIN)) + return + + config.disable_ooc_emoji = !(config.disable_ooc_emoji) + log_admin("[key_name(usr)] toggled OOC Emoji.") + message_admins("[key_name_admin(usr)] toggled OOC Emoji.", 1) + feedback_add_details("admin_verb", "TEMOJ") + /datum/admins/proc/startnow() set category = "Server" set desc="Start the round RIGHT NOW" @@ -794,7 +807,8 @@ var/global/nologevent = 0 var/turf/T = get_turf(usr.loc) T.ChangeTurf(chosen) else - new chosen(usr.loc) + var/atom/A = new chosen(usr.loc) + A.admin_spawned = TRUE log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])") feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c56b3c7404f..6b2224962f5 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -48,6 +48,7 @@ var/list/admin_verbs_admin = list( /datum/admins/proc/togglelooc, /*toggles looc on/off for everyone*/ /datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/ /datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/ + /datum/admins/proc/toggleemoji, /*toggles using emoji in ooc for everyone*/ /client/proc/game_panel, /*game panel, allows to change game-mode etc*/ /client/proc/cmd_admin_say, /*admin-only ooc chat*/ /datum/admins/proc/PlayerNotes, @@ -163,7 +164,9 @@ var/list/admin_verbs_debug = list( /client/proc/map_template_upload, /client/proc/view_runtimes, /client/proc/admin_serialize, - /client/proc/admin_deserialize + /client/proc/admin_deserialize, + /client/proc/jump_to_ruin, + /client/proc/toggle_medal_disable ) var/list/admin_verbs_possess = list( /proc/possess, diff --git a/code/modules/admin/buildmode.dm b/code/modules/admin/buildmode.dm index 72461ed6ae1..32bdfa135b5 100644 --- a/code/modules/admin/buildmode.dm +++ b/code/modules/admin/buildmode.dm @@ -446,22 +446,8 @@ log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])") new/obj/machinery/door/airlock(get_turf(object)) else if(istype(object,/turf) && ctrl_click && left_click) - switch(build_dir) - if(NORTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.dir = NORTH - if(SOUTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.dir = SOUTH - if(EAST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.dir = EAST - if(WEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.dir = WEST - if(NORTHWEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.dir = NORTHWEST + var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) + WIN.setDir(build_dir) log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])") if(ADV_BUILDMODE) @@ -472,7 +458,7 @@ T.ChangeTurf(objholder) else var/obj/A = new objholder (get_turf(object)) - A.dir = build_dir + A.setDir(build_dir) log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]") else if(right_click) if(isobj(object)) @@ -561,7 +547,7 @@ T.ChangeTurf(objholder) else var/obj/A = new objholder(T) - A.dir = build_dir + A.setDir(build_dir) deselect_region() return diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 631b621528f..8e98e238fee 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -393,8 +393,11 @@ logout_status = " (snpc)" else logout_status = M.client ? "" : " (logged out)" + var/dname = M.real_name + if(!dname) + dname = M - return {"[M.real_name][caption][logout_status][M.stat == 2 ? " (DEAD)" : ""] + return {"[dname][caption][logout_status][M.stat == 2 ? " (DEAD)" : ""] PM[close ? "" : ""]"} /datum/admins/proc/check_antagonists() @@ -424,7 +427,7 @@ else dat += "Nuclear Operative not found!" dat += "
" - for(var/obj/item/weapon/disk/nuclear/N in world) + for(var/obj/item/weapon/disk/nuclear/N in poi_list) dat += "" if(can_collar) dat += "" - dat += "" + dat += "" dat += {"
Nuclear Disk(s)
[N.name], " var/atom/disk_loc = N.loc while(!istype(disk_loc, /turf)) @@ -489,6 +492,11 @@ if(ticker.mode.cult.len) dat += check_role_table("Cultists", ticker.mode.cult, 0) + dat += "
use Cult Mindspeak" + if(GAMEMODE_IS_CULT) + var/datum/game_mode/cult/cult_round = ticker.mode + if(!cult_round.narsie_condition_cleared) + dat += "
complete objective (debug)" if(ticker.mode.traitors.len) dat += check_role_table("Traitors", ticker.mode.traitors) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1efb3567828..4a01b1161e8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1533,6 +1533,34 @@ else if(href_list["check_antagonist"]) check_antagonists() + else if(href_list["cult_nextobj"]) + if(alert(usr, "Validate the current Cult objective and unlock the next one?", "Cult Cheat Code", "Yes", "No") != "Yes") + return + + if(!GAMEMODE_IS_CULT) + alert("Couldn't locate cult mode datum! This shouldn't ever happen, tell a coder!") + return + + var/datum/game_mode/cult/cult_round = ticker.mode + cult_round.bypass_phase() + message_admins("Admin [key_name_admin(usr)] has unlocked the Cult's next objective.") + log_admin("Admin [key_name_admin(usr)] has unlocked the Cult's next objective.") + + else if(href_list["cult_mindspeak"]) + var/input = stripped_input(usr, "Communicate to all the cultists with the voice of [ticker.mode.cultdat.entity_name]", "Voice of [ticker.mode.cultdat.entity_name]", "") + if(!input) + return + + for(var/datum/mind/H in ticker.mode.cult) + if (H.current) + to_chat(H.current, "[ticker.mode.cultdat.entity_name] murmurs, [input]") + + for(var/mob/dead/observer/O in player_list) + to_chat(O, "[ticker.mode.cultdat.entity_name] murmurs, [input]") + + message_admins("Admin [key_name_admin(usr)] has talked with the Voice of [ticker.mode.cultdat.entity_name].") + log_admin("[key_name(usr)] Voice of [ticker.mode.cultdat.entity_name]: [input]") + else if(href_list["adminplayerobservecoodjump"]) if(!check_rights(R_ADMIN)) return @@ -2145,6 +2173,7 @@ else var/atom/O = new path(target) if(O) + O.admin_spawned = TRUE O.dir = obj_dir if(obj_name) O.name = obj_name @@ -2277,11 +2306,11 @@ if(gravity_is_on) log_admin("[key_name(usr)] toggled gravity on.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity on.", 1) - command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") + event_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.") else log_admin("[key_name(usr)] toggled gravity off.", 1) message_admins("\blue [key_name_admin(usr)] toggled gravity off.", 1) - command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") + event_announcement.Announce("Feedback surge detected in mass-distributions systems. Artifical gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.") if("power") feedback_inc("admin_secrets_fun_used",1) @@ -2553,7 +2582,7 @@ if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) W.req_access = list() message_admins("[key_name_admin(usr)] activated Egalitarian Station mode") - command_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg') + event_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg') if("onlyone") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","OO") diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index c17671995ff..73b481bbc6b 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -119,6 +119,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," for(var/client/X in modholders + adminholders) if(X.prefs.sound & SOUND_ADMINHELP) X << 'sound/effects/adminhelp.ogg' + window_flash(X) to_chat(X, msg) //show it to the person adminhelping too diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 63241ce43c5..5de3178e7ff 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -133,6 +133,7 @@ if(holder && !C.holder) recieve_message = "-- Click the [recieve_pm_type]'s name to reply --\n" if(C.adminhelped) + window_flash(C) to_chat(C, recieve_message) C.adminhelped = 0 @@ -149,6 +150,9 @@ adminhelp(reply) //sender has left, adminhelp instead return + // for emoji, we have to define a specific span for jquery to look for + msg = "[msg]" + recieve_message = "[type] from-[recieve_pm_type][key_name(src, C, C.holder ? 1 : 0, type)]: [msg]" to_chat(C, recieve_message) to_chat(src, "[send_pm_type][type] to-[key_name(C, src, holder ? 1 : 0, type)]: [msg]") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 862eed1b986..59ea8992889 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1474,3 +1474,57 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that return error_cache.showTo(usr) + +/client/proc/jump_to_ruin() + set category = "Debug" + set name = "Jump to Ruin" + set desc = "Displays a list of all placed ruins to teleport to." + + if(!check_rights(R_DEBUG)) + return + + var/list/names = list() + for(var/i in ruin_landmarks) + var/obj/effect/landmark/ruin/ruin_landmark = i + var/datum/map_template/ruin/template = ruin_landmark.ruin_template + + var/count = 1 + var/name = template.name + var/original_name = name + + while(name in names) + count++ + name = "[original_name] ([count])" + + names[name] = ruin_landmark + + var/ruinname = input("Select ruin", "Jump to Ruin") as null|anything in names + + var/obj/effect/landmark/ruin/landmark = names[ruinname] + + if(istype(landmark)) + var/datum/map_template/ruin/template = landmark.ruin_template + admin_forcemove(usr, get_turf(landmark)) + + to_chat(usr, "[template.name]") + to_chat(usr, "[template.description]") + + log_admin("[key_name(usr)] jumped to ruin [ruinname]") + if(!isobserver(usr)) + message_admins("[key_name_admin(usr)] jumped to ruin [ruinname]", 1) + + feedback_add_details("admin_verb","JT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/toggle_medal_disable() + set category = "Debug" + set name = "Toggle Medal Disable" + set desc = "Toggles the safety lock on trying to contact the medal hub." + + if(!check_rights(R_DEBUG)) + return + + global.medals_enabled = !global.medals_enabled + + message_admins("[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") + feedback_add_details("admin_verb","TMH") // If... + log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index bfc4f7a8887..5a53b0201b3 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -30,6 +30,12 @@ var/intercom_range_display_status = 0 src.pixel_x = -224 src.pixel_y = -224 +/obj/effect/debugging/mapfix_marker + name = "map fix marker" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "mapfixmarker" + desc = "I am a mappers mistake." + /obj/effect/debugging/marker icon = 'icons/turf/areas.dmi' icon_state = "yellow" diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm index c416f224cf9..c7b2d6d537e 100644 --- a/code/modules/admin/verbs/massmodvar.dm +++ b/code/modules/admin/verbs/massmodvar.dm @@ -137,32 +137,38 @@ for(var/mob/M in mob_list) if( istype(M , O.type) ) M.vars[variable] = O.vars[variable] + M.on_varedit(variable) else if(istype(O, /obj)) for(var/obj/A in world) if( istype(A , O.type) ) A.vars[variable] = O.vars[variable] + A.on_varedit(variable) else if(istype(O, /turf)) for(var/turf/A in world) if( istype(A , O.type) ) A.vars[variable] = O.vars[variable] + A.on_varedit(variable) else if(istype(O, /mob)) for(var/mob/M in mob_list) if(M.type == O.type) M.vars[variable] = O.vars[variable] + M.on_varedit(variable) else if(istype(O, /obj)) for(var/obj/A in world) if(A.type == O.type) A.vars[variable] = O.vars[variable] + A.on_varedit(variable) else if(istype(O, /turf)) for(var/turf/A in world) if(A.type == O.type) A.vars[variable] = O.vars[variable] + A.on_varedit(variable) if("edit referenced object") return .(O.vars[variable]) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 0be55889bc2..8cce4c5a761 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -131,7 +131,7 @@ var/list/forbidden_varedit_object_types = list( L[var_value] = mod_list_add_ass() //haha if("No") L += var_value - + /client/proc/mod_list(var/list/L) if(!check_rights(R_VAREDIT)) return @@ -440,6 +440,7 @@ var/list/forbidden_varedit_object_types = list( if(var_as_text == null) var_as_text = "[O.vars[variable]]" + O.on_varedit(variable) log_to_dd("### VarEdit by [src]: [O.type] [variable]=[html_encode("[var_as_text]")]") log_admin("[key_name(src)] modified [original_name]'s [variable] to [var_as_text]") message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [var_as_text]", 1) diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index 6b6eb863b45..1da3d3bfc55 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -58,7 +58,7 @@ if(reload_cooldown > delta) return 1 - command_announcement.Announce("Bluespace artillery fire detected. Brace for impact.") + event_announcement.Announce("Bluespace artillery fire detected. Brace for impact.") message_admins("[key_name_admin(usr)] has launched an artillery strike.", 1) var/list/L = list() for(var/turf/T in get_area_turfs(targetarea.type)) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index b2864d1c7cc..4c050e0d4f3 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -26,6 +26,8 @@ var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID var/timeofdeath = null var/coffin = 0 + var/brute_damage = 0 + var/oxy_damage = 0 /obj/effect/landmark/corpse/initialize() if(istype(src,/obj/effect/landmark/corpse/clown)) @@ -37,34 +39,36 @@ var/mob/living/carbon/human/human/M = new /mob/living/carbon/human/human (src.loc) M.real_name = src.name M.death(1) //Kills the new mob + M.adjustOxyLoss(oxy_damage) + M.adjustBruteLoss(brute_damage) M.timeofdeath = timeofdeath - if(src.mob_species) - M.set_species(src.mob_species) - if(src.corpseuniform) - M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform) - if(src.corpsesuit) - M.equip_to_slot_or_del(new src.corpsesuit(M), slot_wear_suit) - if(src.corpseshoes) - M.equip_to_slot_or_del(new src.corpseshoes(M), slot_shoes) - if(src.corpsegloves) - M.equip_to_slot_or_del(new src.corpsegloves(M), slot_gloves) - if(src.corpseradio) - M.equip_to_slot_or_del(new src.corpseradio(M), slot_l_ear) - if(src.corpseglasses) - M.equip_to_slot_or_del(new src.corpseglasses(M), slot_glasses) - if(src.corpsemask) - M.equip_to_slot_or_del(new src.corpsemask(M), slot_wear_mask) - if(src.corpsehelmet) - M.equip_to_slot_or_del(new src.corpsehelmet(M), slot_head) - if(src.corpsebelt) - M.equip_to_slot_or_del(new src.corpsebelt(M), slot_belt) - if(src.corpsepocket1) - M.equip_to_slot_or_del(new src.corpsepocket1(M), slot_r_store) - if(src.corpsepocket2) - M.equip_to_slot_or_del(new src.corpsepocket2(M), slot_l_store) - if(src.corpseback) - M.equip_to_slot_or_del(new src.corpseback(M), slot_back) - if(src.corpseid == 1) + if(mob_species) + M.set_species(mob_species) + if(corpseuniform) + M.equip_to_slot_or_del(new corpseuniform(M), slot_w_uniform) + if(corpsesuit) + M.equip_to_slot_or_del(new corpsesuit(M), slot_wear_suit) + if(corpseshoes) + M.equip_to_slot_or_del(new corpseshoes(M), slot_shoes) + if(corpsegloves) + M.equip_to_slot_or_del(new corpsegloves(M), slot_gloves) + if(corpseradio) + M.equip_to_slot_or_del(new corpseradio(M), slot_l_ear) + if(corpseglasses) + M.equip_to_slot_or_del(new corpseglasses(M), slot_glasses) + if(corpsemask) + M.equip_to_slot_or_del(new corpsemask(M), slot_wear_mask) + if(corpsehelmet) + M.equip_to_slot_or_del(new corpsehelmet(M), slot_head) + if(corpsebelt) + M.equip_to_slot_or_del(new corpsebelt(M), slot_belt) + if(corpsepocket1) + M.equip_to_slot_or_del(new corpsepocket1(M), slot_r_store) + if(corpsepocket2) + M.equip_to_slot_or_del(new corpsepocket2(M), slot_l_store) + if(corpseback) + M.equip_to_slot_or_del(new corpseback(M), slot_back) + if(corpseid == 1) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" var/datum/job/jobdatum @@ -73,9 +77,9 @@ if(J.title == corpseidaccess) jobdatum = J break - if(src.corpseidicon) + if(corpseidicon) W.icon_state = corpseidicon - if(src.corpseidaccess) + if(corpseidaccess) if(jobdatum) W.access = jobdatum.get_access() else @@ -84,18 +88,14 @@ W.assignment = corpseidjob W.registered_name = M.real_name M.equip_to_slot_or_del(W, slot_wear_id) - if(src.coffin == 1) + if(coffin == 1) var/obj/structure/closet/coffin/sarcophagus/sarc = locate(/obj/structure/closet/coffin/sarcophagus) in loc if(sarc) M.loc = sarc qdel(src) - - // I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example. - - - - +/obj/effect/landmark/corpse/damaged + brute_damage = 1000 /obj/effect/landmark/corpse/syndicatesoldier name = "Syndicate Operative" diff --git a/code/modules/awaymissions/mission_code/clownplanet.dm b/code/modules/awaymissions/mission_code/clownplanet.dm index 359037ada0a..8d64d3074d2 100644 --- a/code/modules/awaymissions/mission_code/clownplanet.dm +++ b/code/modules/awaymissions/mission_code/clownplanet.dm @@ -4,10 +4,10 @@ name = "\improper Clown Planet" icon_state = "honk" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 requires_power = 0 report_alerts = 0 - + /area/awaymission/clownplanet/miningtown name = "\improper Clown Planet - Bananium-o-Rama" icon_state = "away1" diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index b12ee063f2d..d340fc6a651 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -13,13 +13,6 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away air_master.setup_allturfs(turfs) log_debug("\tTook [stop_watch(subtimer)]s") - subtimer = start_watch() - log_debug("Initializing lighting") - for(var/turf/T in turfs) - if(T.dynamic_lighting) - T.lighting_build_overlays() - log_debug("\tTook [stop_watch(subtimer)]s") - subtimer = start_watch() log_debug("Smoothing tiles") for(var/turf/T in smoothTurfs) @@ -205,7 +198,17 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away template = safepick(possible_ruins) if(!template) return 0 + var/turf/central_turf = get_turf(src) + for(var/i in template.get_affected_turfs(central_turf, 1)) + var/turf/T = i + for(var/mob/living/simple_animal/monster in T) + qdel(monster) + for(var/obj/structure/flora/ash/plant in T) + qdel(plant) template.load(get_turf(src),centered = 1) template.loaded++ + var/datum/map_template/ruin = template + if(istype(ruin)) + new /obj/effect/landmark/ruin(central_turf, ruin) qdel(src) return 1 diff --git a/code/modules/awaymissions/zvis.dm b/code/modules/awaymissions/zvis.dm index 06d60f3389f..735dd307ddb 100644 --- a/code/modules/awaymissions/zvis.dm +++ b/code/modules/awaymissions/zvis.dm @@ -1,7 +1,7 @@ /area/awaymission/upperlevel name = "Open Space" color = "#888" - lighting_use_dynamic = 0 + dynamic_lighting = 0 requires_power = 0 // Used by /turf/unsimulated/floor/upperlevel as a reference for where the other floor is diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 6e1fe9126fd..8f8d26efebe 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -232,6 +232,10 @@ to_chat(src, "Become a BYOND member to access member-perks and features, as well as support the engine that makes this game possible. Click here to find out more.") return 0 return 1 + +//Like for /atoms, but clients are their own snowflake FUCK +/client/proc/setDir(newdir) + dir = newdir /client/proc/handle_spam_prevention(var/message, var/mute_type, var/throttle = 0) if(throttle) @@ -621,3 +625,6 @@ if(lang.flags & RESTRICTED) message += " (RESTRICTED)" to_chat(world, "[message]") + +/client/proc/colour_transition(var/list/colour_to = null, var/time = 10) //Call this with no parameters to reset to default. + animate(src, color=colour_to, time=time, easing=SINE_EASING) diff --git a/code/modules/client/preference/loadout/loadout_hat.dm b/code/modules/client/preference/loadout/loadout_hat.dm index e5f8c158092..7e4ca4620d9 100644 --- a/code/modules/client/preference/loadout/loadout_hat.dm +++ b/code/modules/client/preference/loadout/loadout_hat.dm @@ -117,3 +117,13 @@ display_name = "science beret" path = /obj/item/clothing/head/beret/sci allowed_roles = list("Research Director", "Scientist") + +/datum/gear/hat/surgicalcap_purple + display_name = "surgical cap, purple" + path = /obj/item/clothing/head/surgery/purple + allowed_roles = list("Chief Medical Officer", "Medical Doctor") + +/datum/gear/hat/surgicalcap_green + display_name = "surgical cap, green" + path = /obj/item/clothing/head/surgery/green + allowed_roles = list("Chief Medical Officer", "Medical Doctor") \ No newline at end of file diff --git a/code/modules/client/preference/loadout/loadout_uniform.dm b/code/modules/client/preference/loadout/loadout_uniform.dm index aaec97829c8..d7df4da720b 100644 --- a/code/modules/client/preference/loadout/loadout_uniform.dm +++ b/code/modules/client/preference/loadout/loadout_uniform.dm @@ -98,6 +98,19 @@ path = /obj/item/clothing/under/rank/head_of_security/skirt allowed_roles = list("Head of Security") +/datum/gear/uniform/medical + subtype_path = /datum/gear/uniform/medical + +/datum/gear/uniform/medical/pscrubs + display_name = "medical scrubs, purple" + path = /obj/item/clothing/under/rank/medical/purple + allowed_roles = list("Chief Medical Officer", "Medical Doctor") + +/datum/gear/uniform/medical/gscrubs + display_name = "medical scrubs, green" + path = /obj/item/clothing/under/rank/medical/green + allowed_roles = list("Chief Medical Officer", "Medical Doctor") + /datum/gear/uniform/sec subtype_path = /datum/gear/uniform/sec diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index bf139ee4c8b..764e88f02fa 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -23,6 +23,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts // ROLE_GANG = 21, ROLE_BORER = 21, ROLE_NINJA = 21, + ROLE_GSPIDER = 21, ROLE_ABDUCTOR = 30, ) @@ -92,6 +93,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts var/show_ghostitem_attack = TRUE var/UI_style_color = "#ffffff" var/UI_style_alpha = 255 + var/windowflashing = TRUE //character preferences @@ -417,6 +419,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "

General Settings

" dat += "Fancy NanoUI: [(nanoui_fancy) ? "Yes" : "No"]
" dat += "Ghost-Item Attack Animation: [(show_ghostitem_attack) ? "Yes" : "No"]
" + dat += "Window Flashing: [(windowflashing) ? "Yes" : "No"]
" dat += "Custom UI settings:
" dat += " - UI Style: [UI_style]
" dat += " - Color: [UI_style_color]
__

" @@ -814,6 +817,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures") HTML += ShowDisabilityState(user,DISABILITY_FLAG_DEAF,"Deaf") HTML += ShowDisabilityState(user,DISABILITY_FLAG_BLIND,"Blind") + HTML += ShowDisabilityState(user,DISABILITY_FLAG_COLOURBLIND,"Colourblind") HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute") @@ -1336,9 +1340,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts //Reset prosthetics. organ_data = list() rlimb_data = list() - if("speciesprefs")//oldvox code - speciesprefs = !speciesprefs - + if("speciesprefs") + speciesprefs = !speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0. if("language") // var/languages_available var/list/new_languages = list("None") @@ -1934,6 +1937,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("ghost_att_anim") show_ghostitem_attack = !show_ghostitem_attack + if("winflash") + windowflashing = !windowflashing + 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 @@ -1962,6 +1968,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("randomslot") randomslot = !randomslot + if(isnewplayer(usr)) + var/mob/new_player/N = usr + N.new_player_panel_proc() if("hear_midis") sound ^= SOUND_MIDI @@ -2145,35 +2154,31 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT) character.dna.SetSEState(FATBLOCK,1,1) - character.mutations += FAT - character.mutations += OBESITY character.overeatduration = 600 if(disabilities & DISABILITY_FLAG_NEARSIGHTED) character.dna.SetSEState(GLASSESBLOCK,1,1) - character.disabilities |= NEARSIGHTED if(disabilities & DISABILITY_FLAG_EPILEPTIC) character.dna.SetSEState(EPILEPSYBLOCK,1,1) - character.disabilities |= EPILEPSY if(disabilities & DISABILITY_FLAG_DEAF) character.dna.SetSEState(DEAFBLOCK,1,1) - character.disabilities |= DEAF if(disabilities & DISABILITY_FLAG_BLIND) character.dna.SetSEState(BLINDBLOCK,1,1) - character.disabilities |= BLIND + + if(disabilities & DISABILITY_FLAG_COLOURBLIND) + character.dna.SetSEState(COLOURBLINDBLOCK,1,1) if(disabilities & DISABILITY_FLAG_MUTE) character.dna.SetSEState(MUTEBLOCK,1,1) - character.disabilities |= MUTE S.handle_dna(character) if(character.dna.dirtySE) character.dna.UpdateSE() - domutcheck(character, null, MUTCHK_FORCED) + domutcheck(character, null, MUTCHK_FORCED) //'Activates' all the above disabilities. character.dna.ready_dna(character, flatten_SE = 0) character.sync_organ_dna(assimilate=1) @@ -2187,26 +2192,26 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts /datum/preferences/proc/open_load_dialog(mob/user) var/DBQuery/query = dbcon.NewQuery("SELECT slot,real_name FROM [format_table_name("characters")] WHERE ckey='[user.ckey]' ORDER BY slot") + var/list/slotnames[max_save_slots] + + if(!query.Execute()) + var/err = query.ErrorMsg() + log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n") + message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n") + return + while(query.NextRow()) + slotnames[text2num(query.item[1])] = query.item[2] var/dat = "" dat += "
" dat += "Select a character slot to load
" var/name - for(var/i=1, i<=max_save_slots, i++) - if(!query.Execute()) - var/err = query.ErrorMsg() - log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n") - message_admins("SQL ERROR during character slot loading. Error : \[[err]\]\n") - return - while(query.NextRow()) - if(i==text2num(query.item[1])) - name = query.item[2] - if(!name) name = "Character[i]" - if(i==default_slot) + for(var/i in 1 to max_save_slots) + name = slotnames[i] || "Character [i]" + if(i == default_slot) name = "[name]" dat += "[name]
" - name = null dat += "
" dat += "Close
" diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index 581daf222d3..f00c9f5d735 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -14,7 +14,8 @@ nanoui_fancy, show_ghostitem_attack, lastchangelog, - exp + exp, + windowflashing FROM [format_table_name("player")] WHERE ckey='[C.ckey]'"} ) @@ -42,6 +43,7 @@ show_ghostitem_attack = text2num(query.item[12]) lastchangelog = query.item[13] exp = query.item[14] + windowflashing = text2num(query.item[15]) //Sanitize ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor)) @@ -57,6 +59,7 @@ show_ghostitem_attack = sanitize_integer(show_ghostitem_attack, 0, 1, initial(show_ghostitem_attack)) lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog)) exp = sanitize_text(exp, initial(exp)) + windowflashing = sanitize_integer(windowflashing, 0, 1, initial(windowflashing)) return 1 /datum/preferences/proc/save_preferences(client/C) @@ -263,7 +266,7 @@ //Sanitize metadata = sanitize_text(metadata, initial(metadata)) - real_name = reject_bad_name(real_name) + real_name = reject_bad_name(real_name, 1) if(isnull(species)) species = "Human" if(isnull(language)) language = "None" if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation) @@ -500,21 +503,24 @@ return return 1 -/* -/datum/preferences/proc/random_character(client/C) +/datum/preferences/proc/load_random_character_slot(client/C) var/DBQuery/query = dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' ORDER BY slot") + var/list/saves = list() + + if(!query.Execute()) + var/err = query.ErrorMsg() + log_game("SQL ERROR during random character slot picking. Error : \[[err]\]\n") + message_admins("SQL ERROR during random character slot picking. Error : \[[err]\]\n") + return while(query.NextRow()) - var/list/saves = list() - for(var/i=1, i<=MAX_SAVE_SLOTS, i++) - if(i==text2num(query.item[1])) - saves += i + saves += text2num(query.item[1]) if(!saves.len) load_character(C) return 0 load_character(C,pick(saves)) - return 1*/ + return 1 /datum/preferences/proc/SetChangelog(client/C,hash) lastchangelog=hash diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 078f83f506a..c80c13d514b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -193,8 +193,9 @@ BLIND // can't see anything "Drask" = 'icons/mob/species/drask/gloves.dmi' ) -/obj/item/clothing/gloves/proc/Touch() - return +// Called just before an attack_hand(), in mob/UnarmedAttack() +/obj/item/clothing/gloves/proc/Touch(atom/A, proximity) + return 0 // return 1 to cancel attack_hand() /obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/weapon/wirecutters)) diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 4fde338ba54..00bd068e067 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -232,8 +232,6 @@ name = "noir sunglasses" desc = "Somehow these seem even more out-of-date than normal sunglasses." actions_types = list(/datum/action/item_action/noir) - var/noir_mode = 0 - color_view = MATRIX_GREYSCALE /obj/item/clothing/glasses/sunglasses/noir/attack_self() toggle_noir() @@ -243,36 +241,8 @@ return 1 /obj/item/clothing/glasses/sunglasses/noir/proc/toggle_noir() - var/list/difference = difflist(usr.client.color, color_view) - - if(!noir_mode) - if(color_view && usr.client && (!usr.client.color || difference)) - animate(usr.client, color = color_view, time = 10) - noir_mode = 1 - else - if(usr.client && usr.client.color && !difference) - animate(usr.client, color = initial(usr.client.color), time = 10) - noir_mode = 0 - -/obj/item/clothing/glasses/sunglasses/noir/equipped(mob/user, slot) - var/list/difference = difflist(user.client.color, color_view) - - if(slot == slot_glasses) - if(noir_mode) - if(color_view && user.client && (!user.client.color || difference.len)) - animate(user.client, color = color_view, time = 10) - else - if(user.client && user.client.color && !difference.len) - animate(user.client, color = initial(user.client.color), time = 10) - ..(user, slot) - -/obj/item/clothing/glasses/sunglasses/noir/dropped(mob/living/carbon/human/user) - var/list/difference = difflist(user.client.color, color_view) - - if(istype(user) && user.glasses == src) - if(user.client && user.client.color && !difference.len) - animate(user.client, color = initial(user.client.color), time = 10) - ..(user) + color_view = color_view ? null : MATRIX_GREYSCALE //Toggles between null and grayscale, with null being the default option. + usr.update_client_colour() /obj/item/clothing/glasses/sunglasses/yeah name = "agreeable glasses" @@ -498,3 +468,28 @@ name = "gar glasses" icon_state = "gar" item_state = "gar" + +/obj/item/clothing/glasses/godeye + name = "eye of god" + desc = "A strange eye, said to have been torn from an omniscient creature that used to roam the wastes." + icon_state = "godeye" + item_state = "godeye" + vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS + darkness_view = 8 + scan_reagents = 1 + flags = NODROP + invis_view = SEE_INVISIBLE_MINIMUM + +/obj/item/clothing/glasses/godeye/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, src) && W != src && W.loc == user) + if(W.icon_state == "godeye") + W.icon_state = "doublegodeye" + W.item_state = "doublegodeye" + W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you." + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.update_inv_wear_mask() + else + to_chat(user, "The eye winks at you and vanishes into the abyss, you feel really unlucky.") + qdel(src) + ..() \ No newline at end of file diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 2b932df2dc1..aefb7188f5c 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -56,3 +56,74 @@ icon_state = "latex" item_state = "lgloves" flags = NODROP + + +/obj/item/clothing/gloves/color/yellow/stun + name = "stun gloves" + desc = "Horrendous and awful. It smells like cancer. The fact it has wires attached to it is incidental." + var/obj/item/weapon/stock_parts/cell/cell = null + var/stun_strength = 5 + var/stun_cost = 3750 + +/obj/item/clothing/gloves/color/yellow/stun/New() + ..() + update_icon() + +/obj/item/clothing/gloves/color/yellow/stun/Destroy() + if(cell) + qdel(cell) + cell = null + return ..() + +/obj/item/clothing/gloves/color/yellow/stun/Touch(atom/A, proximity) + if(!ishuman(loc)) + return FALSE //Only works while worn + if(!iscarbon(A)) + return FALSE + if(!proximity) + return FALSE + if(cell) + var/mob/living/carbon/human/H = loc + if(H.a_intent == I_HARM) + var/mob/living/carbon/C = A + if(cell.use(stun_cost)) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(5, 0, loc) + s.start() + playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) + H.do_attack_animation(C) + visible_message("[C] has been touched with [src] by [H]!") + C.Stun(stun_strength) + C.Weaken(stun_strength) + C.apply_effect(STUTTER, stun_strength) + else + to_chat(H, "Not enough charge!") + return TRUE + return FALSE + +/obj/item/clothing/gloves/color/yellow/stun/update_icon() + ..() + overlays.Cut() + overlays += "gloves_wire" + if(cell) + overlays += "gloves_cell" + +/obj/item/clothing/gloves/color/yellow/stun/attackby(obj/item/weapon/W, mob/living/user, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) + if(!cell) + if(!user.drop_item()) + to_chat(user, "[W] is stuck to you!") + return + W.forceMove(src) + cell = W + to_chat(user, "You attach [W] to [src].") + update_icon() + else + to_chat(user, "[src] already has a cell.") + + else if(iswirecutter(W)) + if(cell) + to_chat(user, "You cut [cell] away from [src].") + cell.forceMove(get_turf(loc)) + cell = null + update_icon() \ No newline at end of file diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 98e5026ae81..88638abde76 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -79,9 +79,17 @@ name = "cueball helmet" desc = "A large, featureless white orb meant to be worn on your head. How do you even see out of this thing?" icon_state = "cueball" + item_state = "cueball" flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR - item_state="cueball" - flags_inv = 0 + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE + +/obj/item/clothing/head/snowman + name = "snowman head" + desc = "A ball of white styrofoam. So festive." + icon_state = "snowman_h" + item_state = "snowman_h" + flags = HEADCOVERSEYES | HEADCOVERSMOUTH | BLOCKHAIR + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE /obj/item/clothing/head/that name = "sturdy top-hat" @@ -348,6 +356,16 @@ attack_verb = list("warned", "cautioned", "smashed") burn_state = FIRE_PROOF +/obj/item/clothing/head/jester + name = "jester hat" + desc = "A hat with bells, to add some merryness to the suit." + icon_state = "jester_hat" + +/obj/item/clothing/head/rice_hat + name = "rice hat" + desc = "Welcome to the rice fields, motherfucker." + icon_state = "rice_hat" + /obj/item/clothing/head/griffin name = "griffon head" desc = "Why not 'eagle head'? Who knows." diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index f299419ed09..427cc071eda 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -139,6 +139,7 @@ w_class = 2 gas_transfer_coefficient = 0.90 + /obj/item/clothing/mask/pig name = "pig mask" desc = "A rubber pig mask." @@ -188,6 +189,58 @@ if(user.real_name == "[originalname][temporaryname]" || user.real_name == "A Horse With No Name") //if it's somehow changed while the mask is on it doesn't revert user.real_name = originalname +/obj/item/clothing/mask/face + flags = MASKCOVERSMOUTH + flags_inv = HIDEFACE + +/obj/item/clothing/mask/face/rat + name = "rat mask" + desc = "A mask made of soft vinyl and latex, representing the head of a rat." + icon_state = "rat" + item_state = "rat" + +/obj/item/clothing/mask/face/fox + name = "fox mask" + desc = "A mask made of soft vinyl and latex, representing the head of a fox." + icon_state = "fox" + item_state = "fox" + +/obj/item/clothing/mask/face/bee + name = "bee mask" + desc = "A mask made of soft vinyl and latex, representing the head of a bee." + icon_state = "bee" + item_state = "bee" + +/obj/item/clothing/mask/face/bear + name = "bear mask" + desc = "A mask made of soft vinyl and latex, representing the head of a bear." + icon_state = "bear" + item_state = "bear" + +/obj/item/clothing/mask/face/bat + name = "bat mask" + desc = "A mask made of soft vinyl and latex, representing the head of a bat." + icon_state = "bat" + item_state = "bat" + +/obj/item/clothing/mask/face/raven + name = "raven mask" + desc = "A mask made of soft vinyl and latex, representing the head of a raven." + icon_state = "raven" + item_state = "raven" + +/obj/item/clothing/mask/face/jackal + name = "jackal mask" + desc = "A mask made of soft vinyl and latex, representing the head of a jackal." + icon_state = "jackal" + item_state = "jackal" + +/obj/item/clothing/mask/face/tribal + name = "tribal mask" + desc = "A mask carved out of wood, detailed carefully by hand." + icon_state = "bumba" + item_state = "bumba" + /obj/item/clothing/mask/fawkes name = "Guy Fawkes mask" desc = "A mask designed to help you remember a specific date." @@ -287,7 +340,7 @@ icon_override = 'icons/goonstation/mob/clothing/mask.dmi' lefthand_file = 'icons/goonstation/mob/inhands/clothing_lefthand.dmi' righthand_file = 'icons/goonstation/mob/inhands/clothing_righthand.dmi' - flags = NODROP + flags = NODROP | AIRTIGHT | MASKCOVERSMOUTH /obj/item/clothing/mask/cursedclown/equipped(mob/user, slot) ..() diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 4b2ae0ea01b..702c47d13ed 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -212,3 +212,15 @@ righthand_file = 'icons/goonstation/mob/inhands/clothing_righthand.dmi' flags = NODROP shoe_sound = "clownstep" + +/obj/item/clothing/shoes/singery + name = "yellow performer's boots" + desc = "These boots were made for dancing." + icon_state = "ysing" + put_on_delay = 50 + +/obj/item/clothing/shoes/singerb + name = "blue performer's boots" + desc = "These boots were made for dancing." + icon_state = "bsing" + put_on_delay = 50 diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 7c74f77b054..37c88241173 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -92,7 +92,7 @@ var/global/list/breach_burn_descriptors = list( if(!breaches) breaches = list() - if(damage > 25) return //We don't need to keep tracking it when it's at 250% pressure loss, really. + if(damage >= 25) return //We don't need to keep tracking it when it's at 250% pressure loss, really. if(!loc) return var/turf/T = get_turf(src) @@ -125,7 +125,7 @@ var/global/list/breach_burn_descriptors = list( var/datum/breach/B = new() breaches += B - B.class = min(amount,5) + B.class = min(amount,(5 - max(damage - 20,0))) //We cap the check at 25, this line could overshoot without the calculation if it gets enough dammage in one shot. B.damtype = damtype B.update_descriptor() diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index d5c4d5626bb..6e484d27ff7 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -7,20 +7,21 @@ armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50) rig_restrict_helmet = 0 // ERT helmets can be taken on and off at will. var/obj/machinery/camera/camera + var/has_camera = TRUE strip_delay = 130 /obj/item/clothing/head/helmet/space/rig/ert/attack_self(mob/user) - if(camera) + if(camera || !has_camera) ..(user) else camera = new /obj/machinery/camera(src) camera.network = list("ERT") cameranet.removeCamera(camera) camera.c_tag = user.name - to_chat(user, "\blue User scanned as [camera.c_tag]. Camera activated.") + to_chat(user, "User scanned as [camera.c_tag]. Camera activated.") /obj/item/clothing/head/helmet/space/rig/ert/examine(mob/user) - if(..(user, 1)) + if(..(user, 1) && has_camera) to_chat(user, "This helmet has a built-in camera. It's [camera ? "" : "in"]active.") /obj/item/clothing/suit/space/rig/ert @@ -101,6 +102,7 @@ desc = "A suit worn by the janitorial of a Nanotrasen Emergency Response Team. Has purple highlights. Armoured, space ready, and fire resistant." icon_state = "ert_janitor" +//Paranormal /obj/item/clothing/head/helmet/space/rig/ert/paranormal name = "paranormal response unit helmet" desc = "A helmet worn by those who deal with paranormal threats for a living." @@ -108,16 +110,39 @@ item_color = "ert_paranormal" max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT sprite_sheets = null + icon_override = 'icons/mob/clothing/paranormal_hardsuit.dmi' + actions_types = list() + has_camera = 0 /obj/item/clothing/suit/space/rig/ert/paranormal name = "paranormal response team suit" desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats." - icon_state = "knight_grey" - item_state = "knight_grey" + icon_state = "rig-paranormal" max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT sprite_sheets = null - + icon_override = 'icons/mob/clothing/paranormal_hardsuit.dmi' + actions_types = list() /obj/item/clothing/suit/space/rig/ert/paranormal/New() ..() new /obj/item/weapon/nullrod(src) + +/obj/item/clothing/head/helmet/space/rig/ert/paranormal/inquisitor + name = "inquisitor's helmet" + icon_state = "rig0-inquisitor" + item_color = "inquisitor" + +/obj/item/clothing/suit/space/rig/ert/paranormal/inquisitor + name = "inquisitor's hardsuit" + icon_state = "rig-inquisitor" + +/obj/item/clothing/head/helmet/space/rig/ert/paranormal/berserker + name = "champion's helmet" + desc = "Peering into the eyes of the helmet is enough to seal damnation." + icon_state = "rig0-berserker" + item_color = "berserker" + +/obj/item/clothing/suit/space/rig/ert/paranormal/berserker + name = "champion's hardsuit" + desc = "Voices echo from the hardsuit, driving the user insane." + icon_state = "rig-berserker" \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 4d7e1011686..3269cf146c5 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -10,10 +10,10 @@ species_restricted = list("exclude", "Diona", "Wryn") species_fit = list("Vox") sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/helmet.dmi', - "Drask" = 'icons/mob/species/drask/helmet.dmi' + "Vox" = 'icons/mob/species/vox/helmet.dmi' ) -/obj/item/clothing/head/helmet/space/capspace/equipped(var/mob/living/carbon/human/user, var/slot) + +/obj/item/clothing/head/helmet/space/capspace/equipped(mob/living/carbon/human/user, slot) if(ishuman(user) && slot == slot_head) if(user.species.name == "Vox") if(flags & BLOCKHAIR) @@ -33,11 +33,9 @@ species_restricted = list("exclude", "Diona", "Wryn") species_fit = list("Vox") sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi', - "Drask" = 'icons/mob/species/drask/suit.dmi' + "Vox" = 'icons/mob/species/vox/suit.dmi' ) - //Deathsquad space suit, not hardsuits because no flashlight! /obj/item/clothing/head/helmet/space/deathsquad name = "deathsquad helmet" @@ -106,7 +104,6 @@ flags_size = ONESIZEFITSALL allowed = list(/obj/item) //for stuffing exta special presents - //Space pirate outfit /obj/item/clothing/head/helmet/space/pirate name = "pirate hat" @@ -136,12 +133,22 @@ desc = "A paramedic EVA helmet. Used in the recovery of bodies from space." icon_state = "paramedic-eva-helmet" item_state = "paramedic-eva-helmet" + species_restricted = list("exclude","Diona","Wryn") + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/helmet.dmi' + ) /obj/item/clothing/suit/space/eva/paramedic name = "Paramedic EVA suit" icon_state = "paramedic-eva" item_state = "paramedic-eva" desc = "A paramedic EVA suit. Used in the recovery of bodies from space." + species_restricted = list("exclude","Diona","Wryn") + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) /obj/item/clothing/suit/space/eva name = "EVA suit" @@ -207,4 +214,4 @@ armor = list(melee = 20, bullet = 40, laser = 30, energy = 25, bomb = 100, bio = 100, rad = 100) max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT unacidable = 1 - strip_delay = 130 \ No newline at end of file + strip_delay = 130 diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index de2cfc0eda5..73fa69d297c 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -69,15 +69,6 @@ A.UpdateButtonIcon() // ENGINEERING -/obj/item/clothing/suit/space/eva/plasmaman/assistant - name = "plasmaman assistant suit" - icon_state = "plasmamanAssistant_suit" - -/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant - name = "plasmaman assistant helmet" - icon_state = "plasmamanAssistant_helmet0" - base_state = "plasmamanAssistant_helmet" - /obj/item/clothing/suit/space/eva/plasmaman/atmostech name = "plasmaman atmospheric suit" icon_state = "plasmamanAtmos_suit" @@ -115,6 +106,14 @@ //SERVICE +/obj/item/clothing/suit/space/eva/plasmaman/assistant + name = "plasmaman assistant suit" + icon_state = "plasmamanAssistant_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant + name = "plasmaman assistant helmet" + icon_state = "plasmamanAssistant_helmet0" + base_state = "plasmamanAssistant_helmet" /obj/item/clothing/suit/space/eva/plasmaman/botanist name = "plasmaman botanist suit" @@ -301,6 +300,17 @@ icon_state = "plasmaman_Captain_helmet0" base_state = "plasmaman_Captain_helmet" + +//IAA/LAWYER +/obj/item/clothing/suit/space/eva/plasmaman/lawyer + name = "plasmaman lawyer suit" + icon_state = "plasmamanlawyer_suit" + +/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer + name = "plasmaman lawyer helmet" + icon_state = "plasmamanlawyer_helmet0" + base_state = "plasmamanlawyer_helmet" + //NUKEOPS /obj/item/clothing/suit/space/eva/plasmaman/nuclear diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 16ddf2bdd69..925beda23cd 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -119,7 +119,7 @@ gun.attack_self(holder.wearer) return 1 - gun.process_fire(target,holder.wearer) + gun.afterattack(target,holder.wearer) return 1 /obj/item/rig_module/mounted/egun diff --git a/code/modules/clothing/spacesuits/rig/modules/handheld.dm b/code/modules/clothing/spacesuits/rig/modules/handheld.dm new file mode 100644 index 00000000000..1a8a66a5fc4 --- /dev/null +++ b/code/modules/clothing/spacesuits/rig/modules/handheld.dm @@ -0,0 +1,50 @@ + +/obj/item/rig_module/handheld + name = "mounted device" + desc = "Some kind of hardsuit extension." + usable = 0 + selectable = 0 + toggleable = 1 + disruptive = 0 + activate_string = "Deploy" + deactivate_string = "Retract" + + var/device_type + var/obj/item/device + +/obj/item/rig_module/handheld/activate() + if(!..()) + return + + if(!holder.wearer.put_in_hands(device)) + to_chat(holder.wearer, "You need a free hand to hold \the [device].") + active = 0 + return + + to_chat(holder.wearer, "You deploy \the [device].") + + +/obj/item/rig_module/handheld/deactivate() + if(!..()) + return + if(ismob(device.loc)) //Better check for the holder, instead of assuming the rigwearer has it. + var/mob/M = device.loc //Helps in case the code fails to keep the module in one place, this should still return it. + M.unEquip(device, 1) + + device.loc = src + to_chat(holder.wearer, "You retract \the [device].") + +/obj/item/rig_module/handheld/New() + ..() + if(device_type) + device = new device_type(src) + device.flags |= NODROP //We don't want to drop it while it's active/inhand. + activate_string += " [device]" + deactivate_string += " [device]" + +/obj/item/rig_module/handheld/horn + name = "mounted bikehorn" + desc = "For tactical honking" + interface_name = "mounted bikehorn" + interface_desc = "Honks" + device_type = /obj/item/weapon/bikehorn diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 46471966aa7..aa1e644e506 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -94,7 +94,9 @@ */ /obj/item/rig_module/device/New() ..() - if(device_type) device = new device_type(src) + if(device_type) + device = new device_type(src) + device.flags |= ABSTRACT //Abstract in the sense that it's not an item that stands alone, but rather is just there to let the module act like it. /obj/item/rig_module/device/engage(atom/target) if(!..() || !device) @@ -417,13 +419,15 @@ interface_desc = "Leave your mark." engage_string = "Toggle stamp type" usable = 1 - var/iastamp - var/deniedstamp + var/obj/iastamp //Theese were just vars, but any device would need to be an object + var/obj/deniedstamp //Stops assigning non-objects to theese vars, which probably would break quite a bit. /obj/item/rig_module/device/stamp/New() ..() iastamp = new /obj/item/weapon/stamp/law(src) deniedstamp = new /obj/item/weapon/stamp/denied(src) + iastamp.flags |= ABSTRACT + deniedstamp.flags |= ABSTRACT device = iastamp /obj/item/rig_module/device/stamp/engage(atom/target) @@ -488,4 +492,4 @@ W.update_icon() /obj/item/rig_module/welding_tank/proc/get_fuel() - return reagents.get_reagent_amount("fuel") \ No newline at end of file + return reagents.get_reagent_amount("fuel") diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 2ebd01a9162..0b9e87891d8 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -42,7 +42,7 @@ //Component/device holders. var/obj/item/weapon/tank/air_supply // Air tank, if any. - var/obj/item/clothing/shoes/boots = null // Deployable boots, if any. + var/obj/item/clothing/shoes/magboots/boots = null // Deployable boots, if any. var/obj/item/clothing/suit/space/new_rig/chest // Deployable chestpiece, if any. var/obj/item/clothing/head/helmet/space/new_rig/helmet = null // Deployable helmet, if any. var/obj/item/clothing/gloves/rig/gloves = null // Deployable gauntlets, if any. @@ -76,6 +76,7 @@ var/airtight = 1 //If set, will adjust AIRTIGHT and STOPSPRESSUREDMAGE flags on components. Otherwise it should leave them untouched. var/emp_protection = 0 + var/has_emergency_release = 1 //Allows suit to be removed from outside. // Wiring! How exciting. var/datum/wires/rig/wires @@ -126,14 +127,17 @@ if(helm_type) helmet = new helm_type(src) verbs |= /obj/item/weapon/rig/proc/toggle_helmet + helmet.item_color="[initial(icon_state)]_sealed" //For the lightswitching to know the correct string to manipulate if(boot_type) boots = new boot_type(src) verbs |= /obj/item/weapon/rig/proc/toggle_boots + boots.magboot_state="[initial(icon_state)]_sealed" //For the magboot (de)activation to know the correct string to manipulate if(chest_type) chest = new chest_type(src) if(allowed) chest.allowed = allowed chest.slowdown = offline_slowdown + chest.holder = src verbs |= /obj/item/weapon/rig/proc/toggle_chest for(var/obj/item/piece in list(gloves,helmet,boots,chest)) @@ -183,6 +187,10 @@ /obj/item/weapon/rig/proc/reset() offline = 2 flags &= ~NODROP + if(helmet && helmet.on) + helmet.toggle_light(wearer) + if(boots && boots.magpulse) + boots.attack_self(wearer) for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(!piece) continue piece.icon_state = "[initial(icon_state)]" @@ -254,6 +262,7 @@ switch(msg_type) if("boots") to_chat(wearer, "\The [correct_piece] seal around your feet.") + correct_piece.icon_state = "[initial(icon_state)]_sealed0" //Solution to not need a sprite for off, on, and unused magboots. if(user != wearer) to_chat(user, "\The [correct_piece] has been sealed.") wearer.update_inv_shoes() @@ -269,6 +278,7 @@ wearer.update_inv_wear_suit() if("helmet") to_chat(wearer, "\The [correct_piece] hisses closed.") + correct_piece.icon_state = "[initial(icon_state)]_sealed0" //Solution to not need a sprite for off, on, and unused helmet light. if(user != wearer) to_chat(user, "\The [correct_piece] has been sealed.") wearer.update_inv_head() @@ -383,10 +393,14 @@ sealing = FALSE if(failed_to_seal) - for(var/obj/item/piece in list(helmet, boots, gloves, chest)) + for(var/obj/item/piece in list(gloves, chest)) if(!piece) continue piece.icon_state = "[initial(icon_state)]_sealed" + if(helmet) + helmet.icon_state = "[initial(icon_state)]_sealed[helmet.on]" + if(boots) + boots.icon_state = "[initial(icon_state)]_sealed[boots.magpulse]" if(airtight) update_component_sealed() update_icon(1) @@ -406,6 +420,10 @@ update_icon(1) /obj/item/weapon/rig/proc/update_component_sealed() + if(istype(boots) && !(flags & NODROP) && boots.magpulse) //If we have (active) boots and unsealed the suit, we deactivate the magboots. + boots.attack_self(wearer) + if(istype(helmet) && !(flags & NODROP) && helmet.on) //If we have an (active) headlamp and unsealed the suit, we deactivate the headlamp. + helmet.toggle_light(wearer) for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(!(flags & NODROP)) piece.flags &= ~STOPSPRESSUREDMAGE @@ -695,6 +713,8 @@ M.visible_message("[M] struggles into \the [src].", "You struggle into \the [src].") wearer = M wearer.wearing_rig = src + if(has_emergency_release) + M.verbs |= /obj/item/weapon/rig/proc/emergency_release update_icon() /obj/item/weapon/rig/proc/toggle_piece(var/piece, var/mob/living/user, var/deploy_mode, var/force) @@ -705,15 +725,15 @@ if(isliving(uneq_piece.loc)) var/mob/living/L = uneq_piece.loc L.unEquip(uneq_piece, 1) - uneq_piece.flags &= ~NODROP uneq_piece.forceMove(src) return 0 if(sealing || !cell || !cell.charge) return 0 - if(user == wearer && user.incapacitated()) // If the user isn't wearing the suit it's probably an AI. - return 0 + if(!(deploy_mode == ONLY_RETRACT && force)) //This should be the case while stripping, stripping does trigger the if statement below. + if(user == wearer && user.incapacitated()) // If the user isn't wearing the suit it's probably an AI. + return 0 var/obj/item/check_slot var/equip_to @@ -752,7 +772,6 @@ if(to_strip) to_strip.unEquip(use_obj, 1) - use_obj.flags &= ~NODROP use_obj.forceMove(src) if(wearer) to_chat(wearer, "Your [use_obj] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.") @@ -762,13 +781,11 @@ to_chat(wearer, "You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.") return use_obj.forceMove(wearer) - use_obj.flags &= ~NODROP if(!wearer.equip_to_slot_if_possible(use_obj, equip_to, 0, 1)) use_obj.forceMove(src) else if(wearer) to_chat(wearer, "Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.") - use_obj.flags |= NODROP if(piece == "helmet" && helmet) helmet.update_light(wearer) @@ -777,17 +794,17 @@ if(!wearer || !user) return 0 - if(flags & NODROP) - if(wearer.head && wearer.head != helmet) + if(flags & NODROP) //We need to check if we have the part, the person is wearing something in the parts slot, and if yes, are they the same. + if(helmet && wearer.head && wearer.head != helmet) to_chat(user, "\The [wearer.head] is blocking \the [src] from deploying!") return 0 - if(wearer.gloves && wearer.gloves != gloves) + if(gloves && wearer.gloves && wearer.gloves != gloves) to_chat(user, "\The [wearer.gloves] is preventing \the [src] from deploying!") return 0 - if(wearer.shoes && wearer.shoes != boots) + if(boots && wearer.shoes && wearer.shoes != boots) to_chat(user, "\The [wearer.shoes] is preventing \the [src] from deploying!") return 0 - if(wearer.wear_suit && wearer.wear_suit != chest) + if(chest && wearer.wear_suit && wearer.wear_suit != chest) to_chat(user, "\The [wearer.wear_suit] is preventing \the [src] from deploying!") return 0 @@ -797,6 +814,7 @@ /obj/item/weapon/rig/dropped(var/mob/user) ..() + user.verbs -= /obj/item/weapon/rig/proc/emergency_release for(var/piece in list("helmet","gauntlets","chest","boots")) toggle_piece(piece, user, ONLY_RETRACT, 1) if(wearer) @@ -996,6 +1014,38 @@ else return null +/obj/item/weapon/rig/proc/emergency_release() + set name = "Suit Emergency Release" + set desc = "Activate the suits emergency release system." + set category = "Object" + set src in oview(1) + var/obj/item/weapon/rig/T = get_rig() + return T.do_emergency_release(usr) + +/obj/item/weapon/rig/proc/do_emergency_release(var/mob/living/user) + if(!can_touch(user, wearer) || !has_emergency_release) + return can_touch(user,wearer) + usr.visible_message("[user] starts activating \the [src] emergency seals release!") + if(!do_after(user,240, target = wearer)) + to_chat(user, "You need to focus on activating the emergency release.") + return 0 + usr.visible_message("[user] activated \the [src] emergency seals release!") + malfunctioning += 1 + malfunction_delay = 30 + unseal(user) + return 1 + +/obj/item/weapon/rig/proc/can_touch(var/mob/user, var/mob/wearer) + if(!user) + return 0 + if(!wearer.Adjacent(user)) + return 0 + if(user.restrained()) + to_chat(user, "You need your hands free for this.") + return 0 + if(user.stat || user.paralysis || user.sleeping || user.lying || user.weakened) + return 0 + return 1 #undef ONLY_DEPLOY #undef ONLY_RETRACT #undef SEAL_DELAY diff --git a/code/modules/clothing/spacesuits/rig/rig_armormod.dm b/code/modules/clothing/spacesuits/rig/rig_armormod.dm new file mode 100644 index 00000000000..ec045c7da2d --- /dev/null +++ b/code/modules/clothing/spacesuits/rig/rig_armormod.dm @@ -0,0 +1,21 @@ +/obj/item/clothing/suit/space/new_rig/calc_breach_damage() + ..() + holder.update_armor() //New dammage, new armormultiplikator. + return damage + +/obj/item/weapon/rig/proc/update_armor() + var/multi = 1 //Multiplicative modification to the armor, maybe add an additive later on + if(chest) + multi *= (100 - chest.damage) / 100 //If we have some breaches, lower the armor value. + + //TODO check for other armor mods, likely modules, which need to be coded. + + for(var/obj/item/piece in list(gloves, helmet, boots, chest)) + if(!istype(piece)) //Do we have the piece + continue + if(islist(armor)) //Did we even give them some armor, if this is the case, the list should be initialized from New() + var/list/L = armor + for(var/armortype in L) + piece.armor[armortype] = L[armortype]*multi + +//Perfect place to also add something like shield modules, or any other hit_reaction modules check. diff --git a/code/modules/clothing/spacesuits/rig/rig_attackby.dm b/code/modules/clothing/spacesuits/rig/rig_attackby.dm index b89c59cf837..a57c2258b04 100644 --- a/code/modules/clothing/spacesuits/rig/rig_attackby.dm +++ b/code/modules/clothing/spacesuits/rig/rig_attackby.dm @@ -141,7 +141,7 @@ if(user.r_hand && user.l_hand) cell.forceMove(get_turf(user)) else - cell.forceMove(user.put_in_hands(cell)) + user.put_in_hands(cell) cell = null else to_chat(user, "There is nothing loaded in that mount.") diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index dab4ad5ac35..0480490c0ca 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -4,7 +4,7 @@ /obj/item/clothing/head/helmet/space/new_rig name = "helmet" - flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | THICKMATERIAL + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | THICKMATERIAL | NODROP flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEMASK body_parts_covered = HEAD heat_protection = HEAD @@ -12,11 +12,12 @@ var/brightness_on = 4 var/on = 0 sprite_sheets = list( - "Tajara" = 'icons/mob/species/tajaran/helmet.dmi', + "Tajaran" = 'icons/mob/species/tajaran/helmet.dmi', "Skrell" = 'icons/mob/species/skrell/helmet.dmi', "Unathi" = 'icons/mob/species/unathi/helmet.dmi' ) species_restricted = null + actions_types = list(/datum/action/item_action/toggle_helmet_light) flash_protect = 2 @@ -28,13 +29,17 @@ toggle_light(user) /obj/item/clothing/head/helmet/space/new_rig/proc/toggle_light(mob/user) - on = !on - icon_state = "rig[on]-[item_color]" + if(flags & AIRTIGHT) //Could also check for STOPSPRESSUREDMAGE, but one is enough, both get toggled when the seal gets toggled. - if(on) - set_light(brightness_on) + on = !on + icon_state = "[item_color][on]" + + if(on) + set_light(brightness_on) + else + set_light(0) else - set_light(0) + to_chat(user, "You cannot turn the light on while the suit isn't sealed.") if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user @@ -42,7 +47,7 @@ /obj/item/clothing/gloves/rig name = "gauntlets" - flags = THICKMATERIAL + flags = THICKMATERIAL | NODROP body_parts_covered = HANDS heat_protection = HANDS cold_protection = HANDS @@ -51,12 +56,19 @@ /obj/item/clothing/shoes/magboots/rig name = "boots" + flags = NODROP body_parts_covered = FEET cold_protection = FEET heat_protection = FEET species_restricted = null gender = PLURAL +/obj/item/clothing/shoes/magboots/rig/attack_self(mob/user) + if(flags & AIRTIGHT) //Could also check for STOPSPRESSUREDMAGE, but one is enough, both get toggled when the seal gets toggled. + ..(user) + else + to_chat(user, "You cannot activate mag-pulse traction system while the suit is not sealed.") + /obj/item/clothing/suit/space/new_rig name = "chestpiece" allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank) @@ -64,14 +76,14 @@ heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEJUMPSUIT|HIDETAIL - flags = STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT + flags = STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT | NODROP slowdown = 0 - //will reach 10 breach damage after 25 laser carbine blasts, 3 revolver hits, or ~1 PTR hit. Completely immune to smg or sts hits. - breach_threshold = 38 + breach_threshold = 20 resilience = 0.2 can_breach = 1 + var/obj/item/weapon/rig/holder sprite_sheets = list( - "Tajara" = 'icons/mob/species/tajaran/suit.dmi', + "Tajaran" = 'icons/mob/species/tajaran/suit.dmi', "Unathi" = 'icons/mob/species/unathi/suit.dmi' ) diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index 0bda9f9288a..2a38480dabc 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -112,7 +112,7 @@ name = "stealth suit control module" suit_type = "stealth" desc = "A highly advanced and expensive suit designed for covert operations." - icon_state = "stealth_rig" + icon_state = "ninja_rig" //supposed to be "stealth_rig", but as it currently only has a semi-copied ninja rig sprite, we can just use them directly. req_access = list(access_syndicate) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 886a98e4678..0ccdf7027d3 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -38,7 +38,7 @@ item_state = "apron" blood_overlay_type = "armor" body_parts_covered = UPPER_TORSO|LOWER_TORSO - allowed = list (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer,/obj/item/weapon/minihoe) + allowed = list(/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle, /obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/cultivator,/obj/item/weapon/reagent_containers/spray/pestspray,/obj/item/weapon/hatchet,/obj/item/weapon/storage/bag/plants) species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 8798caf2e06..ef20bbd0362 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -249,6 +249,13 @@ I.overlays += image(icon = 'icons/mob/robots.dmi' , icon_state = "eyes-robot") //gotta look realistic H.add_alt_appearance("standard_borg_disguise", I, silicon_mob_list+H) //you look like a robot to robots! (including yourself because you're totally a robot) +/obj/item/clothing/suit/snowman + name = "snowman outfit" + desc = "Two white spheres covered in white glitter. 'Tis the season." + icon_state = "snowman" + item_state = "snowman" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + flags_inv = HIDEJUMPSUIT /obj/item/clothing/suit/poncho name = "poncho" @@ -279,6 +286,44 @@ item_state = "ponchoshame" flags = NODROP +/obj/item/clothing/suit/hooded/carp_costume + name = "carp costume" + desc = "A costume made from 'synthetic' carp scales, it smells." + icon_state = "carp_casual" + item_state = "labcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too + allowed = list(/obj/item/weapon/tank/emergency_oxygen) + hoodtype = /obj/item/clothing/head/hooded/carp_hood + +/obj/item/clothing/head/hooded/carp_hood + name = "carp hood" + desc = "A hood attached to a carp costume." + icon_state = "carp_casual" + body_parts_covered = HEAD + cold_protection = HEAD + min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT + flags = NODROP|BLOCKHAIR + flags_inv = HIDEEARS + +/obj/item/clothing/suit/hooded/bee_costume // It's Hip! + name = "bee costume" + desc = "Bee the true Queen!" + icon_state = "bee" + item_state = "labcoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + flags = THICKMATERIAL + hoodtype = /obj/item/clothing/head/hooded/bee_hood + +/obj/item/clothing/head/hooded/bee_hood + name = "bee hood" + desc = "A hood attached to a bee costume." + icon_state = "bee" + body_parts_covered = HEAD + flags = THICKMATERIAL|NODROP|BLOCKHAIR + flags_inv = HIDEEARS + /obj/item/clothing/suit/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? name = "bloated human suit" desc = "A horribly bloated suit made from human skins." @@ -376,7 +421,7 @@ /obj/item/clothing/suit/hooded/wintercoat/hydro name = "hydroponics winter coat" icon_state = "wintercoat_hydro" - allowed = list(/obj/item/weapon/reagent_containers/spray, /obj/item/device/analyzer/plant_analyzer, /obj/item/seeds, /obj/item/weapon/reagent_containers/glass/bottle, /obj/item/weapon/hatchet, /obj/item/weapon/storage/bag/plants) + allowed = list(/obj/item/weapon/reagent_containers/spray, /obj/item/device/plant_analyzer, /obj/item/seeds, /obj/item/weapon/reagent_containers/glass/bottle, /obj/item/weapon/hatchet, /obj/item/weapon/storage/bag/plants) hoodtype = /obj/item/clothing/head/winterhood/hydro /obj/item/clothing/head/winterhood/hydro @@ -728,6 +773,13 @@ adjust_flavour = null burn_state = FIRE_PROOF +/obj/item/clothing/suit/jacket/leather/overcoat + name = "leather overcoat" + desc = "That's a damn fine coat." + icon_state = "leathercoat" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS|LEGS + /obj/item/clothing/suit/officercoat name = "Clown Officer's Coat" desc = "A classy clown officer's overcoat, also designed by Hugo Boss." diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 44a2f5b1c49..cae5fbd28f0 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -74,6 +74,10 @@ strip_delay = 70 put_on_delay = 70 burn_state = FIRE_PROOF + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/head.dmi' + ) /obj/item/clothing/suit/bomb_suit name = "bomb suit" @@ -99,17 +103,20 @@ sprite_sheets = list( "Vox" = 'icons/mob/species/vox/suit.dmi' ) - hide_tail_by_species = list("Vox") /obj/item/clothing/head/bomb_hood/security icon_state = "bombsuitsec" item_state = "bombsuitsec" + species_fit = null + sprite_sheets = null /obj/item/clothing/suit/bomb_suit/security icon_state = "bombsuitsec" item_state = "bombsuitsec" allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs) + species_fit = null + sprite_sheets = null /* * Radiation protection @@ -123,6 +130,10 @@ strip_delay = 60 put_on_delay = 60 burn_state = FIRE_PROOF + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/head.dmi' + ) /obj/item/clothing/suit/radiation name = "Radiation suit" @@ -140,4 +151,8 @@ flags_inv = HIDEJUMPSUIT|HIDETAIL strip_delay = 60 put_on_delay = 60 - burn_state = FIRE_PROOF \ No newline at end of file + burn_state = FIRE_PROOF + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 6da895760af..486d7d7c34e 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -495,6 +495,26 @@ item_color = "janimaid" body_parts_covered = UPPER_TORSO|LOWER_TORSO +/obj/item/clothing/under/singery + name = "yellow performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "ysing" + item_state = "ysing" + item_color = "ysing" + +/obj/item/clothing/under/singerb + name = "blue performer's outfit" + desc = "Just looking at this makes you want to sing." + icon_state = "bsing" + item_state = "bsing" + item_color = "bsing" + +/obj/item/clothing/under/jester + name = "jester suit" + desc = "A jolly dress, well suited to entertain your master, nuncle." + icon_state = "jester" + item_color = "jester" + /obj/item/clothing/under/flappers name = "flappers" desc = "Nothing like the roarin' '20s, flapping the night away on the dance floor." diff --git a/code/modules/computer3/computers/communications.dm b/code/modules/computer3/computers/communications.dm index a4fad8a16cb..bff075c4791 100644 --- a/code/modules/computer3/computers/communications.dm +++ b/code/modules/computer3/computers/communications.dm @@ -47,7 +47,7 @@ New() ..() - crew_announcement.newscast = 1 + crew_announcement.newscast = 0 Reset() ..() diff --git a/code/modules/computer3/program_disks.dm b/code/modules/computer3/program_disks.dm index 201fff39392..64b592b06be 100644 --- a/code/modules/computer3/program_disks.dm +++ b/code/modules/computer3/program_disks.dm @@ -1,44 +1,30 @@ - - /obj/item/weapon/disk/file/arcade name = "Arcade game grab pack" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade,/datum/file/program/arcade) /*/obj/item/weapon/disk/file/aifixer name = "AI System Integrity Restorer" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/aifixer)*/ /obj/item/weapon/disk/file/atmos_alert name = "Atmospheric Alert Notifier" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/atmos_alert) /obj/item/weapon/disk/file/cameras name = "Camera Viewer" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/security) /obj/item/weapon/disk/file/card name = "ID Card Modifier" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/card_comp) /* /obj/item/weapon/disk/file/genetics name = "Genetics & Cloning" desc = "A program install disk." - icon = 'icons/obj/stock_parts.dmi' - icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/cloning,/datum/file/program/dnascanner) */ diff --git a/code/modules/computer3/storage.dm b/code/modules/computer3/storage.dm index 9ff8cab497b..acb569d3072 100644 --- a/code/modules/computer3/storage.dm +++ b/code/modules/computer3/storage.dm @@ -163,6 +163,7 @@ //parent_type = /obj/item/part/computer/storage // todon't: do this name = "Data Disk" desc = "A device that can be inserted and removed into computers easily as a form of portable data storage. This one stores 1 Megabyte" + icon_state = "datadisk_arcade" var/list/files var/list/spawn_files = list() var/writeprotect = 0 diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 288dcfcd9c5..d8111a3fed0 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -6,7 +6,6 @@ var/time = 30 //time in deciseconds var/parts[] = list() //type paths of items that will be placed in the result var/chem_catalists[] = list() //like tools but for reagents - var/fruit[] = list() //grown products required by the recipe var/category = CAT_MISC // Recipe category /datum/crafting_recipe/proc/AdjustChems(var/obj/resultobj as obj) @@ -49,10 +48,8 @@ result = /obj/item/weapon/melee/baton/cattleprod reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1, /obj/item/stack/rods = 1, - /obj/item/weapon/wirecutters = 1, - /obj/item/weapon/stock_parts/cell = 1) + /obj/item/device/assembly/igniter = 1) time = 40 - parts = list(/obj/item/weapon/stock_parts/cell = 1) category = CAT_WEAPON /datum/crafting_recipe/bola @@ -308,4 +305,11 @@ time = 20 reqs = list(/obj/item/stack/sheet/mineral/bananium = 5, /obj/item/weapon/bikehorn) - category = CAT_MISC \ No newline at end of file + category = CAT_MISC + +/datum/crafting_recipe/bonfire + name = "Bonfire" + time = 60 + reqs = list(/obj/item/weapon/grown/log = 5) + result = /obj/structure/bonfire + category = CAT_PRIMAL \ No newline at end of file diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index df0f6916530..97d010439c9 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -154,6 +154,14 @@ icon_on = "guessipon" icon_off = "guessip" +/obj/item/weapon/lighter/zippo/fluff/duckchan // Duckchan: Rybys Romney + name = "Monogrammed Zippo" + desc = " A shiny purple zippo lighter, engraved with Rybys Romney and BuzzPing's name, with a festive green flame." + icon = 'icons/obj/custom_items.dmi' + icon_state = "rybysfluff" + icon_on = "rybysfluffopen" + icon_off = "rybysfluff" + /obj/item/weapon/fluff/dogwhistle //phantasmicdream: Zeke Varloss name = "Sax's whistle" desc = "This whistle seems to have a strange aura about it. Maybe you should blow on it?" @@ -376,6 +384,18 @@ icon_state = "kakicharakiti" //////////// Suits //////////// +/obj/item/clothing/suit/fluff/dusty_jacket //ComputerlessCitizen: Screech + name = "Dusty Jacket" + desc = "A worn leather jacket. Some burn holes have been patched." + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + icon = 'icons/obj/custom_items.dmi' + icon_state = "dusty_jacket" + ignore_suitadjust = 1 + actions_types = list() + adjust_flavour = null + species_fit = null + sprite_sheets = null + /obj/item/clothing/suit/storage/labcoat/fluff/aeneas_rinil //Socialsystem: Lynn Fea name = "Robotics labcoat" desc = "A labcoat with a few markings denoting it as the labcoat of roboticist." diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 3bc26b52799..ed8b8d52ccd 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -10,7 +10,7 @@ /datum/event/alien_infestation/announce() if(successSpawn) - command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') + event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/alien_infestation/start() var/list/vents = list() @@ -29,6 +29,8 @@ respawnable_list -= C.client var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) new_xeno.key = C.key + if(ticker && ticker.mode) + ticker.mode.xenos += new_xeno.mind spawncount-- successSpawn = 1 diff --git a/code/modules/events/anomaly.dm b/code/modules/events/anomaly.dm index a1f951f5747..0349d09d0b8 100644 --- a/code/modules/events/anomaly.dm +++ b/code/modules/events/anomaly.dm @@ -15,7 +15,7 @@ setup(safety_loop) /datum/event/anomaly/announce() - command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm index 65b005c2538..e5327d92b16 100644 --- a/code/modules/events/anomaly_bluespace.dm +++ b/code/modules/events/anomaly_bluespace.dm @@ -4,7 +4,7 @@ endWhen = 160 /datum/event/anomaly/anomaly_bluespace/announce() - command_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_bluespace/start() var/turf/T = pick(get_area_turfs(impact_area)) @@ -33,7 +33,7 @@ var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO playsound(TO, 'sound/effects/phasein.ogg', 100, 1) - command_announcement.Announce("Massive bluespace translocation detected.", "Anomaly Alert") + event_announcement.Announce("Massive bluespace translocation detected.", "Anomaly Alert") var/list/flashers = list() for(var/mob/living/carbon/C in viewers(TO, null)) diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm index b7a14ab9327..e5cebbff40d 100644 --- a/code/modules/events/anomaly_flux.dm +++ b/code/modules/events/anomaly_flux.dm @@ -4,7 +4,7 @@ endWhen = 180 /datum/event/anomaly/anomaly_flux/announce() - command_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_flux/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm index 0c9f3776f82..19fe7a41525 100644 --- a/code/modules/events/anomaly_grav.dm +++ b/code/modules/events/anomaly_grav.dm @@ -4,7 +4,7 @@ endWhen = 70 /datum/event/anomaly/anomaly_grav/announce() - command_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_grav/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm index b1cf81b23c3..3c2e6025952 100644 --- a/code/modules/events/anomaly_pyro.dm +++ b/code/modules/events/anomaly_pyro.dm @@ -4,7 +4,7 @@ endWhen = 110 /datum/event/anomaly/anomaly_pyro/announce() - command_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/anomaly/anomaly_pyro/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm index c950444978e..662669509cb 100644 --- a/code/modules/events/anomaly_vortex.dm +++ b/code/modules/events/anomaly_vortex.dm @@ -4,7 +4,7 @@ endWhen = 80 /datum/event/anomaly/anomaly_vortex/announce() - command_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") + event_announcement.Announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert") /datum/event/anomaly/anomaly_vortex/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 3fc9d3f1bdc..0bb69c693bb 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -4,7 +4,7 @@ var/obj/effect/blob/core/Blob /datum/event/blob/announce() - command_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') + event_announcement.Announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/AI/outbreak5.ogg') /datum/event/blob/start() var/turf/T = pick(blobstart) diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index d640bca8641..8245f24b291 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -14,7 +14,7 @@ "You don't want to buy anything? Yeah, well I didn't want to buy your mom either.") /datum/event/brand_intelligence/announce() - command_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert") + event_announcement.Announce("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert") /datum/event/brand_intelligence/start() for(var/obj/machinery/vending/V in machines) diff --git a/code/modules/events/cargobonus.dm b/code/modules/events/cargobonus.dm index 75276615a40..c51c7ff41a8 100644 --- a/code/modules/events/cargobonus.dm +++ b/code/modules/events/cargobonus.dm @@ -2,7 +2,7 @@ announceWhen = 5 /datum/event/cargo_bonus/announce() - command_announcement.Announce("Congratulations! [station_name()] was chosen for a supply limit increase. Please contact the local cargo department for details!", "Supply Alert") + event_announcement.Announce("Congratulations! [station_name()] was chosen for a supply limit increase. Please contact the local cargo department for details!", "Supply Alert") /datum/event/cargo_bonus/start() supply_controller.points += rand(100,500) \ No newline at end of file diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index 13b5c884131..abab5c39254 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -14,7 +14,7 @@ announcement = "Massive migration of unknown biological entities has been detected near [station_name()], please stand-by." else announcement = "Unknown biological [spawned_carp.len == 1 ? "entity has" : "entities have"] been detected near [station_name()], please stand-by." - command_announcement.Announce(announcement, "Lifesign Alert") + event_announcement.Announce(announcement, "Lifesign Alert") /datum/event/carp_migration/start() if(severity == EVENT_LEVEL_MAJOR) diff --git a/code/modules/events/communications_blackout.dm b/code/modules/events/communications_blackout.dm index 6ada1a25c0f..1b499027150 100644 --- a/code/modules/events/communications_blackout.dm +++ b/code/modules/events/communications_blackout.dm @@ -12,7 +12,7 @@ to_chat(A, "
") if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts. - command_announcement.Announce(alert) + event_announcement.Announce(alert) /datum/event/communications_blackout/start() for(var/obj/machinery/telecomms/T in telecomms_list) @@ -20,7 +20,7 @@ /proc/communications_blackout(var/silent = 1) if(!silent) - command_announcement.Announce("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT", new_sound = 'sound/misc/interference.ogg') + event_announcement.Announce("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT", new_sound = 'sound/misc/interference.ogg') else // AIs will always know if there's a comm blackout, rogue AIs could then lie about comm blackouts in the future while they shutdown comms for(var/mob/living/silicon/ai/A in player_list) to_chat(A, "
") diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index e8483ccc4ca..069ef9865af 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -7,7 +7,7 @@ announceWhen = rand(15, 30) /datum/event/disease_outbreak/announce() - command_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') + event_announcement.Announce("Confirmed outbreak of level 7 major viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') /datum/event/disease_outbreak/start() if(!virus_type) diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm index c0ef182571b..94ef81ceee5 100644 --- a/code/modules/events/electrical_storm.dm +++ b/code/modules/events/electrical_storm.dm @@ -3,7 +3,7 @@ var/lightsoutRange = 25 /datum/event/electrical_storm/announce() - command_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") + event_announcement.Announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert") /datum/event/electrical_storm/start() var/list/epicentreList = list() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 1a2a4e897cb..bece706a653 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -101,8 +101,13 @@ var/list/event_last_fired = list() playercount_modifier = 1 if(26 to 35) playercount_modifier = 0.9 - if(36 to 100000) + if(36 to 50) playercount_modifier = 0.8 + if(50 to 80) + playercount_modifier = 0.7 + if(80 to 10000) + playercount_modifier = 0.6 + playercount_modifier = playercount_modifier * delay_modifier var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier @@ -155,6 +160,7 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 40, list(ASSIGNMENT_SECURITY = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Immovable Rod", /datum/event/immovable_rod, 0, list(ASSIGNMENT_ENGINEER = 30), 1), //new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1), // NON-BAY EVENTS new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300), @@ -170,7 +176,7 @@ var/list/event_last_fired = list() 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, "Morph Spawn", /datum/event/spawn_morph, 0, is_one_shot = 1), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, is_one_shot = 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1) ) @@ -185,7 +191,8 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1), new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, is_one_shot = 1) + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, is_one_shot = 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1) ) diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 5a892efb691..db9dd4c6955 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -8,14 +8,14 @@ power_failure(0) /datum/event/grid_check/announce() - command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') + event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg') /datum/event/grid_check/end() power_restore() /proc/power_failure(var/announce = 1) if(announce) - command_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg') + event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg') var/list/skipped_areas = list(/area/turret_protected/ai) var/list/skipped_areas_apc = list(/area/engine/engineering) @@ -45,7 +45,7 @@ var/list/skipped_areas_apc = list(/area/engine/engineering) if(announce) - command_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') + event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/apc/C in apcs) var/area/current_area = get_area(C) if(current_area.type in skipped_areas_apc || !is_station_level(C.z)) @@ -64,7 +64,7 @@ /proc/power_restore_quick(var/announce = 1) if(announce) - command_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') + event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') for(var/obj/machinery/power/smes/S in machines) if(!is_station_level(S.z)) continue diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm index 3012b0f9535..2dc2c8a17dd 100644 --- a/code/modules/events/immovable_rod.dm +++ b/code/modules/events/immovable_rod.dm @@ -11,7 +11,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 announceWhen = 5 /datum/event/immovable_rod/announce() - command_announcement.Announce("What the fuck was that?!", "General Alert") + event_announcement.Announce("What the fuck was that?!", "General Alert") /datum/event/immovable_rod/start() var/startside = pick(cardinal) @@ -34,9 +34,23 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 loc = start z_original = z destination = end + notify_ghosts("\A [src] is inbound!", + enter_link="(Click to follow)", + source=src, action=NOTIFY_FOLLOW) + poi_list |= src if(end && end.z==z_original) walk_towards(src, destination, 1) +/obj/effect/immovablerod/Topic(href, href_list) + if(href_list["follow"]) + var/mob/dead/observer/ghost = usr + if(istype(ghost)) + ghost.ManualFollow(src) + +/obj/effect/immovablerod/Destroy() + poi_list.Remove(src) + return ..() + /obj/effect/immovablerod/Move() if(z != z_original || loc == destination) qdel(src) @@ -65,4 +79,4 @@ In my current plan for it, 'solid' will be defined as anything with density == 1 H.adjustBruteLoss(160) if(clong.density || prob(10)) clong.ex_act(2) - return + return \ No newline at end of file diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index ee2aa2de868..8e4a5834ba2 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -97,7 +97,7 @@ /datum/event/infestation/announce() - command_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") + event_announcement.Announce("Bioscans indicate that [vermstring] have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") #undef LOC_KITCHEN #undef LOC_ATMOS diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 20a53a4413f..4979b0889ed 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -17,7 +17,7 @@ /datum/event/ion_storm/announce() if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance))) - command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/AI/ionstorm.ogg') + event_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/AI/ionstorm.ogg') /datum/event/ion_storm/start() diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index a3f302cff9f..500350a037c 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -9,4 +9,4 @@ H.AdjustHallucinate(rand(50, 100)) /datum/event/mass_hallucination/announce() - command_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") + event_announcement.Announce("It seems that station [station_name()] is passing through a minor radiation field, this may cause some hallucination, but no further damage") diff --git a/code/modules/events/meaty_gore.dm b/code/modules/events/meaty_gore.dm index 729f5182344..b9cb43deb99 100644 --- a/code/modules/events/meaty_gore.dm +++ b/code/modules/events/meaty_gore.dm @@ -1,5 +1,5 @@ /datum/event/meteor_wave/gore/announce() - command_announcement.Announce("Unknown biological debris have been detected near [station_name()], please stand-by.", "Debris Alert") + event_announcement.Announce("Unknown biological debris have been detected near [station_name()], please stand-by.", "Debris Alert") /datum/event/meteor_wave/gore/setup() waves = 3 @@ -14,4 +14,4 @@ /datum/event/meteor_wave/gore/end() - command_announcement.Announce("The station has cleared the debris.", "Debris Alert") + event_announcement.Announce("The station has cleared the debris.", "Debris Alert") diff --git a/code/modules/events/meaty_ops.dm b/code/modules/events/meaty_ops.dm index 19263c75f82..d92e79edea9 100644 --- a/code/modules/events/meaty_ops.dm +++ b/code/modules/events/meaty_ops.dm @@ -1,6 +1,6 @@ /datum/event/meteor_wave/goreop/announce() var/meteor_declaration = "MeteorOps have declared their intent to utterly destroy [station_name()] with their own bodies, and dares the crew to try and stop them." - command_announcement.Announce(meteor_declaration, "Declaration of 'War'", 'sound/effects/siren.ogg') + event_announcement.Announce(meteor_declaration, "Declaration of 'War'", 'sound/effects/siren.ogg') /datum/event/meteor_wave/goreop/setup() waves = 3 @@ -16,4 +16,4 @@ /datum/event/meteor_wave/goreops/end() - command_announcement.Announce("All MeteorOps are dead. Major Station Victory.", "MeteorOps") \ No newline at end of file + event_announcement.Announce("All MeteorOps are dead. Major Station Victory.", "MeteorOps") \ No newline at end of file diff --git a/code/modules/events/meaty_ores.dm b/code/modules/events/meaty_ores.dm index df56749734e..48d24ebeef1 100644 --- a/code/modules/events/meaty_ores.dm +++ b/code/modules/events/meaty_ores.dm @@ -1,8 +1,8 @@ /datum/event/dust/meaty/announce() if(prob(16)) - command_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") + event_announcement.Announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert") else - command_announcement.Announce("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert", new_sound = 'sound/AI/meteors.ogg') + event_announcement.Announce("Meaty ores have been detected on collision course with the station.", "Meaty Ore Alert", new_sound = 'sound/AI/meteors.ogg') /datum/event/dust/meaty/setup() qnty = rand(45,125) diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm index d26e43dba6b..b21e02bd7fa 100644 --- a/code/modules/events/meteors.dm +++ b/code/modules/events/meteors.dm @@ -10,9 +10,9 @@ /datum/event/meteor_wave/announce() switch(severity) if(EVENT_LEVEL_MAJOR) - command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') + event_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg') else - command_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert") + event_announcement.Announce("The station is now in a meteor shower.", "Meteor Alert") //meteor showers are lighter and more common, /datum/event/meteor_wave/tick() @@ -25,9 +25,9 @@ /datum/event/meteor_wave/end() switch(severity) if(EVENT_LEVEL_MAJOR) - command_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert") + event_announcement.Announce("The station has cleared the meteor storm.", "Meteor Alert") else - command_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert") + event_announcement.Announce("The station has cleared the meteor shower", "Meteor Alert") /datum/event/meteor_wave/proc/get_meteors() switch(severity) diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index 340ca836e94..8f16d2636ea 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -37,7 +37,7 @@ /datum/event/prison_break/announce() if(areas && areas.len > 0) - command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] [(eventDept == "Security")? "imprisonment":"containment"] subroutines. Secure any compromised areas immediately. Station AI involvement is recommended.", "[eventDept] Alert") + event_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] [(eventDept == "Security")? "imprisonment":"containment"] subroutines. Secure any compromised areas immediately. Station AI involvement is recommended.", "[eventDept] Alert") /datum/event/prison_break/start() for(var/area/A in world) diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 7968e2493cf..2e090979ce6 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -21,7 +21,7 @@ /datum/event/radiation_storm/start() spawn() - command_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') + event_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') for(var/area/A in world) if(!is_station_level(A.z) || is_safe_zone(A)) @@ -32,7 +32,7 @@ sleep(600) - command_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") + event_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") for(var/i = 0, i < 10, i++) for(var/mob/living/carbon/human/H in living_mob_list) @@ -58,7 +58,7 @@ sleep(100) - command_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") + event_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") for(var/area/A in world) if(!is_station_level(A.z) || is_safe_zone(A)) diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index 9b7386fe470..3a770bf7864 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -30,7 +30,7 @@ msg = "Contact has been lost with a combat drone wing operating out of the NSV Icarus. If any are sighted in the area, approach with caution." else msg = "Unidentified hackers have targetted a combat drone wing deployed from the NSV Icarus. If any are sighted in the area, approach with caution." - command_announcement.Announce(msg, "Rogue drone alert") + event_announcement.Announce(msg, "Rogue drone alert") /datum/event/rogue_drone/tick() return @@ -48,6 +48,6 @@ num_recovered++ if(num_recovered > drones_list.len * 0.75) - command_announcement.Announce("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") + event_announcement.Announce("Icarus drone control reports the malfunctioning wing has been recovered safely.", "Rogue drone alert") else - command_announcement.Announce("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") + event_announcement.Announce("Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered.", "Rogue drone alert") diff --git a/code/modules/events/slaughterevent.dm b/code/modules/events/slaughterevent.dm index 3a7464baa8c..f46ebcfd605 100644 --- a/code/modules/events/slaughterevent.dm +++ b/code/modules/events/slaughterevent.dm @@ -37,8 +37,8 @@ player_mind.transfer_to(S) player_mind.assigned_role = "Slaughter Demon" player_mind.special_role = SPECIAL_ROLE_SLAUGHTER_DEMON - message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.") - log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.") + message_admins("[key_name_admin(S)] has been made into a Slaughter Demon by an event.") + log_game("[key_name_admin(S)] was spawned as a Slaughter Demon by an event.") return 1 /datum/event/spawn_slaughter/start() diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index cf00e4f78b9..61ba1b5350d 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -1,11 +1,570 @@ -/var/global/spacevines_spawned = 0 - -/datum/event/spacevine - announceWhen = 10 +//Types of usual mutations +#define POSITIVE 1 +#define NEGATIVE 2 +#define MINOR_NEGATIVE 3 /datum/event/spacevine/start() - spacevine_infestation() - spacevines_spawned = 1 + var/list/turfs = list() //list of all the empty floor turfs in the hallway areas -/datum/event/spacevine/announce() - command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg') + var/obj/effect/spacevine/SV = new() + + for(var/area/hallway/A in world) + for(var/turf/F in A) + if(F.Enter(SV)) + turfs += F + + qdel(SV) + + if(turfs.len) //Pick a turf to spawn at if we can + var/turf/T = pick(turfs) + new/obj/effect/spacevine_controller(T) //spawn a controller at turf + + +/datum/spacevine_mutation + var/name = "" + var/severity = 1 + var/hue + var/quality + +/datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/effect/spacevine/holder) + holder.mutations |= src + holder.color = hue + +/datum/spacevine_mutation/proc/process_mutation(obj/effect/spacevine/holder) + return + +/datum/spacevine_mutation/proc/process_temperature(obj/effect/spacevine/holder, temp, volume) + return + +/datum/spacevine_mutation/proc/on_birth(obj/effect/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_grow(obj/effect/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_death(obj/effect/spacevine/holder) + return + +/datum/spacevine_mutation/proc/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage) + . = expected_damage + +/datum/spacevine_mutation/proc/on_cross(obj/effect/spacevine/holder, mob/crosser) + return + +/datum/spacevine_mutation/proc/on_chem(obj/effect/spacevine/holder, datum/reagent/R) + return + +/datum/spacevine_mutation/proc/on_eat(obj/effect/spacevine/holder, mob/living/eater) + return + +/datum/spacevine_mutation/proc/on_spread(obj/effect/spacevine/holder, turf/target) + return + +/datum/spacevine_mutation/proc/on_buckle(obj/effect/spacevine/holder, mob/living/buckled) + return + +/datum/spacevine_mutation/proc/on_explosion(severity, obj/effect/spacevine/holder) + return + + +/datum/spacevine_mutation/space_covering + name = "space protective" + hue = "#aa77aa" + quality = POSITIVE + +/turf/simulated/floor/vines + color = "#aa77aa" + icon_state = "vinefloor" + broken_states = list() + + +//All of this shit is useless for vines + +/turf/simulated/floor/vines/attackby() + return + +/turf/simulated/floor/vines/burn_tile() + return + +/turf/simulated/floor/vines/break_tile() + return + +/turf/simulated/floor/vines/make_plating() + return + +/turf/simulated/floor/vines/break_tile_to_plating() + return + +/turf/simulated/floor/vines/ex_act(severity) + if(severity < 3) + ChangeTurf(baseturf) + +/turf/simulated/floor/vines/narsie_act() + if(prob(20)) + ChangeTurf(baseturf) //nar sie eats this shit + +/turf/simulated/floor/vines/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(50)) + ChangeTurf(baseturf) + +/turf/simulated/floor/vines/ChangeTurf(turf/open/floor/T) + . = ..() + //Do this *after* the turf has changed as qdel in spacevines will call changeturf again if it hasn't + for(var/obj/effect/spacevine/SV in src) + qdel(SV) + +/datum/spacevine_mutation/space_covering + var/static/list/coverable_turfs + +/datum/spacevine_mutation/space_covering/New() + . = ..() + if(!coverable_turfs) + coverable_turfs = typecacheof(list( + /turf/space + )) + coverable_turfs -= typecacheof(list( + /turf/space/transit + )) + +/datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder) + process_mutation(holder) + +/datum/spacevine_mutation/space_covering/process_mutation(obj/effect/spacevine/holder) + var/turf/T = get_turf(holder) + if(is_type_in_typecache(T, coverable_turfs)) + var/currtype = T.type + T.ChangeTurf(/turf/simulated/floor/vines) + T.baseturf = currtype + +/datum/spacevine_mutation/space_covering/on_death(obj/effect/spacevine/holder) + var/turf/T = get_turf(holder) + if(istype(T, /turf/simulated/floor/vines)) + T.ChangeTurf(T.baseturf) + +/datum/spacevine_mutation/bluespace + name = "bluespace" + hue = "#3333ff" + quality = MINOR_NEGATIVE + +/datum/spacevine_mutation/bluespace/on_spread(obj/effect/spacevine/holder, turf/target) + if(holder.energy > 1 && !locate(/obj/effect/spacevine) in target) + holder.master.spawn_spacevine_piece(target, holder) + +/datum/spacevine_mutation/light + name = "light" + hue = "#ffff00" + quality = POSITIVE + severity = 4 + +/datum/spacevine_mutation/light/on_grow(obj/effect/spacevine/holder) + if(holder.energy) + holder.set_light(severity) + +/datum/spacevine_mutation/toxicity + name = "toxic" + hue = "#ff00ff" + severity = 10 + quality = NEGATIVE + +/datum/spacevine_mutation/toxicity/on_cross(obj/effect/spacevine/holder, mob/living/crosser) + if(issilicon(crosser)) + return + if(prob(severity) && istype(crosser) && !isvineimmune(crosser)) + to_chat(crosser, "You accidently touch the vine and feel a strange sensation.") + crosser.adjustToxLoss(5) + +/datum/spacevine_mutation/toxicity/on_eat(obj/effect/spacevine/holder, mob/living/eater) + if(!isvineimmune(eater)) + eater.adjustToxLoss(5) + +/datum/spacevine_mutation/explosive //OH SHIT IT CAN CHAINREACT RUN!!! + name = "explosive" + hue = "#ff0000" + quality = NEGATIVE + severity = 2 + +/datum/spacevine_mutation/explosive/on_explosion(explosion_severity, obj/effect/spacevine/holder) + if(explosion_severity < 3) + qdel(holder) + else + . = 1 + spawn(5) + qdel(holder) + +/datum/spacevine_mutation/explosive/on_death(obj/effect/spacevine/holder, mob/hitter, obj/item/I) + explosion(holder.loc, 0, 0, severity, 0, 0) + +/datum/spacevine_mutation/fire_proof + name = "fire proof" + hue = "#ff8888" + quality = MINOR_NEGATIVE + +/datum/spacevine_mutation/fire_proof/process_temperature(obj/effect/spacevine/holder, temp, volume) + return 1 + +/datum/spacevine_mutation/fire_proof/on_hit(obj/effect/spacevine/holder, mob/hitter, obj/item/I, expected_damage) + if(I && I.damtype == "fire") + . = 0 + else + . = expected_damage + +/datum/spacevine_mutation/vine_eating + name = "vine eating" + hue = "#ff7700" + quality = MINOR_NEGATIVE + +/datum/spacevine_mutation/vine_eating/on_spread(obj/effect/spacevine/holder, turf/target) + var/obj/effect/spacevine/prey = locate() in target + if(prey && !prey.mutations.Find(src)) //Eat all vines that are not of the same origin + qdel(prey) + +/datum/spacevine_mutation/aggressive_spread //very OP, but im out of other ideas currently + name = "aggressive spreading" + hue = "#333333" + severity = 3 + quality = NEGATIVE + +/datum/spacevine_mutation/aggressive_spread/on_spread(obj/effect/spacevine/holder, turf/target) + target.ex_act(severity) // vine immunity handled at /mob/ex_act + +/datum/spacevine_mutation/aggressive_spread/on_buckle(obj/effect/spacevine/holder, mob/living/buckled) + buckled.ex_act(severity) + +/datum/spacevine_mutation/transparency + name = "transparent" + hue = "" + quality = POSITIVE + +/datum/spacevine_mutation/transparency/on_grow(obj/effect/spacevine/holder) + holder.set_opacity(0) + holder.alpha = 125 + +/datum/spacevine_mutation/thorns + name = "thorny" + hue = "#666666" + severity = 10 + quality = NEGATIVE + +/datum/spacevine_mutation/thorns/on_cross(obj/effect/spacevine/holder, mob/living/crosser) + if(prob(severity) && istype(crosser) && !isvineimmune(holder)) + var/mob/living/M = crosser + M.adjustBruteLoss(5) + to_chat(M, "You cut yourself on the thorny vines.") + +/datum/spacevine_mutation/thorns/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) + if(prob(severity) && istype(hitter) && !isvineimmune(holder)) + var/mob/living/M = hitter + M.adjustBruteLoss(5) + to_chat(M, "You cut yourself on the thorny vines.") + . = expected_damage + +/datum/spacevine_mutation/woodening + name = "hardened" + hue = "#997700" + quality = NEGATIVE + +/datum/spacevine_mutation/woodening/on_grow(obj/effect/spacevine/holder) + if(holder.energy) + holder.density = 1 + holder.maxhealth = 100 + holder.health = holder.maxhealth + +/datum/spacevine_mutation/woodening/on_hit(obj/effect/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) + if(!is_sharp(I)) + . = expected_damage * 0.5 + else + . = expected_damage + +/datum/spacevine_mutation/flowering + name = "flowering" + hue = "#0A480D" + quality = NEGATIVE + severity = 10 + +/datum/spacevine_mutation/flowering/on_grow(obj/effect/spacevine/holder) + if(holder.energy == 2 && prob(severity) && !locate(/obj/structure/alien/resin/flower_bud_enemy) in range(5,holder)) + new /obj/structure/alien/resin/flower_bud_enemy(get_turf(holder)) + +/datum/spacevine_mutation/flowering/on_cross(obj/effect/spacevine/holder, mob/living/crosser) + if(prob(25)) + holder.entangle(crosser) + + +// SPACE VINES (Note that this code is very similar to Biomass code) +/obj/effect/spacevine + name = "space vines" + desc = "An extremely expansionistic species of vine." + icon = 'icons/effects/spacevines.dmi' + icon_state = "Light1" + anchored = 1 + density = 0 + layer = MOB_LAYER + 0.8 + mouse_opacity = 2 //Clicking anywhere on the turf is good enough + pass_flags = PASSTABLE | PASSGRILLE + var/health = 50 + var/maxhealth = 50 + var/energy = 0 + var/obj/effect/spacevine_controller/master = null + var/list/mutations = list() + +/obj/effect/spacevine/New() + ..() + color = "#ffffff" + +/obj/effect/spacevine/examine(mob/user) + ..() + var/text = "This one is a" + if(mutations.len) + for(var/A in mutations) + var/datum/spacevine_mutation/SM = A + text += " [SM.name]" + else + text += " normal" + text += " vine." + to_chat(user, text) + +/obj/effect/spacevine/Destroy() + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_death(src) + if(master) + master.vines -= src + master.growth_queue -= src + if(!master.vines.len) + var/obj/item/seeds/kudzu/KZ = new(loc) + KZ.mutations |= mutations + KZ.set_potency(master.mutativeness * 10) + KZ.set_production((master.spread_cap / initial(master.spread_cap)) * 5) + master = null + mutations.Cut() + set_opacity(0) + if(buckled_mob) + unbuckle_mob() + return ..() + +/obj/effect/spacevine/proc/add_mutation(datum/spacevine_mutation/mutation) + mutations |= mutation + color = mutation.hue + +/obj/effect/spacevine/proc/on_chem_effect(datum/reagent/R) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.on_chem(src, R) + if(!override && istype(R, /datum/reagent/glyphosate)) + if(prob(50)) + qdel(src) + +/obj/effect/spacevine/proc/eat(mob/eater) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.on_eat(src, eater) + if(!override) + if(prob(10)) + eater.say("Nom") + qdel(src) + +/obj/effect/spacevine/attackby(obj/item/weapon/W, mob/user, params) + if (!W || !user || !W.type) + return + user.changeNext_move(CLICK_CD_MELEE) + var/force = W.force + + if(istype(W, /obj/item/weapon/scythe)) + force = force * 4 + for(var/obj/effect/spacevine/B in orange(1,src)) + B.health = health - force + if(B.health < 1) + qdel(B) + + health = health - force + + if(health < 1) + qdel(src) + + return + + if(is_sharp(W)) + force = force * 4 + + if(W && W.damtype == "fire") + force = force * 4 + + for(var/datum/spacevine_mutation/SM in mutations) + force = SM.on_hit(src, user, W, force) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further + + health = health - force + if(health < 1) + qdel(src) + + ..() + +/obj/effect/spacevine/Crossed(mob/crosser) + if(isliving(crosser)) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_cross(src, crosser) + +/obj/effect/spacevine/attack_hand(mob/user) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_hit(src, user) + user_unbuckle_mob(user, user) + +/obj/effect/spacevine/attack_alien(mob/living/user) + eat(user) + +/obj/effect/spacevine_controller + invisibility = 101 + var/list/obj/effect/spacevine/vines = list() + var/list/growth_queue = list() + var/spread_multiplier = 5 + var/spread_cap = 30 + var/list/mutations_list = list() + var/mutativeness = 1 + +/obj/effect/spacevine_controller/New(loc, list/muts, potency, production) + color = "#ffffff" + spawn_spacevine_piece(loc, , muts) + processing_objects.Add(src) + init_subtypes(/datum/spacevine_mutation/, mutations_list) + if(potency != null) + mutativeness = potency / 10 + if(production != null) + spread_cap *= production / 5 + spread_multiplier /= production / 5 + ..() + + +/obj/effect/spacevine_controller/ex_act() //only killing all vines will end this suffering + return + +/obj/effect/spacevine_controller/singularity_act() + return + +/obj/effect/spacevine_controller/singularity_pull() + return + +/obj/effect/spacevine_controller/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/effect/spacevine_controller/proc/spawn_spacevine_piece(turf/location, obj/effect/spacevine/parent, list/muts) + var/obj/effect/spacevine/SV = new(location) + growth_queue += SV + vines += SV + SV.master = src + if(muts && muts.len) + for(var/datum/spacevine_mutation/M in muts) + M.add_mutation_to_vinepiece(SV) + return + if(parent) + SV.mutations |= parent.mutations + SV.color = parent.color + if(prob(mutativeness)) + var/list/random_mutations_picked = mutations_list - SV.mutations + if(random_mutations_picked.len) + var/datum/spacevine_mutation/randmut = pick(random_mutations_picked) + randmut.add_mutation_to_vinepiece(SV) + + for(var/datum/spacevine_mutation/SM in SV.mutations) + SM.on_birth(SV) + +/obj/effect/spacevine_controller/process() + if(!vines) + qdel(src) //space vines exterminated. Remove the controller + return + if(!growth_queue) + qdel(src) //Sanity check + return + + var/length = 0 + + length = min( spread_cap , max( 1 , vines.len / spread_multiplier ) ) + var/i = 0 + var/list/obj/effect/spacevine/queue_end = list() + + for(var/obj/effect/spacevine/SV in growth_queue) + if(qdeleted(SV)) + continue + i++ + queue_end += SV + growth_queue -= SV + for(var/datum/spacevine_mutation/SM in SV.mutations) + SM.process_mutation(SV) + if(SV.energy < 2) //If tile isn't fully grown + if(prob(20)) + SV.grow() + else //If tile is fully grown + SV.entangle_mob() + + //if(prob(25)) + SV.spread() + if(i >= length) + break + + growth_queue = growth_queue + queue_end + +/obj/effect/spacevine/proc/grow() + if(!energy) + icon_state = pick("Med1", "Med2", "Med3") + energy = 1 + set_opacity(1) + else + icon_state = pick("Hvy1", "Hvy2", "Hvy3") + energy = 2 + + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_grow(src) + +/obj/effect/spacevine/proc/entangle_mob() + if(!buckled_mob && prob(25)) + for(var/mob/living/V in loc) + entangle(V) + if(has_buckled_mobs()) + break //only capture one mob at a time + + +/obj/effect/spacevine/proc/entangle(mob/living/V) + if(!V || isvineimmune(V)) + return + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_buckle(src, V) + if((V.stat != DEAD) && (V.buckled != src)) //not dead or captured + to_chat(V, "The vines [pick("wind", "tangle", "tighten")] around you!") + buckle_mob(V, 1) + +/obj/effect/spacevine/proc/spread() + var/direction = pick(cardinal) + var/turf/stepturf = get_step(src,direction) + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_spread(src, stepturf) + stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen + if(!locate(/obj/effect/spacevine, stepturf)) + if(stepturf.Enter(src)) + if(master) + master.spawn_spacevine_piece(stepturf, src) + +/obj/effect/spacevine/ex_act(severity) + var/i + for(var/datum/spacevine_mutation/SM in mutations) + i += SM.on_explosion(severity, src) + if(!i && prob(100/severity)) + qdel(src) + +/obj/effect/spacevine/temperature_expose(null, temp, volume) + var/override = 0 + for(var/datum/spacevine_mutation/SM in mutations) + override += SM.process_temperature(src, temp, volume) + if(!override) + qdel(src) + +/obj/effect/spacevine/CanPass(atom/movable/mover, turf/target, height=0) + if(isvineimmune(mover)) + . = TRUE + else + . = ..() + +/proc/isvineimmune(atom/A) + . = FALSE + if(isliving(A)) + var/mob/living/M = A + if(("vines" in M.faction) || ("plants" in M.faction)) + . = TRUE \ No newline at end of file diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 2b3ffb799df..ab703f0edc9 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -10,7 +10,7 @@ sent_spiders_to_station = 1 /datum/event/spider_infestation/announce() - command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') + event_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') /datum/event/spider_infestation/start() diff --git a/code/modules/events/tear.dm b/code/modules/events/tear.dm index e409f6592d8..7a13c239de0 100644 --- a/code/modules/events/tear.dm +++ b/code/modules/events/tear.dm @@ -5,7 +5,7 @@ var/obj/effect/tear/TE /datum/event/tear/announce() - command_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") + event_announcement.Announce("A tear in the fabric of space and time has opened. Expected location: [impact_area.name].", "Anomaly Alert") /datum/event/tear/start() var/turf/T = pick(get_area_turfs(impact_area)) diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index e5679764a39..137ffc83183 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -6,7 +6,7 @@ var/list/vents = list() /datum/event/vent_clog/announce() - command_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") + event_announcement.Announce("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert") /datum/event/vent_clog/setup() endWhen = rand(25, 100) diff --git a/code/modules/events/wallrot.dm b/code/modules/events/wallrot.dm index a246345b632..84c0ee211c4 100644 --- a/code/modules/events/wallrot.dm +++ b/code/modules/events/wallrot.dm @@ -3,7 +3,7 @@ endWhen = announceWhen + 1 /datum/event/wallrot/announce() - command_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") + event_announcement.Announce("Harmful fungi detected on station. Station structures may be contaminated.", "Biohazard Alert") /datum/event/wallrot/start() spawn() diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 398994f972d..91a4612cb16 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -21,7 +21,7 @@ wormholes += new /obj/effect/portal/wormhole(T, null, null, -1) /datum/event/wormholes/announce() - command_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') + event_announcement.Announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", new_sound = 'sound/AI/spanomalies.ogg') /datum/event/wormholes/tick() if(activeFor % shift_frequency == 0) diff --git a/code/modules/fish/fish_items.dm b/code/modules/fish/fish_items.dm index 0266f06df90..7d5d3bf20ce 100644 --- a/code/modules/fish/fish_items.dm +++ b/code/modules/fish/fish_items.dm @@ -1,6 +1,6 @@ var/global/list/fish_items_list = list("goldfish" = /obj/item/weapon/fish/goldfish, - "clownfish" = /obj/item/weapon/bananapeel/clownfish, + "clownfish" = /obj/item/weapon/grown/bananapeel/clownfish, "shark" = /obj/item/weapon/fish/shark, "baby space carp" = /obj/item/weapon/fish/babycarp, "catfish" = /obj/item/weapon/fish/catfish, @@ -208,7 +208,7 @@ var/global/list/fish_items_list = list("goldfish" = /obj/item/weapon/fish/goldfi ..() -/obj/item/weapon/bananapeel/clownfish +/obj/item/weapon/grown/bananapeel/clownfish name = "clown fish" desc = "Even underwater, you cannot escape HONKing." icon = 'icons/obj/fish_items.dmi' diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler.dm b/code/modules/food_and_drinks/drinks/bottler/bottler.dm index c6b88b78c6c..81974b39c0e 100644 --- a/code/modules/food_and_drinks/drinks/bottler/bottler.dm +++ b/code/modules/food_and_drinks/drinks/bottler/bottler.dm @@ -213,12 +213,7 @@ for(var/i = 1, i <= slots.len, i++) var/obj/item/O = slots[i] if(istype(O, recipe.ingredients[i])) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O - if(G.seed && G.seed.kitchen_tag == recipe.tags[i]) - number_matches++ - else - number_matches++ + number_matches++ if(number_matches == 3) return recipe return null diff --git a/code/modules/food_and_drinks/drinks/bottler/bottler_recipes.dm b/code/modules/food_and_drinks/drinks/bottler/bottler_recipes.dm index be7504afade..85b3452ebfc 100644 --- a/code/modules/food_and_drinks/drinks/bottler/bottler_recipes.dm +++ b/code/modules/food_and_drinks/drinks/bottler/bottler_recipes.dm @@ -3,7 +3,6 @@ var/name = "" var/description = "" var/list/ingredients[3] - var/list/tags[3] var/datum/reagent/result = null @@ -12,12 +11,10 @@ name = "Example" description = "This is an example." ingredients = list(thing_1, thing_2, thing_3) - tags = list(null, "tag_2", null) result = "water" The ingredients list must have 3 non-null entries. -The tags list must have 3 entries, using null where a tag is unused. -Failing to ensure both lists have EXACTLY 3 entries (unless the system is updated in the future to use a different number) will result in runtimes. +Failing to ensure the list has EXACTLY 3 entries (unless the system is updated in the future to use a different number) will result in runtimes. There is no excuse to do this wrong now that there is an example for you. --FalseIncarnate */ @@ -25,62 +22,55 @@ There is no excuse to do this wrong now that there is an example for you. --Fals /datum/bottler_recipe/Paradise_Punch name = "Paradise Punch" description = "Tastes just how you'd think Paradise would if you could bottle it." - ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown) - tags = list("grapes", "banana", "cherries") + ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown/grapes, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/cherries) result = "paradise_punch" /datum/bottler_recipe/Applepocalypse name = "Apple-pocalypse" description = "If doomsday came in fruit form, it'd probably be apples." - ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown) - tags = list("apple", "apple", "apple") + ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown/apple, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple) result = "apple-pocalypse" /datum/bottler_recipe/Berry_Banned name = "Berry Banned" description = "Reason for ban: Excessive Flavor." - ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown) - tags = list("berries", "berries", "berries") + ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown/berries, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries) result = "berry_banned" /datum/bottler_recipe/Berry_Banned2 name = "Berry Banned" description = "Reason for ban: Excessive Flavor." - ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown, - /obj/item/weapon/reagent_containers/food/snacks/grown) - tags = list("poisonberries", "poisonberries", "poisonberries") + ingredients = list(/obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison) result = "berry_banned2" /datum/bottler_recipe/Blackeye_Brew name = "Blackeye Brew" description = "Creamy, smooth flavor, just like the bald heads of the masses. Supposedly aged for 30 years." ingredients = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola, - /obj/item/weapon/reagent_containers/food/snacks/grown, + /obj/item/weapon/reagent_containers/food/snacks/grown/sugarcane, /obj/item/weapon/reagent_containers/food/snacks/icecream) - tags = list(null, "sugarcane", null) result = "blackeye_brew" /datum/bottler_recipe/Grape_Granade name = "Grape Granade" description = "Exploding with grape flavor and a favorite among ERT members system-wide." ingredients = list(/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice, - /obj/item/weapon/reagent_containers/food/snacks/grown, + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes, /obj/item/device/flash) - tags = list(null, "grapes", null) result = "grape_granade" /datum/bottler_recipe/Meteor_Malt name = "Meteor Malt" description = "Soft drinks have been detected on collision course with your tastebuds." ingredients = list(/obj/item/weapon/ore, - /obj/item/weapon/reagent_containers/food/snacks/grown, + /obj/item/weapon/reagent_containers/food/snacks/grown/wheat, /obj/item/weapon/ore) - tags = list(null, "wheat", null) result = "meteor_malt" diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 0814bf988f4..ee1d2821fa1 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -61,7 +61,7 @@ to_chat(user, " [src] is full.") return - var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) to_chat(user, " You fill [src] with [trans] units of the contents of [target].") else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it. @@ -331,4 +331,11 @@ name = "cup" desc = "A cup with the british flag emblazoned on it." icon_state = "britcup" - volume = 30 \ No newline at end of file + volume = 30 + +/obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl + name = "mushroom bowl" + desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point." + icon = 'icons/obj/lavaland/ash_flora.dmi' + icon_state = "mushroom_bowl" + w_class = 2 \ No newline at end of file diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index f14c0d19254..4655dcba98f 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -5,7 +5,8 @@ possible_transfer_amounts = null volume = 50 //Sets the default container amount for all food items. var/filling_color = "#FFFFFF" //Used by sandwiches. - var/bitesize = 1 + var/junkiness = 0 //for junk food. used to lower human satiety. + var/bitesize = 2 var/consume_sound = 'sound/items/eatfood.ogg' var/apply_type = INGEST var/apply_method = "swallow" @@ -15,5 +16,5 @@ /obj/item/weapon/reagent_containers/food/New() ..() - pixel_x = rand(-10, 10) //Randomizes postion - pixel_y = rand(-10, 10) \ No newline at end of file + pixel_x = rand(-5, 5) //Randomizes postion + pixel_y = rand(-5, 5) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/candy.dm b/code/modules/food_and_drinks/food/candy.dm index 32a4a584a88..d0d6ab4b32d 100644 --- a/code/modules/food_and_drinks/food/candy.dm +++ b/code/modules/food_and_drinks/food/candy.dm @@ -22,7 +22,6 @@ desc = "Such sweet, fattening food." icon_state = "chocolatebar" filling_color = "#7D5F46" - bitesize = 2 list_reagents = list("nutriment" = 2, "chocolate" = 4) /obj/item/weapon/reagent_containers/food/snacks/candy/caramel @@ -30,7 +29,6 @@ desc = "Chewy and dense, yet it practically melts in your mouth!" icon_state = "caramel" filling_color = "#DB944D" - bitesize = 2 list_reagents = list("cream" = 2, "sugar" = 2) @@ -39,7 +37,6 @@ desc = "A hard, brittle candy with a distinctive taste." icon_state = "toffee" filling_color = "#7D5F46" - bitesize = 2 list_reagents = list("nutriment" = 3, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/candy/nougat @@ -47,7 +44,6 @@ desc = "A soft, chewy candy commonly found in candybars." icon_state = "nougat" filling_color = "#7D5F46" - bitesize = 2 list_reagents = list("nutriment" = 3, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/candy/taffy @@ -55,7 +51,6 @@ desc = "Old fashioned saltwater taffy. Chewy!" icon_state = "candy1" filling_color = "#7D5F46" - bitesize = 2 list_reagents = list("nutriment" = 3, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/candy/taffy/New() @@ -111,7 +106,6 @@ desc = "It's a handful of candy corn. Cannot be stored in a detective's hat, alas." icon_state = "candycorn" filling_color = "#FFFCB0" - bitesize = 2 list_reagents = list("nutriment" = 4, "sugar" = 2) // *********************************************************** @@ -134,14 +128,15 @@ trash = /obj/item/trash/candy filling_color = "#7D5F46" bitesize = 3 - list_reagents = list("nutriment" = 2, "chocolate" = 5) + junkiness = 25 + list_reagents = list("nutriment" = 1, "chocolate" = 1) + /obj/item/weapon/reagent_containers/food/snacks/candy/candycane name = "candy cane" desc = "A festive mint candy cane." icon_state = "candycane" filling_color = "#F2F2F2" - bitesize = 2 list_reagents = list("minttoxin" = 1, "sugar" = 5) /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear @@ -181,7 +176,6 @@ desc = "Not legal tender. Tasty though." icon_state = "candy_cash" filling_color = "#302000" - bitesize = 2 list_reagents = list("nutriment" = 2, "chocolate" = 4) /obj/item/weapon/reagent_containers/food/snacks/candy/coin @@ -511,32 +505,35 @@ // Candybar Flavors // *********************************************************** -/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/rice +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery + list_reagents = list("nutriment" = 1, "chocolate" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/rice name = "Asteroid Crunch Bar" desc = "Crunchy rice deposits in delicious chocolate! A favorite of miners galaxy-wide." icon_state = "asteroidcrunch" trash = /obj/item/trash/candy filling_color = "#7D5F46" -/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/toffee +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/toffee name = "Yum-baton Bar" desc = "Chocolate and toffee in the shape of a baton. Security sure knows how to pound these down!" icon_state = "yumbaton" filling_color = "#7D5F46" -/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/caramel name = "Malper Bar" desc = "A chocolate syringe filled with a caramel injection. Just what the doctor ordered!" icon_state = "malper" filling_color = "#7D5F46" -/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel_nougat +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/caramel_nougat name = "Toxins Test Bar" desc = "An explosive combination of chocolate, caramel, and nougat. Research has never been so tasty!" icon_state = "toxinstest" filling_color = "#7D5F46" -/obj/item/weapon/reagent_containers/food/snacks/candy/candybar/nougat +/obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/nougat name = "Tool-erone Bar" desc = "Chocolate-covered nougat, shaped like a wrench. Great for an engineer on the go!" icon_state = "toolerone" diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 77e3f22a1e8..dfd89a809da 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -69,6 +69,7 @@ icon_state = "breadslice" var/baseicon = "sandwich" var/basename = "sandwich" + bitesize = 4 var/top = 1 //Do we have a top? var/obj/item/toptype var/add_overlays = 1 //Do we stack? @@ -76,7 +77,6 @@ var/sandwich_limit = 40 var/fullycustom = 0 trash = /obj/item/trash/plate - bitesize = 2 var/list/ingredients = list() list_reagents = list("nutriment" = 8) diff --git a/code/modules/food_and_drinks/food/meat.dm b/code/modules/food_and_drinks/food/meat.dm index 4635f6eb9b1..19d8307c906 100644 --- a/code/modules/food_and_drinks/food/meat.dm +++ b/code/modules/food_and_drinks/food/meat.dm @@ -44,4 +44,12 @@ /obj/item/weapon/reagent_containers/food/snacks/meat/ham name = "Ham" desc = "Taste like bacon." - list_reagents = list("protein" = 3, "porktonium" = 10) \ No newline at end of file + list_reagents = list("protein" = 3, "porktonium" = 10) + +/obj/item/weapon/reagent_containers/food/snacks/meat/meatwheat + name = "meatwheat clump" + desc = "This doesn't look like meat, but your standards aren't that high to begin with." + list_reagents = list("nutriment" = 3, "vitamin" = 2, "blood" = 5) + filling_color = rgb(150, 0, 0) + icon_state = "meatwheat_clump" + bitesize = 4 \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/seafood.dm b/code/modules/food_and_drinks/food/seafood.dm index c0a95d39315..0a219ee2de6 100644 --- a/code/modules/food_and_drinks/food/seafood.dm +++ b/code/modules/food_and_drinks/food/seafood.dm @@ -6,7 +6,7 @@ icon_state = "fishfillet" filling_color = "#FFDEFE" bitesize = 6 - list_reagents = list("protein" = 3, "carpotoxin" = 3) + list_reagents = list("protein" = 3, "carpotoxin" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/salmonmeat name = "raw salmon" @@ -14,8 +14,8 @@ icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfillet" filling_color = "#FFDEFE" - bitesize = 3 - list_reagents = list("protein" = 3) + bitesize = 6 + list_reagents = list("protein" = 3, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/salmonsteak name = "Salmon steak" @@ -25,7 +25,7 @@ trash = /obj/item/trash/plate filling_color = "#7A3D11" bitesize = 3 - list_reagents = list("nutriment" = 4, "sodiumchloride" = 1, "blackpepper" = 1) + list_reagents = list("nutriment" = 4, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/catfishmeat name = "raw catfish" @@ -33,8 +33,8 @@ icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfillet" filling_color = "#FFDEFE" - bitesize = 3 - list_reagents = list("protein" = 3) + bitesize = 6 + list_reagents = list("protein" = 3, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/fishfingers name = "Fish Fingers" @@ -42,8 +42,8 @@ icon = 'icons/obj/food/seafood.dmi' icon_state = "fishfingers" filling_color = "#FFDEFE" - bitesize = 3 - list_reagents = list("nutriment" = 4, "carpotoxin" = 3) + bitesize = 1 + list_reagents = list("nutriment" = 4) /obj/item/weapon/reagent_containers/food/snacks/fishburger name = "Fillet -o- Carp Sandwich" @@ -52,7 +52,7 @@ icon_state = "fishburger" filling_color = "#FFDEFE" bitesize = 3 - list_reagents = list("nutriment" = 6, "carpotoxin" = 3) + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/cubancarp name = "Cuban Carp" @@ -62,7 +62,7 @@ trash = /obj/item/trash/plate filling_color = "#E9ADFF" bitesize = 3 - list_reagents = list("nutriment" = 6, "carpotoxin" = 3, "capsaicin" = 3) + list_reagents = list("nutriment" = 6, "capsaicin" = 1) /obj/item/weapon/reagent_containers/food/snacks/fishandchips name = "Fish and Chips" @@ -71,7 +71,7 @@ icon_state = "fishandchips" filling_color = "#E3D796" bitesize = 3 - list_reagents = list("nutriment" = 6, "carpotoxin" = 3) + list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/sashimi name = "carp sashimi" @@ -79,7 +79,7 @@ icon = 'icons/obj/food/seafood.dmi' icon_state = "sashimi" bitesize = 3 - list_reagents = list("nutriment" = 6, "toxin" = 5) + list_reagents = list("nutriment" = 6, "capsaicin" = 5) /obj/item/weapon/reagent_containers/food/snacks/fried_shrimp name = "fried shrimp" diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 49cd0c1fa3b..ff684c3296b 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -11,7 +11,9 @@ var/eatverb var/wrapped = 0 var/dried_type = null + var/dry = 0 var/cooktype[0] + var/cooked_type = null //for microwave cooking. path of the resulting item after microwaving //Placeholder for effect that trigger on eating that aren't tied to reagents. @@ -25,12 +27,8 @@ user.visible_message("[user] finishes eating \the [src].") user.unEquip(src) //so icons update :[ Post_Consume(M) - if(trash) - if(ispath(trash,/obj/item)) - var/obj/item/TrashItem = new trash(user) - user.put_in_hands(TrashItem) - else if(istype(trash,/obj/item)) - user.put_in_hands(trash) + var/obj/item/trash_item = generate_trash(usr) + usr.put_in_hands(trash_item) qdel(src) return @@ -47,7 +45,7 @@ qdel(src) return 0 - if(istype(M, /mob/living/carbon)) + if(iscarbon(M)) var/mob/living/carbon/C = M if(C.eat(src, user)) bitecount++ @@ -173,6 +171,19 @@ return +/obj/item/weapon/reagent_containers/food/snacks/proc/generate_trash(atom/location) + if(trash) + if(ispath(trash, /obj/item)) + . = new trash(location) + trash = null + return + else if(istype(trash, /obj/item)) + var/obj/item/trash_item = trash + trash_item.forceMove(location) + . = trash + trash = null + return + /obj/item/weapon/reagent_containers/food/snacks/Destroy() if(contents) for(var/atom/movable/something in contents) @@ -255,20 +266,23 @@ trash = /obj/item/trash/snack_bowl filling_color = "#468C00" bitesize = 3 - list_reagents = list("nutriment" = 8, "omnizine" = 8) + list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/chips name = "chips" desc = "Commander Riker's What-The-Crisps" icon_state = "chips" + bitesize = 1 trash = /obj/item/trash/chips filling_color = "#E8C31E" - list_reagents = list("nutriment" = 3, "sodiumchloride" = 1) + junkiness = 20 + list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/cornchips name = "corn chips" desc = "Goes great with salsa! OLE!" icon_state = "chips" + bitesize = 1 trash = /obj/item/trash/chips filling_color = "#E8C31E" list_reagents = list("nutriment" = 3) @@ -277,23 +291,22 @@ name = "cookie" desc = "COOKIE!!!" icon_state = "COOKIE!!!" + bitesize = 1 filling_color = "#DBC94F" - list_reagents = list("nutriment" = 5) + list_reagents = list("nutriment" = 1) /obj/item/weapon/reagent_containers/food/snacks/chocolatebar name = "Chocolate Bar" desc = "Such sweet, fattening food." icon_state = "chocolatebar" filling_color = "#7D5F46" - bitesize = 2 - list_reagents = list("nutriment" = 2, "chocolate" = 4) + list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) /obj/item/weapon/reagent_containers/food/snacks/choc_pile //for reagent chocolate being spilled on turfs name = "Pile of Chocolate" desc = "A pile of pure chocolate pieces." icon_state = "cocoa" filling_color = "#7D5F46" - bitesize = 2 list_reagents = list("chocolate" = 5) /obj/item/weapon/reagent_containers/food/snacks/chocolateegg @@ -301,95 +314,75 @@ desc = "Such sweet, fattening food." icon_state = "chocolateegg" filling_color = "#7D5F46" - bitesize = 2 - list_reagents = list("nutriment" = 3, "chocolate" = 4) + list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) /obj/item/weapon/reagent_containers/food/snacks/donut name = "donut" desc = "Goes great with Robust Coffee." icon_state = "donut1" - filling_color = "#D9C386" - bitesize = 3 + bitesize = 5 + list_reagents = list("nutriment" = 3, "sugar" = 2) + var/extra_reagent = null + filling_color = "#D2691E" + var/randomized_sprinkles = 1 -/obj/item/weapon/reagent_containers/food/snacks/donut/normal - name = "donut" - desc = "Goes great with Robust Coffee." - icon_state = "donut1" - list_reagents = list("nutriment" = 3, "sprinkles" = 1) - -/obj/item/weapon/reagent_containers/food/snacks/donut/normal/New() +/obj/item/weapon/reagent_containers/food/snacks/donut/New() ..() - if(prob(30)) + if(randomized_sprinkles && prob(30)) icon_state = "donut2" name = "frosted donut" reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" /obj/item/weapon/reagent_containers/food/snacks/donut/sprinkles name = "frosted donut" icon_state = "donut2" - list_reagents = list("nutriment" = 3, "sprinkles" = 3) + list_reagents = list("nutriment" = 3, "sugar" = 2, "spinkles" = 2) + filling_color = "#FF69B4" + randomized_sprinkles = 0 /obj/item/weapon/reagent_containers/food/snacks/donut/chaos - name = "Chaos Donut" + name = "chaos donut" desc = "Like life, it never quite tastes the same." - icon_state = "donut1" - filling_color = "#ED11E6" bitesize = 10 /obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New() ..() - var/extra_reagent = pick("nutriment", "capsaicin", "frostoil", "sprinkles", "plasma", "chocolate", "slimejelly", "banana", "berryjuice", "omnizine") + extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") reagents.add_reagent("[extra_reagent]", 3) if(prob(30)) icon_state = "donut2" - name = "Frosted Chaos Donut" + name = "frosted chaos donut" reagents.add_reagent("sprinkles", 2) - + filling_color = "#FF69B4" /obj/item/weapon/reagent_containers/food/snacks/donut/jelly - name = "Jelly Donut" + name = "jelly donut" desc = "You jelly?" icon_state = "jdonut1" - filling_color = "#ED1169" - bitesize = 5 - list_reagents = list("nutriment" = 3, "sprinkles" = 1, "berryjuice" = 5) + extra_reagent = "berryjuice" /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New() ..() + if(extra_reagent) + reagents.add_reagent("[extra_reagent]", 3) if(prob(30)) icon_state = "jdonut2" - name = "Frosted Jelly Donut" + name = "frosted jelly Donut" reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" -/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly - name = "Jelly Donut" +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly + name = "jelly donut" desc = "You jelly?" icon_state = "jdonut1" - filling_color = "#ED1169" - bitesize = 5 - list_reagents = list("nutriment" = 3, "sprinkles" = 1, "slimejelly" = 5) + extra_reagent = "slimejelly" -/obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly/New() - ..() - if(prob(30)) - icon_state = "jdonut2" - name = "Frosted Jelly Donut" - reagents.add_reagent("sprinkles", 2) - -/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly - name = "Jelly Donut" +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/cherryjelly + name = "jelly donut" desc = "You jelly?" icon_state = "jdonut1" - filling_color = "#ED1169" - bitesize = 5 - list_reagents = list("nutriment" = 3, "sprinkles" = 1, "cherryjelly" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly/New() - ..() - if(prob(30)) - icon_state = "jdonut2" - name = "Frosted Jelly Donut" - reagents.add_reagent("sprinkles", 2) + extra_reagent = "cherryjelly" /obj/item/weapon/reagent_containers/food/snacks/egg name = "egg" @@ -458,14 +451,15 @@ desc = "A fried egg, with a touch of salt and pepper." icon_state = "friedegg" filling_color = "#FFDF78" - list_reagents = list("nutriment" = 2, "egg" = 5, "sodiumchloride" = 1, "blackpepper" = 1) + bitesize = 1 + list_reagents = list("nutriment" = 3, "egg" = 5) /obj/item/weapon/reagent_containers/food/snacks/boiledegg name = "Boiled egg" desc = "A hard boiled egg." icon_state = "egg" filling_color = "#FFFFFF" - list_reagents = list("nutriment" = 2, "egg" = 5) + list_reagents = list("nutriment" = 2, "egg" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/organ @@ -475,7 +469,7 @@ icon_state = "appendix" filling_color = "#E00D34" bitesize = 3 - list_reagents = list("protein" = 4) + list_reagents = list("protein" = 4, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/appendix //yes, this is the same as meat. I might do something different in future @@ -485,7 +479,7 @@ icon_state = "appendix" filling_color = "#E00D34" bitesize = 3 - list_reagents = list("protein" = 3) + list_reagents = list("protein" = 3, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed name = "inflamed appendix" @@ -499,7 +493,7 @@ desc = "We all love tofu." filling_color = "#FFFEE0" bitesize = 3 - list_reagents = list("plantmatter" = 3) + list_reagents = list("plantmatter" = 2) /obj/item/weapon/reagent_containers/food/snacks/fried_tofu name = "Fried Tofu" @@ -507,7 +501,7 @@ desc = "Proof that even vegetarians crave unhealthy foods." filling_color = "#FFFEE0" bitesize = 3 - list_reagents = list("nutriment" = 3) + list_reagents = list("plantmatter" = 3) /obj/item/weapon/reagent_containers/food/snacks/tofurkey name = "Tofurkey" @@ -530,7 +524,7 @@ icon_state = "hugemushroomslice" filling_color = "#E0D7C5" bitesize = 6 - list_reagents = list("plantmatter" = 3, "psilocybin" = 3) + list_reagents = list("plantmatter" = 3, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/tomatomeat name = "tomato slice" @@ -538,7 +532,7 @@ icon_state = "tomatomeat" filling_color = "#DB0000" bitesize = 6 - list_reagents = list("protein" = 3) + list_reagents = list("protein" = 2) /obj/item/weapon/reagent_containers/food/snacks/bearmeat name = "bear meat" @@ -546,7 +540,7 @@ icon_state = "bearmeat" filling_color = "#DB0000" bitesize = 3 - list_reagents = list("protein" = 12, "methamphetamine" = 5) + list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/xenomeat name = "meat" @@ -554,14 +548,14 @@ icon_state = "xenomeat" filling_color = "#43DE18" bitesize = 6 - list_reagents = list("protein" = 3) + list_reagents = list("protein" = 3, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/spidermeat name = "spider meat" desc = "A slab of spider meat." icon_state = "spidermeat" bitesize = 3 - list_reagents = list("protein" = 3, "toxin" = 3) + list_reagents = list("protein" = 3, "toxin" = 3, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/lizardmeat name = "mutant lizard meat" @@ -575,7 +569,6 @@ name = "spider leg" desc = "A still twitching leg of a giant spider... you don't really want to eat this, do you?" icon_state = "spiderleg" - bitesize = 2 list_reagents = list("protein" = 2, "toxin" = 2) /obj/item/weapon/reagent_containers/food/snacks/meatball @@ -583,16 +576,14 @@ desc = "A great meal all round." icon_state = "meatball" filling_color = "#DB0000" - bitesize = 2 - list_reagents = list("protein" = 3) + list_reagents = list("protein" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/sausage name = "Sausage" desc = "A piece of mixed, long meat." icon_state = "sausage" filling_color = "#DB0000" - bitesize = 2 - list_reagents = list("protein" = 6, "porktonium" = 10) + list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) /obj/item/weapon/reagent_containers/food/snacks/donkpocket name = "Donk-pocket" @@ -639,16 +630,16 @@ desc = "A strange looking burger. It looks almost sentient." icon_state = "brainburger" filling_color = "#F2B6EA" - bitesize = 2 - list_reagents = list("nutriment" = 6, "prions" = 10) + bitesize = 3 + list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/ghostburger name = "Ghost Burger" desc = "Spooky! It doesn't look very filling." icon_state = "ghostburger" filling_color = "#FFF2FF" - bitesize = 2 - list_reagents = list("nutriment" = 2) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/human var/hname = "" @@ -659,71 +650,72 @@ name = "-burger" desc = "A bloody burger." icon_state = "hburger" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/cheeseburger name = "cheeseburger" desc = "The cheese adds a good flavor." icon_state = "cheeseburger" - list_reagents = list("nutriment" = 2) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/monkeyburger name = "burger" desc = "The cornerstone of every nutritious breakfast." icon_state = "hburger" filling_color = "#D63C3C" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/tofuburger name = "Tofu Burger" desc = "What.. is that meat?" icon_state = "tofuburger" filling_color = "#FFFEE0" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/roburger name = "roburger" desc = "The lettuce is the only organic component. Beep." icon_state = "roburger" filling_color = "#CCCCCC" - bitesize = 2 - list_reagents = list("nutriment" = 2, "nanomachines" = 10) + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/roburgerbig name = "roburger" desc = "This massive patty looks like poison. Beep." icon_state = "roburger" filling_color = "#CCCCCC" - volume = 100 - bitesize = 0.1 - list_reagents = list("nanomachines" = 100) + volume = 120 + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/xenoburger name = "xenoburger" desc = "Smells caustic. Tastes like heresy." icon_state = "xburger" filling_color = "#43DE18" - bitesize = 2 - list_reagents = list("nutriment" = 8) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/clownburger name = "Clown Burger" desc = "This tastes funny..." icon_state = "clownburger" filling_color = "#FF00FF" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/mimeburger name = "Mime Burger" desc = "Its taste defies language." icon_state = "mimeburger" filling_color = "#FFFFFF" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/omelette name = "Omelette Du Fromage" @@ -731,14 +723,14 @@ icon_state = "omelette" trash = /obj/item/trash/plate filling_color = "#FFF9A8" - list_reagents = list("nutriment" = 8) + list_reagents = list("nutriment" = 8, "vitamin" = 1) + bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/muffin name = "Muffin" desc = "A delicious and spongy little cake" icon_state = "muffin" filling_color = "#E0CF9B" - bitesize = 2 list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/pie @@ -748,7 +740,7 @@ trash = /obj/item/trash/plate filling_color = "#FBFFB8" bitesize = 3 - list_reagents = list("nutriment" = 4, "banana" = 5) + list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) ..() @@ -762,7 +754,7 @@ icon_state = "berryclafoutis" trash = /obj/item/trash/plate bitesize = 3 - list_reagents = list("nutriment" = 4, "berryjuice" = 5) + list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/waffles name = "waffles" @@ -770,8 +762,7 @@ icon_state = "waffles" trash = /obj/item/trash/waffles filling_color = "#E6DEB5" - bitesize = 2 - list_reagents = list("nutriment" = 8) + list_reagents = list("nutriment" = 8, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/eggplantparm name = "Eggplant Parmigiana" @@ -779,8 +770,7 @@ icon_state = "eggplantparm" trash = /obj/item/trash/plate filling_color = "#4D2F5E" - bitesize = 2 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 6, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/soylentgreen name = "Soylent Green" @@ -788,8 +778,7 @@ icon_state = "soylent_green" trash = /obj/item/trash/waffles filling_color = "#B8E6B5" - bitesize = 2 - list_reagents = list("nutriment" = 10) + list_reagents = list("nutriment" = 10, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/soylenviridians name = "Soylen Virdians" @@ -797,8 +786,7 @@ icon_state = "soylent_yellow" trash = /obj/item/trash/waffles filling_color = "#E6FA61" - bitesize = 2 - list_reagents = list("nutriment" = 10) + list_reagents = list("nutriment" = 10, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/meatpie name = "Meat-pie" @@ -806,8 +794,8 @@ desc = "An old barber recipe, very delicious!" trash = /obj/item/trash/plate filling_color = "#948051" - bitesize = 2 - list_reagents = list("nutriment" = 10) + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/tofupie name = "Tofu-pie" @@ -815,24 +803,24 @@ desc = "A delicious tofu pie." trash = /obj/item/trash/plate filling_color = "#FFFEE0" - bitesize = 2 - list_reagents = list("nutriment" = 10) + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/amanita_pie name = "amanita pie" desc = "Sweet and tasty poison pie." icon_state = "amanita_pie" filling_color = "#FFCCCC" - bitesize = 3 - list_reagents = list("nutriment" = 5, "amanitin" = 3, "psilocybin" = 1) + bitesize = 4 + list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/plump_pie name = "plump pie" desc = "I bet you love stuff made out of plump helmets!" icon_state = "plump_pie" filling_color = "#B8279B" - bitesize = 2 - list_reagents = list("nutriment" = 8) + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/plump_pie/New() ..() @@ -847,8 +835,7 @@ desc = "A delicious meatpie. Probably heretical." trash = /obj/item/trash/plate filling_color = "#43DE18" - bitesize = 2 - list_reagents = list("nutriment" = 10) + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/wingfangchu name = "Wing Fang Chu" @@ -856,8 +843,7 @@ icon_state = "wingfangchu" trash = /obj/item/trash/snack_bowl filling_color = "#43DE18" - bitesize = 2 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/human/kabob name = "-kabob" @@ -865,7 +851,6 @@ desc = "A human meat, on a stick." trash = /obj/item/stack/rods filling_color = "#A85340" - bitesize = 2 list_reagents = list("nutriment" = 8) /obj/item/weapon/reagent_containers/food/snacks/monkeykabob @@ -874,7 +859,6 @@ desc = "Delicious meat, on a stick." trash = /obj/item/stack/rods filling_color = "#A85340" - bitesize = 2 list_reagents = list("nutriment" = 8) /obj/item/weapon/reagent_containers/food/snacks/tofukabob @@ -883,7 +867,6 @@ desc = "Vegan meat, on a stick." trash = /obj/item/stack/rods filling_color = "#FFFEE0" - bitesize = 2 list_reagents = list("nutriment" = 8) /obj/item/weapon/reagent_containers/food/snacks/popcorn @@ -912,8 +895,14 @@ desc = "Beef jerky made from the finest space cows." trash = /obj/item/trash/sosjerky filling_color = "#631212" - bitesize = 2 - list_reagents = list("protein" = 4) + junkiness = 25 + list_reagents = list("protein" = 1, "sugar" = 3) + +/obj/item/weapon/reagent_containers/food/snacks/sosjerky/healthy + name = "homemade beef jerky" + desc = "Homemade beef jerky made from the finest space cows." + list_reagents = list("nutriment" = 3, "vitamin" = 1) + junkiness = 0 /obj/item/weapon/reagent_containers/food/snacks/pistachios name = "Pistachios" @@ -921,7 +910,8 @@ desc = "A snack of deliciously salted pistachios. A perfectly valid choice..." trash = /obj/item/trash/pistachios filling_color = "#BAD145" - list_reagents = list("plantmatter" = 6, "sodiumchloride" = 1) + junkiness = 20 + list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) /obj/item/weapon/reagent_containers/food/snacks/no_raisin name = "4no Raisins" @@ -929,14 +919,21 @@ desc = "Best raisins in the universe. Not sure why." trash = /obj/item/trash/raisins filling_color = "#343834" - list_reagents = list("plantmatter" = 6) + junkiness = 25 + list_reagents = list("plantmatter" = 2, "sugar" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/no_raisin/healthy + name = "homemade raisins" + desc = "homemade raisins, the best in all of spess." + list_reagents = list("nutriment" = 3, "vitamin" = 2) + junkiness = 0 /obj/item/weapon/reagent_containers/food/snacks/spacetwinkie name = "Space Twinkie" icon_state = "space_twinkie" desc = "Guaranteed to survive longer then you will." filling_color = "#FFE591" - bitesize = 2 + junkiness = 25 list_reagents = list("sugar" = 4) /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers @@ -945,36 +942,36 @@ desc = "Bite sized cheesie snacks that will honk all over your mouth" trash = /obj/item/trash/cheesie filling_color = "#FFA305" - bitesize = 2 - list_reagents = list("nutriment" = 4, "fake_cheese" = 2) + junkiness = 25 + list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/chinese/chowmein name = "chow mein" desc = "What is in this anyways?" icon_state = "chinese1" - bitesize = 2 - list_reagents = list("nutriment" = 6, "beans" = 3, "msg" = 4) + junkiness = 25 + list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) /obj/item/weapon/reagent_containers/food/snacks/chinese/tao name = "Admiral Yamamoto carp" desc = "Tastes like chicken." icon_state = "chinese2" - bitesize = 2 - list_reagents = list("nutriment" = 4, "protein" = 2, "msg" = 4) + junkiness = 25 + list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) /obj/item/weapon/reagent_containers/food/snacks/chinese/newdles name = "chinese newdles" desc = "Made fresh, weekly!" icon_state = "chinese3" - bitesize = 2 - list_reagents = list("nutriment" = 6, "msg" = 4) + junkiness = 25 + list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/chinese/rice name = "fried rice" desc = "A timeless classic." icon_state = "chinese4" - bitesize = 2 - list_reagents = list("nutriment" = 3, "rice" = 3, "msg" = 4) + junkiness = 20 + list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) /obj/item/weapon/reagent_containers/food/snacks/syndicake name = "Syndi-Cakes" @@ -990,7 +987,6 @@ desc = "Totally baked." icon_state = "loadedbakedpotato" filling_color = "#9C7A68" - bitesize = 2 list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/fries @@ -999,7 +995,6 @@ icon_state = "fries" trash = /obj/item/trash/plate filling_color = "#EDDD00" - bitesize = 2 list_reagents = list("nutriment" = 4) /obj/item/weapon/reagent_containers/food/snacks/soydope @@ -1008,7 +1003,6 @@ icon_state = "soydope" trash = /obj/item/trash/plate filling_color = "#C4BF76" - bitesize = 2 list_reagents = list("nutriment" = 2) /obj/item/weapon/reagent_containers/food/snacks/spagetti @@ -1016,7 +1010,7 @@ desc = "A bundle of raw spaghetti." icon_state = "spagetti" filling_color = "#EDDD00" - list_reagents = list("nutriment" = 1) + list_reagents = list("nutriment" = 1, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/cheesyfries name = "Cheesy Fries" @@ -1024,7 +1018,6 @@ icon_state = "cheesyfries" trash = /obj/item/trash/plate filling_color = "#EDDD00" - bitesize = 2 list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/fortunecookie @@ -1032,7 +1025,6 @@ desc = "A true prophecy in each cookie!" icon_state = "fortune_cookie" filling_color = "#E8E79E" - bitesize = 2 list_reagents = list("nutriment" = 3) /obj/item/weapon/reagent_containers/food/snacks/badrecipe @@ -1040,8 +1032,7 @@ desc = "Someone should be demoted from chef for this." icon_state = "badrecipe" filling_color = "#211F02" - bitesize = 2 - list_reagents = list("????" = 5, "carbon" = 3) + list_reagents = list("????" = 30) /obj/item/weapon/reagent_containers/food/snacks/badrecipe/New() ..() @@ -1056,7 +1047,7 @@ trash = /obj/item/trash/plate filling_color = "#7A3D11" bitesize = 3 - list_reagents = list("nutriment" = 4, "sodiumchloride" = 1, "blackpepper" = 1) + list_reagents = list("nutriment" = 5) /obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff name = "Spacy Liberty Duff" @@ -1080,7 +1071,6 @@ name = "Poppy pretzel" desc = "It's all twisted up!" icon_state = "poppypretzel" - bitesize = 2 filling_color = "#916E36" list_reagents = list("nutriment" = 5) @@ -1091,7 +1081,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#785210" bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5) + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/slimesoup name = "slime soup" @@ -1099,7 +1089,7 @@ icon_state = "slimesoup" filling_color = "#C4DBA0" bitesize = 5 - list_reagents = list("slimejelly" = 5, "water" = 10) + list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/bloodsoup name = "Tomato soup" @@ -1107,7 +1097,7 @@ icon_state = "tomatosoup" filling_color = "#FF0000" bitesize = 5 - list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5) + list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/clownstears name = "Clown's Tears" @@ -1115,7 +1105,7 @@ icon_state = "clownstears" filling_color = "#C4FBFF" bitesize = 5 - list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 10) + list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) /obj/item/weapon/reagent_containers/food/snacks/vegetablesoup name = "Vegetable soup" @@ -1124,7 +1114,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#AFC4B5" bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5) + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/nettlesoup name = "Nettle soup" @@ -1133,54 +1123,20 @@ trash = /obj/item/trash/snack_bowl filling_color = "#AFC4B5" bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "omnizine" = 5) + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/mysterysoup - name = "Mystery soup" + name = "mystery soup" desc = "The mystery is, why aren't you eating it?" icon_state = "mysterysoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#F082FF" + var/extra_reagent = null bitesize = 5 + list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/mysterysoup/New() ..() - var/mysteryselect = pick(1,2,3,4,5,6,7,8,9,10) - switch(mysteryselect) - if(1) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("capsaicin", 3) - reagents.add_reagent("tomatojuice", 2) - if(2) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("frostoil", 3) - reagents.add_reagent("tomatojuice", 2) - if(3) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("water", 5) - reagents.add_reagent("omnizine", 5) - if(4) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("water", 10) - if(5) - reagents.add_reagent("nutriment", 2) - reagents.add_reagent("banana", 10) - if(6) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("blood", 10) - if(7) - reagents.add_reagent("slimejelly", 10) - reagents.add_reagent("water", 10) - if(8) - reagents.add_reagent("carbon", 10) - reagents.add_reagent("toxin", 10) - if(9) - reagents.add_reagent("nutriment", 5) - reagents.add_reagent("tomatojuice", 10) - if(10) - reagents.add_reagent("nutriment", 6) - reagents.add_reagent("tomatojuice", 5) - reagents.add_reagent("oculine", 5) + extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") + reagents.add_reagent("[extra_reagent]", 5) /obj/item/weapon/reagent_containers/food/snacks/wishsoup name = "Wish Soup" @@ -1195,7 +1151,8 @@ ..() if(prob(25)) desc = "A wish come true!" // hue - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("nutriment", 9) + reagents.add_reagent("vitamin", 1) /obj/item/weapon/reagent_containers/food/snacks/hotchili name = "Hot Chili" @@ -1204,7 +1161,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#FF3C00" bitesize = 5 - list_reagents = list("nutriment" = 6, "capsaicin" = 3, "tomatojuice" = 2) + list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/coldchili name = "Cold Chili" @@ -1213,20 +1170,18 @@ filling_color = "#2B00FF" trash = /obj/item/trash/snack_bowl bitesize = 5 - list_reagents = list("nutriment" = 6, "frostoil" = 3, "tomatojuice" = 2) + list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/raw_bacon name = "raw bacon" desc = "It's fleshy and pink!" icon_state = "raw_bacon" - bitesize = 2 list_reagents = list("nutriment" = 1, "porktonium" = 10) /obj/item/weapon/reagent_containers/food/snacks/bacon name = "bacon" desc = "It looks juicy and tastes amazing!" icon_state = "bacon2" - bitesize = 2 list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) /obj/item/weapon/reagent_containers/food/snacks/telebacon @@ -1234,7 +1189,6 @@ desc = "It tastes a little odd but it is still delicious." icon_state = "bacon" var/obj/item/device/radio/beacon/bacon/baconbeacon - bitesize = 2 list_reagents = list("nutriment" = 4, "porktonium" = 10) /obj/item/weapon/reagent_containers/food/snacks/telebacon/New() @@ -1254,12 +1208,12 @@ bitesize = 12 filling_color = "#ADAC7F" var/monkey_type = "Monkey" - list_reagents = list("protein" = 10) + list_reagents = list("nutriment" = 2) /obj/item/weapon/reagent_containers/food/snacks/monkeycube/afterattack(obj/O, mob/user, proximity) if(!proximity) return - if(istype(O,/obj/structure/sink) && !wrapped) + if(istype(O, /obj/structure/sink)) to_chat(user, "You place [src] under a stream of water...") user.drop_item() forceMove(get_turf(O)) @@ -1268,22 +1222,16 @@ var/obj/machinery/computer/camera_advanced/xenobio/X = O X.monkeys++ to_chat(user, "You feed [src] to the [X]. It now has [X.monkeys] monkey cubes stored.") + user.drop_item() qdel(src) return ..() -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/attack_self(mob/user) - if(wrapped) - Unwrap(user) - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature) if(volume >= 5) return Expand() /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) - if(wrapped) - ..() - return if(do_after(user, 40, target = source)) return 1 @@ -1293,57 +1241,30 @@ 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" - desc = "Just add water!" - to_chat(user, "You unwrap the cube.") - wrapped = 0 - -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped - desc = "Still wrapped in some paper." - icon_state = "monkeycubewrap" - wrapped = 1 - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube name = "farwa cube" monkey_type = "Farwa" -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube - name = "farwa cube" - monkey_type = "Farwa" - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wolpincube name = "wolpin cube" monkey_type = "Wolpin" -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube - name = "wolpin cube" - monkey_type = "Wolpin" - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube name = "stok cube" monkey_type = "Stok" -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube - name = "stok cube" - monkey_type = "Stok" - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube name = "neaera cube" monkey_type = "Neara" -/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube - name = "neaera cube" - monkey_type = "Neara" - /obj/item/weapon/reagent_containers/food/snacks/spellburger name = "Spell Burger" desc = "This is absolutely Ei Nath." icon_state = "spellburger" filling_color = "#D505FF" - bitesize = 2 - list_reagents = list("nutriment" = 6) + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger name = "Big Bite Burger" @@ -1351,7 +1272,7 @@ icon_state = "bigbiteburger" filling_color = "#E3D681" bitesize = 3 - list_reagents = list("nutriment" = 14) + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/enchiladas name = "Enchiladas" @@ -1368,7 +1289,7 @@ icon_state = "burrito" trash = /obj/item/trash/plate filling_color = "#A36A1F" - list_reagents = list("nutriment" = 5) + list_reagents = list("nutriment" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/chimichanga name = "Chimichanga" @@ -1385,7 +1306,7 @@ trash = /obj/item/trash/tray filling_color = "#5C3C11" bitesize = 6 - list_reagents = list("nutriment" = 10, "banana" = 5, "blackpepper" = 1, "sodiumchloride" = 1) + list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/baguette name = "Baguette" @@ -1393,7 +1314,7 @@ icon_state = "baguette" filling_color = "#E3D796" bitesize = 3 - list_reagents = list("nutriment" = 6, "blackpepper" = 1, "sodiumchloride" = 1) + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/sandwich name = "Sandwich" @@ -1401,8 +1322,7 @@ icon_state = "sandwich" trash = /obj/item/trash/plate filling_color = "#D9BE29" - bitesize = 2 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich name = "Toasted Sandwich" @@ -1410,7 +1330,6 @@ icon_state = "toastedsandwich" trash = /obj/item/trash/plate filling_color = "#D9BE29" - bitesize = 2 list_reagents = list("nutriment" = 6, "carbon" = 2) /obj/item/weapon/reagent_containers/food/snacks/grilledcheese @@ -1419,8 +1338,7 @@ icon_state = "toastedsandwich" trash = /obj/item/trash/plate filling_color = "#D9BE29" - bitesize = 2 - list_reagents = list("nutriment" = 7) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? + list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? /obj/item/weapon/reagent_containers/food/snacks/tomatosoup name = "Tomato Soup" @@ -1428,8 +1346,8 @@ icon_state = "tomatosoup" trash = /obj/item/trash/snack_bowl filling_color = "#D92929" - bitesize = 3 - list_reagents = list("nutriment" = 5, "tomatojuice" = 10) + bitesize = 5 + list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles name = "Roffle Waffles" @@ -1438,15 +1356,15 @@ trash = /obj/item/trash/waffles filling_color = "#FF00F7" bitesize = 4 - list_reagents = list("nutriment" = 8, "psilocybin" = 8) + list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/stew name = "Stew" desc = "A nice and warm stew. Healthy and strong." icon_state = "stew" filling_color = "#9E673A" - bitesize = 10 - list_reagents = list("nutriment" = 10, "tomatojuice" = 5, "oculine" = 5, "water" = 5) + bitesize = 7 + list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast name = "Jellied Toast" @@ -1455,42 +1373,39 @@ trash = /obj/item/trash/plate filling_color = "#B572AB" bitesize = 3 - list_reagents = list("nutriment" = 1) /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/cherry - list_reagents = list("nutriment" = 1, "cherryjelly" = 5) + list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jelliedtoast/slime - list_reagents = list("nutriment" = 1, "slimejelly" = 5) + list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jellyburger name = "Jelly Burger" desc = "Culinary delight..?" icon_state = "jellyburger" filling_color = "#B572AB" - bitesize = 2 - list_reagents = list("nutriment" = 5) + bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/jellyburger/slime - list_reagents = list("nutriment" = 5, "slimejelly" = 5) + list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry - list_reagents = list("nutriment" = 5, "cherryjelly" = 5) + list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/milosoup name = "Milosoup" desc = "The universes best soup! Yum!!!" icon_state = "milosoup" trash = /obj/item/trash/snack_bowl - bitesize = 4 - list_reagents = list("nutriment" = 8, "water" = 5) + bitesize = 5 + list_reagents = list("nutriment" = 7, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat name = "Stewed Soy Meat" desc = "Even non-vegetarians will LOVE this!" icon_state = "stewedsoymeat" trash = /obj/item/trash/plate - bitesize = 2 list_reagents = list("nutriment" = 8) /obj/item/weapon/reagent_containers/food/snacks/boiledspagetti @@ -1499,8 +1414,7 @@ icon_state = "spagettiboiled" trash = /obj/item/trash/plate filling_color = "#FCEE81" - bitesize = 2 - list_reagents = list("nutriment" = 2) + list_reagents = list("nutriment" = 2, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/boiledrice name = "Boiled Rice" @@ -1508,8 +1422,7 @@ icon_state = "boiledrice" trash = /obj/item/trash/snack_bowl filling_color = "#FFFBDB" - bitesize = 2 - list_reagents = list("nutriment" = 2) + list_reagents = list("nutriment" = 5, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/ricepudding name = "Rice Pudding" @@ -1517,8 +1430,7 @@ icon_state = "rpudding" trash = /obj/item/trash/snack_bowl filling_color = "#FFFBDB" - bitesize = 2 - list_reagents = list("nutriment" = 4) + list_reagents = list("nutriment" = 7, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/pastatomato name = "Spagetti" @@ -1527,7 +1439,7 @@ trash = /obj/item/trash/plate filling_color = "#DE4545" bitesize = 4 - list_reagents = list("nutriment" = 6, "tomatojuice" = 10) + list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/meatballspagetti name = "Spagetti & Meatballs" @@ -1535,23 +1447,20 @@ icon_state = "meatballspagetti" trash = /obj/item/trash/plate filling_color = "#DE4545" - bitesize = 2 - list_reagents = list("nutriment" = 8, "synaptizine" = 5) + list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/spesslaw name = "Spesslaw" desc = "A lawyers favourite" icon_state = "spesslaw" filling_color = "#DE4545" - bitesize = 2 - list_reagents = list("nutriment" = 8, "synaptizine" = 10) + list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/poppypretzel name = "Poppy Pretzel" desc = "A large soft pretzel full of POP!" icon_state = "poppypretzel" filling_color = "#AB7D2E" - bitesize = 2 list_reagents = list("nutriment" = 5) /obj/item/weapon/reagent_containers/food/snacks/carrotfries @@ -1560,16 +1469,15 @@ icon_state = "carrotfries" trash = /obj/item/trash/plate filling_color = "#FAA005" - bitesize = 2 - list_reagents = list("plantmatter" = 3, "oculine" = 3) + list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/superbiteburger name = "Super Bite Burger" desc = "This is a mountain of a burger. FOOD!" icon_state = "superbiteburger" filling_color = "#CCA26A" - bitesize = 10 - list_reagents = list("nutriment" = 50) + bitesize = 7 + list_reagents = list("nutriment" = 40, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/candiedapple name = "Candied Apple" @@ -1577,7 +1485,7 @@ icon_state = "candiedapple" filling_color = "#F21873" bitesize = 3 - list_reagents = list("nutriment" = 3) // A candy apple without sugar... + list_reagents = list("nutriment" = 3, "sugar" = 2) /obj/item/weapon/reagent_containers/food/snacks/applepie name = "Apple Pie" @@ -1585,7 +1493,7 @@ icon_state = "applepie" filling_color = "#E0EDC5" bitesize = 3 - list_reagents = list("nutriment" = 4) + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/cherrypie name = "Cherry Pie" @@ -1593,7 +1501,7 @@ icon_state = "cherrypie" filling_color = "#FF525A" bitesize = 3 - list_reagents = list("nutriment" = 4) + list_reagents = list("nutriment" = 10, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/twobread name = "Two Bread" @@ -1601,7 +1509,7 @@ icon_state = "twobread" filling_color = "#DBCC9A" bitesize = 3 - list_reagents = list("nutriment" = 2) + list_reagents = list("nutriment" = 2, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jellysandwich name = "Jelly Sandwich" @@ -1610,13 +1518,12 @@ trash = /obj/item/trash/plate filling_color = "#9E3A78" bitesize = 3 - list_reagents = list("nutriment" = 2) /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime - list_reagents = list("nutriment" = 2, "slimejelly" = 5) + list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry - list_reagents = list("nutriment" = 2, "cherryjelly" = 5) + list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/boiledslimecore name = "Boiled Slime Core" @@ -1629,8 +1536,9 @@ name = "mint" desc = "it is only wafer thin." icon_state = "mint" + bitesize = 1 filling_color = "#F2F2F2" - list_reagents = list("minttoxin" = 2) + list_reagents = list("minttoxin" = 1) /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup name = "chantrelle soup" @@ -1638,15 +1546,14 @@ icon_state = "mushroomsoup" trash = /obj/item/trash/snack_bowl filling_color = "#E386BF" - bitesize = 3 - list_reagents = list("nutriment" = 8) + bitesize = 5 + list_reagents = list("nutriment" = 8, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit name = "plump helmet biscuit" desc = "This is a finely-prepared plump helmet biscuit. The ingredients are exceptionally minced plump helmet, and well-minced dwarven wheat flour." icon_state = "phelmbiscuit" filling_color = "#CFB4C4" - bitesize = 2 list_reagents = list("nutriment" = 5) /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New() @@ -1654,7 +1561,6 @@ if(prob(10)) name = "exceptional plump helmet biscuit" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" // Is this a reference? - reagents.add_reagent("nutriment", 3) reagents.add_reagent("omnizine", 5) /obj/item/weapon/reagent_containers/food/snacks/chawanmushi @@ -1670,25 +1576,13 @@ desc = "Wait, how do you spell it again..?" icon_state = "beetsoup" trash = /obj/item/trash/snack_bowl + bitesize = 5 filling_color = "#FAC9FF" - bitesize = 2 - list_reagents = list("nutriment" = 8) + list_reagents = list("nutriment" = 7, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/beetsoup/New() ..() - switch(rand(1,6)) - if(1) - name = "borsch" - if(2) - name = "bortsch" - if(3) - name = "borstch" - if(4) - name = "borsh" - if(5) - name = "borshch" - if(6) - name = "borscht" + name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") /obj/item/weapon/reagent_containers/food/snacks/herbsalad name = "herb salad" @@ -1697,7 +1591,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#76B87F" bitesize = 3 - list_reagents = list("nutriment" = 8) + list_reagents = list("nutriment" = 8, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/validsalad name = "valid salad" @@ -1706,7 +1600,7 @@ trash = /obj/item/trash/snack_bowl filling_color = "#76B87F" bitesize = 3 - list_reagents = list("nutriment" = 8, "omnizine" = 5) + list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/appletart name = "golden apple streusel tart" @@ -1715,45 +1609,13 @@ trash = /obj/item/trash/plate filling_color = "#FFFF00" bitesize = 3 - list_reagents = list("nutriment" = 8, "gold" = 5) - -/obj/item/weapon/reagent_containers/food/snacks/dough_ball - name = "ball of raw dough" - desc = "A ball of raw dough, ready to be molded into new recipes." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "dough" - list_reagents = list("nutriment" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/dough_ball/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W,/obj/item/weapon/kitchen/rollingpin)) - user.visible_message( \ - "[user] flattens the dough with the rolling pin!", \ - "You flatten the dough with your rolling pin!" \ - ) - new /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough(loc) - qdel(src) + list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) /////////////////////////////////////////////////Sliceable//////////////////////////////////////// // All the food items that can be sliced into smaller bits like Meatbread and Cheesewheels // sliceable is just an organization type path, it doesn't have any additional code or variables tied to it. -/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough - name = "flattened dough" - desc = "Still raw. You resist the temptation to cover it in tomato sauce." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flatdough" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice - slices_num = 3 - list_reagents = list("nutriment" = 3) - -/obj/item/weapon/reagent_containers/food/snacks/doughslice - name = "slice of dough" - desc = "an individual portion of raw dough, ready to be cooked." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "doughslice" - bitesize = 2 - /obj/item/weapon/reagent_containers/food/snacks/sliceable/meatbread name = "meatbread loaf" desc = "The culinary base of every self-respecting eloquen/tg/entleman." @@ -1761,8 +1623,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/meatbreadslice slices_num = 5 filling_color = "#FF7575" - bitesize = 2 - list_reagents = list("protein" = 20, "nutriment" = 10) + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/meatbreadslice name = "meatbread slice" @@ -1770,7 +1631,6 @@ icon_state = "meatbreadslice" trash = /obj/item/trash/plate filling_color = "#FF7575" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread name = "xenomeatbread loaf" @@ -1779,8 +1639,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/xenomeatbreadslice slices_num = 5 filling_color = "#8AFF75" - bitesize = 2 - list_reagents = list("protein" = 20, "nutriment" = 10) + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/xenomeatbreadslice name = "xenomeatbread slice" @@ -1788,7 +1647,6 @@ icon_state = "xenobreadslice" trash = /obj/item/trash/plate filling_color = "#8AFF75" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/spidermeatbread name = "spider meat loaf" @@ -1796,15 +1654,13 @@ icon_state = "spidermeatbread" slice_path = /obj/item/weapon/reagent_containers/food/snacks/spidermeatbreadslice slices_num = 5 - bitesize = 2 - list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15) + list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/spidermeatbreadslice name = "spider meat bread slice" desc = "A slice of meatloaf made from an animal that most likely still wants you dead." icon_state = "xenobreadslice" trash = /obj/item/trash/plate - bitesize = 2 list_reagents = list("toxin" = 2) /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread @@ -1814,7 +1670,6 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/bananabreadslice slices_num = 5 filling_color = "#EDE5AD" - bitesize = 2 list_reagents = list("banana" = 20, "nutriment" = 20) /obj/item/weapon/reagent_containers/food/snacks/bananabreadslice @@ -1823,7 +1678,6 @@ icon_state = "bananabreadslice" trash = /obj/item/trash/plate filling_color = "#EDE5AD" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread name = "Tofubread" @@ -1832,8 +1686,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/tofubreadslice slices_num = 5 filling_color = "#F7FFE0" - bitesize = 2 - list_reagents = list("nutriment" = 30) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/tofubreadslice name = "Tofubread slice" @@ -1841,7 +1694,6 @@ icon_state = "tofubreadslice" trash = /obj/item/trash/plate filling_color = "#F7FFE0" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake name = "Carrot Cake" @@ -1849,9 +1701,9 @@ icon_state = "carrotcake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice slices_num = 5 + bitesize = 3 filling_color = "#FFD675" - bitesize = 2 - list_reagents = list("nutriment" = 25, "oculine" = 10) + list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice name = "Carrot Cake slice" @@ -1859,7 +1711,6 @@ icon_state = "carrotcake_slice" trash = /obj/item/trash/plate filling_color = "#FFD675" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake name = "Brain Cake" @@ -1868,8 +1719,8 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/braincakeslice slices_num = 5 filling_color = "#E6AEDB" - bitesize = 2 - list_reagents = list("protein" = 15, "nutriment" = 10, "mannitol" = 10) + bitesize = 3 + list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/braincakeslice name = "Brain Cake slice" @@ -1877,7 +1728,6 @@ icon_state = "braincakeslice" trash = /obj/item/trash/plate filling_color = "#E6AEDB" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake name = "Cheese Cake" @@ -1886,8 +1736,8 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice slices_num = 5 filling_color = "#FAF7AF" - bitesize = 2 - list_reagents = list("nutriment" = 25) + bitesize = 3 + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice name = "Cheese Cake slice" @@ -1895,7 +1745,6 @@ icon_state = "cheesecake_slice" trash = /obj/item/trash/plate filling_color = "#FAF7AF" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake name = "Vanilla Cake" @@ -1903,8 +1752,9 @@ icon_state = "plaincake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/plaincakeslice slices_num = 5 + bitesize = 3 filling_color = "#F7EDD5" - list_reagents = list("nutriment" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/plaincakeslice name = "Vanilla Cake slice" @@ -1912,7 +1762,6 @@ icon_state = "plaincake_slice" trash = /obj/item/trash/plate filling_color = "#F7EDD5" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake name = "Orange Cake" @@ -1920,8 +1769,9 @@ icon_state = "orangecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/orangecakeslice slices_num = 5 + bitesize = 3 filling_color = "#FADA8E" - list_reagents = list("nutriment" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/orangecakeslice name = "Orange Cake slice" @@ -1929,16 +1779,16 @@ icon_state = "orangecake_slice" trash = /obj/item/trash/plate filling_color = "#FADA8E" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake name = "Lime Cake" desc = "A cake with added lime." icon_state = "limecake" + bitesize = 3 slice_path = /obj/item/weapon/reagent_containers/food/snacks/limecakeslice slices_num = 5 filling_color = "#CBFA8E" - list_reagents = list("nutriment" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/limecakeslice name = "Lime Cake slice" @@ -1946,7 +1796,6 @@ icon_state = "limecake_slice" trash = /obj/item/trash/plate filling_color = "#CBFA8E" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake name = "Lemon Cake" @@ -1954,8 +1803,9 @@ icon_state = "lemoncake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice slices_num = 5 + bitesize = 3 filling_color = "#FAFA8E" - list_reagents = list("nutriment" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/lemoncakeslice name = "Lemon Cake slice" @@ -1963,7 +1813,6 @@ icon_state = "lemoncake_slice" trash = /obj/item/trash/plate filling_color = "#FAFA8E" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake name = "Chocolate Cake" @@ -1971,8 +1820,9 @@ icon_state = "chocolatecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice slices_num = 5 + bitesize = 3 filling_color = "#805930" - list_reagents = list("nutriment" = 20, "chocolate" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/chocolatecakeslice name = "Chocolate Cake slice" @@ -1980,7 +1830,6 @@ icon_state = "chocolatecake_slice" trash = /obj/item/trash/plate filling_color = "#805930" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel name = "Cheese wheel" @@ -1989,22 +1838,19 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/cheesewedge slices_num = 5 filling_color = "#FFF700" - bitesize = 2 - list_reagents = list("nutriment" = 20, "cheese" = 20) + list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) /obj/item/weapon/reagent_containers/food/snacks/cheesewedge name = "Cheese wedge" desc = "A wedge of delicious Cheddar. The cheese wheel it was cut from can't have gone far." icon_state = "cheesewedge" filling_color = "#FFF700" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/weirdcheesewedge name = "Weird Cheese" desc = "Some kind of... gooey, messy, gloopy thing. Similar to cheese, but only in the looser sense of the word." icon_state = "weirdcheesewedge" filling_color = "#00FF33" - bitesize = 2 list_reagents = list("mercury" = 5, "lsd" = 5, "ethanol" = 5, "weird_cheese" = 5) /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake @@ -2015,7 +1861,7 @@ slices_num = 5 filling_color = "#FFD6D6" bitesize = 3 - list_reagents = list("nutriment" = 20, "sprinkles" = 10) + list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/birthdaycakeslice name = "Birthday Cake slice" @@ -2023,7 +1869,6 @@ icon_state = "birthdaycakeslice" trash = /obj/item/trash/plate filling_color = "#FFD6D6" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/bread name = "Bread" @@ -2032,8 +1877,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/breadslice slices_num = 6 filling_color = "#FFE396" - bitesize = 2 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 10) /obj/item/weapon/reagent_containers/food/snacks/breadslice name = "Bread slice" @@ -2041,8 +1885,7 @@ icon_state = "breadslice" trash = /obj/item/trash/plate filling_color = "#D27332" - bitesize = 2 - list_reagents = list("bread" = 5) + list_reagents = list("nutriment" = 2, "bread" = 5) /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread name = "Cream Cheese Bread" @@ -2051,8 +1894,7 @@ slice_path = /obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice slices_num = 5 filling_color = "#FFF896" - bitesize = 2 - list_reagents = list("nutriment" = 20) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice name = "Cream Cheese Bread slice" @@ -2060,14 +1902,13 @@ icon_state = "creamcheesebreadslice" trash = /obj/item/trash/plate filling_color = "#FFF896" - bitesize = 2 + list_reagents = list("nutriment" = 4, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/watermelonslice name = "Watermelon Slice" desc = "A slice of watery goodness." icon_state = "watermelonslice" filling_color = "#FF3867" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake name = "Apple Cake" @@ -2075,8 +1916,9 @@ icon_state = "applecake" slice_path = /obj/item/weapon/reagent_containers/food/snacks/applecakeslice slices_num = 5 + bitesize = 3 filling_color = "#EBF5B8" - list_reagents = list("nutriment" = 15) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/applecakeslice name = "Apple Cake slice" @@ -2084,7 +1926,6 @@ icon_state = "applecakeslice" trash = /obj/item/trash/plate filling_color = "#EBF5B8" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie name = "Pumpkin Pie" @@ -2092,8 +1933,9 @@ icon_state = "pumpkinpie" slice_path = /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice slices_num = 5 + bitesize = 3 filling_color = "#F5B951" - list_reagents = list("nutriment" = 15) + list_reagents = list("nutriment" = 20, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/pumpkinpieslice name = "Pumpkin Pie slice" @@ -2101,12 +1943,12 @@ icon_state = "pumpkinpieslice" trash = /obj/item/trash/plate filling_color = "#F5B951" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/cracker name = "Cracker" desc = "It's a salted cracker." icon_state = "cracker" + bitesize = 1 filling_color = "#F5DEB8" list_reagents = list("nutriment" = 1) @@ -2140,15 +1982,14 @@ icon_state = "pizzamargherita" slice_path = /obj/item/weapon/reagent_containers/food/snacks/margheritaslice slices_num = 6 - bitesize = 2 - list_reagents = list("nutriment" = 40, "tomatojuice" = 6) + list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/margheritaslice name = "Margherita slice" desc = "A slice of the classic pizza." icon_state = "pizzamargheritaslice" filling_color = "#BAA14C" - bitesize = 2 + list_reagents = list("nutriment" = 5) /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza name = "Meatpizza" @@ -2156,15 +1997,13 @@ icon_state = "meatpizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/meatpizzaslice slices_num = 6 - bitesize = 2 - list_reagents = list("protein" = 30, "nutriment" = 20, "tomatojuice" = 6) + list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) /obj/item/weapon/reagent_containers/food/snacks/meatpizzaslice name = "Meatpizza slice" desc = "A slice of a meaty pizza." icon_state = "meatpizzaslice" filling_color = "#BAA14C" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza name = "Mushroompizza" @@ -2172,15 +2011,13 @@ icon_state = "mushroompizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice slices_num = 6 - bitesize = 2 - list_reagents = list("plantmatter" = 25, "nutriment" = 10) + list_reagents = list("plantmatter" = 30, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice name = "Mushroompizza slice" desc = "Maybe it is the last slice of pizza in your life." icon_state = "mushroompizzaslice" filling_color = "#BAA14C" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza name = "Vegetable pizza" @@ -2188,15 +2025,13 @@ icon_state = "vegetablepizza" slice_path = /obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice slices_num = 6 - bitesize = 2 - list_reagents = list("plantmatter" = 20, "nutriment" = 10, "tomatojuice" = 6, "oculine" = 12) + list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/vegetablepizzaslice name = "Vegetable pizza slice" desc = "A slice of the most green pizza of all pizzas not containing green ingredients " icon_state = "vegetablepizzaslice" filling_color = "#BAA14C" - bitesize = 2 /obj/item/pizzabox name = "pizza box" @@ -2377,57 +2212,52 @@ name = "egg wrap" desc = "The precursor to Pigs in a Blanket." icon_state = "wrap" - bitesize = 2 list_reagents = list("nutriment" = 5) /obj/item/weapon/reagent_containers/food/snacks/beans name = "tin of beans" desc = "Musical fruit in a slightly less musical container." icon_state = "beans" - bitesize = 2 - list_reagents = list("nutriment" = 10, "beans" = 10) + list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/benedict name = "eggs benedict" desc = "There is only one egg on this, how rude." icon_state = "benedict" bitesize = 3 - list_reagents = list("nutriment" = 3, "egg" = 3) + list_reagents = list("nutriment" = 6, "egg" = 3, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/hotdog name = "hotdog" desc = "Fresh footlong ready to go down on." icon_state = "hotdog" bitesize = 3 - list_reagents = list("nutriment" = 3, "ketchup" = 3) + list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) /obj/item/weapon/reagent_containers/food/snacks/meatbun name = "meat bun" desc = "Has the potential to not be Dog." icon_state = "meatbun" bitesize = 6 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 6, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich name = "icecream sandwich" desc = "Portable Ice-cream in it's own packaging." icon_state = "icecreamsandwich" - bitesize = 2 list_reagents = list("nutriment" = 2, "ice" = 2) /obj/item/weapon/reagent_containers/food/snacks/notasandwich name = "not-a-sandwich" desc = "Something seems to be wrong with this, you can't quite figure what. Maybe it's his moustache." icon_state = "notasandwich" - bitesize = 2 - list_reagents = list("nutriment" = 6) + list_reagents = list("nutriment" = 6, "vitamin" = 6) /obj/item/weapon/reagent_containers/food/snacks/sugarcookie name = "sugar cookie" desc = "Just like your little sister used to make." icon_state = "sugarcookie" - bitesize = 2 - list_reagents = list("nutriment" = 2, "sugar" = 5) + list_reagents = list("nutriment" = 3, "sugar" = 3) /obj/item/weapon/reagent_containers/food/snacks/friedbanana name = "Fried Banana" @@ -2441,8 +2271,7 @@ icon_state = "dionaroast" trash = /obj/item/trash/plate filling_color = "#75754B" - bitesize = 2 - list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2) + list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) /obj/item/weapon/reagent_containers/food/snacks/boiledspiderleg name = "boiled spider leg" @@ -2450,14 +2279,13 @@ icon_state = "spiderlegcooked" trash = /obj/item/trash/plate bitesize = 3 - list_reagents = list("nutriment" = 3, "toxin" = 2) + list_reagents = list("nutriment" = 3, "capsaicin" = 2) /obj/item/weapon/reagent_containers/food/snacks/spidereggs name = "spider eggs" desc = "A cluster of juicy spider eggs. A great side dish for when you care not for your health." icon_state = "spidereggs" - bitesize = 2 - list_reagents = list("protein" = 2, "toxin" = 3) + list_reagents = list("protein" = 2, "toxin" = 2) /obj/item/weapon/reagent_containers/food/snacks/spidereggsham name = "green eggs and ham" @@ -2465,7 +2293,7 @@ icon_state = "spidereggsham" trash = /obj/item/trash/plate bitesize = 4 - list_reagents = list("nutriment" = 6, "sodiumchloride" = 1, "toxin" = 3) + list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/sliceable/turkey name = "Turkey" @@ -2473,8 +2301,7 @@ icon_state = "turkey" slice_path = /obj/item/weapon/reagent_containers/food/snacks/turkeyslice slices_num = 6 - bitesize = 2 - list_reagents = list("protein" = 24, "nutriment" = 18) + list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) /obj/item/weapon/reagent_containers/food/snacks/turkeyslice name = "turkey serving" @@ -2482,7 +2309,6 @@ icon_state = "turkeyslice" trash = /obj/item/trash/plate filling_color = "#B97A57" - bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/mashed_potatoes //mashed taters name = "mashed potatoes" @@ -2490,8 +2316,7 @@ icon_state = "mashedtaters" trash = /obj/item/trash/plate filling_color = "#D6D9C1" - bitesize = 2 - list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10) + list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) ////////////////////////////////ICE CREAM/////////////////////////////////// /obj/item/weapon/reagent_containers/food/snacks/icecream @@ -2499,6 +2324,7 @@ desc = "Delicious ice cream." icon = 'icons/obj/kitchen.dmi' icon_state = "icecream_cone" + bitesize = 3 list_reagents = list("nutriment" = 1, "sugar" = 1) /obj/item/weapon/reagent_containers/food/snacks/icecream/New() @@ -2532,7 +2358,6 @@ desc = "A box of cereal." icon = 'icons/obj/food/food.dmi' icon_state = "cereal_box" - bitesize = 2 list_reagents = list("nutriment" = 3) /obj/item/weapon/reagent_containers/food/snacks/deepfryholder @@ -2540,7 +2365,6 @@ desc = "If you can see this description the code for the deep fryer fucked up." icon = 'icons/obj/food/food.dmi' icon_state = "deepfried_holder_icon" - bitesize = 2 list_reagents = list("nutriment" = 3) /obj/item/weapon/reagent_containers/food/snacks/dough @@ -2548,8 +2372,7 @@ desc = "A piece of dough." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "dough" - bitesize = 2 - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) // Dough + rolling pin = flat dough /obj/item/weapon/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) @@ -2571,14 +2394,13 @@ icon_state = "flat dough" slice_path = /obj/item/weapon/reagent_containers/food/snacks/doughslice slices_num = 3 - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6) /obj/item/weapon/reagent_containers/food/snacks/doughslice name = "dough slice" desc = "The building block of an impressive dish." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "doughslice" - bitesize = 2 list_reagents = list("nutriment" = 1) /obj/item/weapon/reagent_containers/food/snacks/bun @@ -2586,53 +2408,34 @@ desc = "The base for any self-respecting burger." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "bun" - bitesize = 3 - list_reagents = list("nutriment" = 4) + list_reagents = list("nutriment" = 1) /obj/item/weapon/reagent_containers/food/snacks/taco name = "taco" desc = "Take a bite!" icon_state = "taco" bitesize = 3 - list_reagents = list("nutriment" = 7) + list_reagents = list("nutriment" = 7, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/cutlet name = "cutlet" desc = "A tasty meat slice." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "cutlet" - bitesize = 2 list_reagents = list("protein" = 2) -/obj/item/weapon/reagent_containers/food/snacks/rawmeatball - name = "raw meatball" - desc = "A raw meatball." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "rawmeatball" - bitesize = 2 - list_reagents = list("protein" = 2) - -/obj/item/weapon/reagent_containers/food/snacks/hotdog - name = "hotdog" - desc = "Unrelated to dogs, maybe." - icon_state = "hotdog" - bitesize = 2 - list_reagents = list("protein" = 6) - /obj/item/weapon/reagent_containers/food/snacks/flatbread name = "flatbread" desc = "Bland but filling." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "flatbread" - bitesize = 2 - list_reagents = list("nutriment" = 3) + list_reagents = list("nutriment" = 6, "vitamin" = 1) /obj/item/weapon/reagent_containers/food/snacks/rawsticks name = "raw potato sticks" desc = "Raw fries, not very tasty." icon = 'icons/obj/food/food_ingredients.dmi' icon_state = "rawsticks" - bitesize = 2 list_reagents = list("plantmatter" = 3) /obj/item/weapon/reagent_containers/food/snacks/ectoplasm @@ -2649,7 +2452,7 @@ trash = /obj/item/trash/liquidfood filling_color = "#A8A8A8" bitesize = 4 - list_reagents = list("nutriment" = 20, "iron" = 3) + list_reagents = list("nutriment" = 20, "iron" = 3, "vitamin" = 2) /obj/item/weapon/reagent_containers/food/snacks/tastybread @@ -2658,5 +2461,28 @@ icon_state = "tastybread" trash = /obj/item/trash/tastybread filling_color = "#A66829" - bitesize = 2 - list_reagents = list("nutriment" = 6) \ No newline at end of file + junkiness = 20 + list_reagents = list("nutriment" = 2, "sugar" = 4) + +/obj/item/weapon/reagent_containers/food/snacks/yakiimo + name = "yaki imo" + desc = "Made with roasted sweet potatoes!" + icon_state = "yakiimo" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 5, "vitamin" = 4) + filling_color = "#8B1105" + +/obj/item/weapon/reagent_containers/food/snacks/roastparsnip + name = "roast parsnip" + desc = "Sweet and crunchy." + icon_state = "roastparsnip" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 3, "vitamin" = 4) + filling_color = "#FF5500" + +/obj/item/weapon/reagent_containers/food/snacks/tatortot + name = "tator tot" + desc = "A large fried potato nugget that may or may not try to valid you." + icon_state = "tatortot" + list_reagents = list("nutriment" = 4) + filling_color = "FFD700" \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 73607d4e3ab..d9b98c82724 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -48,11 +48,7 @@ return 0 for(var/Type in subtypesof(/datum/deepfryer_special)) var/datum/deepfryer_special/P = new Type() - if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/grown)) - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = I - if(G.seed.kitchen_tag != P.input) - continue - else if(!istype(I, P.input)) + if(!istype(I, P.input)) continue return P return 0 diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index fafa983cf1d..908411f5731 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -12,8 +12,12 @@ var/locked = 0 //Used to prevent mobs from breaking the feedin anim var/gib_throw_dir = WEST // Direction to spit meat and gibs in. Defaults to west. - var/gibtime = 40 // Time from starting until meat appears + var/gibtime = 40 // Time from starting until meat appears + var/animation_delay = GIBBER_ANIMATION_DELAY + + // For hiding gibs, making an even more devious trap (invisible autogibbers) + var/stealthmode = FALSE var/list/victims = list() use_power = 1 @@ -110,25 +114,25 @@ /obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) if(occupant) - to_chat(user, "The gibber is full, empty it first!") + to_chat(user, "The [src] is full, empty it first!") return if(operating) - to_chat(user, "The gibber is locked and running, wait for it to finish.") + to_chat(user, "The [src] is locked and running, wait for it to finish.") return if(!ishuman(victim) || issmall(victim)) - to_chat(user, "This is not suitable for the gibber!") + to_chat(user, "This is not suitable for the [src]]!") return if(victim.abiotic(1)) to_chat(user, "Subject may not have abiotic items on.") return - user.visible_message("[user] starts to put [victim] into the gibber!") + user.visible_message("[user] starts to put [victim] into the [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!") + user.visible_message("[user] stuffs [victim] into the [src]]!") victim.forceMove(src) occupant = victim @@ -195,16 +199,16 @@ 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 + animate(holder, pixel_y = 16, time = animation_delay) //animate going down - sleep(GIBBER_ANIMATION_DELAY) + sleep(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 + animate(holder, pixel_y = -3, time = animation_delay) //animate going down further - sleep(GIBBER_ANIMATION_DELAY) //time everything right, animate doesn't prevent proc from continuing + sleep(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 @@ -231,7 +235,7 @@ operating = 1 update_icon() var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = gibtime * 5) //start shaking var/slab_name = occupant.name var/slab_count = 3 @@ -254,8 +258,8 @@ 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)]" + occupant.create_attack_log("Was gibbed by [key_name(user)]") //One shall not simply gib a mob unnoticed!) + user.create_attack_log("Gibbed [key_name(occupant)]") if(occupant.ckey) msg_admin_attack("[key_name_admin(user)] gibbed [key_name_admin(occupant)]") @@ -266,11 +270,10 @@ 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.create_attack_log("Was gibbed by an autogibber (\the [src])") occupant.emote("scream") playsound(get_turf(src), 'sound/goonstation/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() @@ -281,15 +284,20 @@ 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) + if(stealthmode) + for(var/atom/movable/AM in contents) + qdel(AM) + sleep(1) + else + 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) + 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 @@ -306,6 +314,8 @@ var/acceptdir = NORTH var/lastacceptdir = NORTH var/turf/lturf + var/consumption_delay = 3 SECONDS + var/list/victim_targets = list() /obj/machinery/gibber/autogibber/New() ..() @@ -320,7 +330,7 @@ RefreshParts() /obj/machinery/gibber/autogibber/process() - if(!lturf || occupant || locked || dirty || operating) + if(!lturf || occupant || locked || dirty || operating || victim_targets.len) return if(acceptdir != lastacceptdir) @@ -331,15 +341,21 @@ lturf = T for(var/mob/living/carbon/human/H in lturf) - if(istype(H) && H.loc == lturf) - visible_message({"\The [src] states, "Food detected!""}) - sleep(30) + victim_targets += H + + if(victim_targets.len) + visible_message({"\The [src] states, "Food detected!""}) + sleep(consumption_delay) + for(var/mob/living/carbon/H in victim_targets) if(H.loc == lturf) //still standing there if(force_move_into_gibber(H)) + locked = 1 // no escape ejectclothes(occupant) cleanbay() startgibbing(null, 1) + locked = 0 break + victim_targets.Cut() /obj/machinery/gibber/autogibber/proc/force_move_into_gibber(var/mob/living/carbon/human/victim) if(!istype(victim)) return 0 @@ -364,7 +380,7 @@ continue if(istype(O,/obj/item/organ)) continue - if(O.flags & NODROP) + if(O.flags & NODROP || stealthmode) qdel(O) //they are already dead by now H.unEquip(O) O.loc = loc @@ -372,7 +388,7 @@ sleep(1) for(var/obj/item/clothing/C in H) - if(C.flags & NODROP) + if(C.flags & NODROP || stealthmode) qdel(C) H.unEquip(C) C.loc = loc @@ -384,7 +400,9 @@ /obj/machinery/gibber/autogibber/proc/cleanbay() var/spats = 0 //keeps track of how many items get spit out. Don't show a message if none are found. for(var/obj/O in src) - if(istype(O)) + if(stealthmode) + qdel(O) + else if(istype(O)) O.loc = loc O.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) spats++ diff --git a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm index 03ceb5c0034..edf714d0f21 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/juicer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/juicer.dm @@ -4,27 +4,29 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" layer = 2.9 - density = 0 + density = 1 anchored = 0 use_power = 1 idle_power_usage = 5 active_power_usage = 100 + pass_flags = PASSTABLE var/obj/item/weapon/reagent_containers/beaker = null - var/global/list/allowed_items = list( + var/global/list/allowed_items = list ( + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = "tomatojuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot = "carrotjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = "grapejuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = "grapejuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/banana = "banana", + /obj/item/weapon/reagent_containers/food/snacks/grown/potato = "potato", + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = "lemonjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = "orangejuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = "limejuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = "watermelonjuice", /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = "watermelonjuice", - /obj/item/weapon/reagent_containers/food/snacks/grown = "water", - ) - - var/global/list/allowed_tags = list ( - "tomato" = "tomatojuice", - "carrot" = "carrotjuice", - "berries" = "berryjuice", - "banana" = "banana", - "potato" = "potato", - "lemon" = "lemonjuice", - "orange" = "orangejuice", - "lime" = "limejuice", - "poisonberries" = "poisonberryjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison = "poisonberryjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/berries = "berryjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = "pumpkinjuice", + /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = "blumpkinjuice", ) /obj/machinery/juicer/New() @@ -135,23 +137,18 @@ beaker = null update_icon() -/obj/machinery/juicer/proc/get_juice_id(var/obj/item/weapon/reagent_containers/food/snacks/O) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/watermelonslice)) - return "watermelonjuice" - else if(istype(O, /obj.item/weapon/reagent_containers/food/snacks/grown)) - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O - for(var/i in allowed_tags) - if(G.seed.kitchen_tag == allowed_tags[i]) - return allowed_tags[i] - return "water" +/obj/machinery/juicer/proc/get_juice_id(obj/item/weapon/reagent_containers/food/snacks/grown/O) + for (var/i in allowed_items) + if (istype(O, i)) + return allowed_items[i] -/obj/machinery/juicer/proc/get_juice_amount(var/obj/item/weapon/reagent_containers/food/snacks/grown/O) - if(!istype(O)) +/obj/machinery/juicer/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O) + if(!istype(O) || !O.seed) return 5 - else if(O.potency == -1) + else if (O.seed.potency == -1) return 5 else - return round(5*sqrt(O.potency)) + return round(5*sqrt(O.seed.potency)) /obj/machinery/juicer/proc/juice() power_change() //it is a portable machine @@ -167,19 +164,21 @@ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break -/obj/structure/closet/crate/juice - New() - ..() - new/obj/machinery/juicer(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) \ No newline at end of file +/obj/structure/closet/crate/juice/New() + ..() + new/obj/machinery/juicer(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/berries(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/banana(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/grapes(src) diff --git a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm index ef7591e3955..baf5e8e98ee 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/kitchen_machine.dm @@ -8,7 +8,7 @@ use_power = 1 idle_power_usage = 5 active_power_usage = 100 - flags = OPENCONTAINER | NOREACT + flags = OPENCONTAINER var/operating = 0 // Is it on? var/dirty = 0 // = {0..100} Does it need cleaning? var/broken = 0 // ={0,1,2} How broken is it??? @@ -33,6 +33,7 @@ /obj/machinery/kitchen_machine/New() create_reagents(100) + reagents.set_reacting(FALSE) if(!available_recipes) available_recipes = new acceptable_items = new @@ -45,7 +46,7 @@ acceptable_items |= item for(var/reagent in recipe.reagents) acceptable_reagents |= reagent - if(recipe.items || recipe.fruit) + if(recipe.items) max_n_of_items = max(max_n_of_items,recipe.count_n_items()) else qdel(recipe) diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 5183fe6a4fa..df9d1dddf4d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -71,21 +71,34 @@ input = /obj/item/weapon/reagent_containers/food/snacks/meat output = /obj/item/weapon/reagent_containers/food/snacks/meatball -/datum/food_processor_process/potato - input = "potato" +/datum/food_processor_process/potatowedges + input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges output = /obj/item/weapon/reagent_containers/food/snacks/fries +/datum/food_processor_process/sweetpotato + input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet + output = /obj/item/weapon/reagent_containers/food/snacks/yakiimo + +/datum/food_processor_process/potato + input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato + output = /obj/item/weapon/reagent_containers/food/snacks/tatortot + /datum/food_processor_process/carrot - input = "carrot" + input = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot output = /obj/item/weapon/reagent_containers/food/snacks/carrotfries /datum/food_processor_process/soybeans - input = "soybeans" + input = /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans output = /obj/item/weapon/reagent_containers/food/snacks/soydope /datum/food_processor_process/spaghetti input = /obj/item/weapon/reagent_containers/food/snacks/doughslice output = /obj/item/weapon/reagent_containers/food/snacks/spagetti + +/datum/food_processor_process/parsnip + input = /obj/item/weapon/reagent_containers/food/snacks/grown/parsnip + output = /obj/item/weapon/reagent_containers/food/snacks/roastparsnip + ///////////////////////// ///END OBJECT RECIPIES/// ///////////////////////// @@ -142,14 +155,10 @@ //END RECIPE DATUMS -/obj/machinery/processor/proc/select_recipe(var/X) +/obj/machinery/processor/proc/select_recipe(X) for(var/Type in subtypesof(/datum/food_processor_process) - /datum/food_processor_process/mob) var/datum/food_processor_process/P = new Type() - if(istype(X, /obj/item/weapon/reagent_containers/food/snacks/grown)) - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = X - if(G.seed.kitchen_tag != P.input) - continue - else if(!istype(X, P.input)) + if(!istype(X, P.input)) continue return P return 0 diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 149744675a9..936b9e30827 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -10,7 +10,6 @@ use_power = 1 idle_power_usage = 5 active_power_usage = 100 - flags = NOREACT var/max_n_of_items = 1500 var/icon_on = "smartfridge" var/icon_off = "smartfridge-off" @@ -21,10 +20,14 @@ var/locked = 0 var/scan_id = 1 var/is_secure = 0 + var/can_dry = FALSE + var/drying = FALSE var/datum/wires/smartfridge/wires = null /obj/machinery/smartfridge/New() ..() + create_reagents() + reagents.set_reacting(FALSE) component_parts = list() var/obj/item/weapon/circuitboard/smartfridge/board = new(null) board.set_type(type) @@ -54,7 +57,7 @@ return ..() /obj/machinery/smartfridge/proc/accept_check(obj/item/O) - if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/)) + if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown/) || istype(O,/obj/item/seeds/) || istype(O,/obj/item/weapon/grown/)) return 1 return 0 @@ -82,7 +85,7 @@ return 1 if(istype(O,/obj/item/weapon/storage/pill_bottle/)) return 1 - if(istype(O,/obj/item/weapon/reagent_containers/food/pill/)) + if(ispill(O)) return 1 return 0 @@ -108,7 +111,7 @@ return 1 if(istype(O,/obj/item/weapon/storage/pill_bottle/)) return 1 - if(istype(O,/obj/item/weapon/reagent_containers/food/pill/)) + if(ispill(O)) return 1 return 0 @@ -192,14 +195,15 @@ * Item Adding ********************/ -/obj/machinery/smartfridge/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/weapon/screwdriver) && anchored) - playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) - panel_open = !panel_open - to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.") - overlays.Cut() - if(panel_open) - overlays += image(icon, "[initial(icon_state)]-panel") +/obj/machinery/smartfridge/default_deconstruction_screwdriver(mob/user, obj/item/weapon/screwdriver/S) + . = ..(user, icon_state, icon_state, S) + + overlays.Cut() + if(panel_open) + overlays += image(icon, "[initial(icon_state)]-panel") + +/obj/machinery/smartfridge/attackby(obj/item/O, var/mob/user) + if(default_deconstruction_screwdriver(user, O)) return if(exchange_parts(user, O)) @@ -305,7 +309,7 @@ to_chat(user, "Some items are refused.") nanomanager.update_uis(src) -/obj/machinery/smartfridge/secure/emag_act(user) +/obj/machinery/smartfridge/secure/emag_act(mob/user) emagged = 1 locked = -1 to_chat(user, "You short out the product lock on [src].") @@ -330,6 +334,8 @@ data["shoot_inventory"] = shoot_inventory data["locked"] = locked data["secure"] = is_secure + data["can_dry"] = can_dry + data["drying"] = drying var/list/items[0] for(var/i=1 to length(item_quants)) @@ -370,6 +376,7 @@ for(var/obj/O in contents) if(O.name == K) O.forceMove(loc) + update_icon() i-- if(i <= 0) return 1 @@ -392,6 +399,7 @@ if(T.name == O) T.forceMove(loc) throw_item = T + update_icon() break break if(!throw_item) @@ -401,6 +409,134 @@ visible_message("[src] launches [throw_item.name] at [target.name]!") return 1 +// ---------------------------- +// Drying Rack 'smartfridge' +// ---------------------------- +/obj/machinery/smartfridge/drying_rack + name = "drying rack" + desc = "A wooden contraption, used to dry plant products, food and leather." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "drying_rack_on" + use_power = 1 + idle_power_usage = 5 + active_power_usage = 200 + icon_on = "drying_rack_on" + icon_off = "drying_rack" + can_dry = TRUE + +/obj/machinery/smartfridge/drying_rack/New() + ..() + if(component_parts && component_parts.len) + component_parts.Cut() + component_parts = null + +/obj/machinery/smartfridge/drying_rack/Destroy() + new /obj/item/stack/sheet/wood(loc, 10) + return ..() + +/obj/machinery/smartfridge/drying_rack/RefreshParts() + return + +/obj/machinery/smartfridge/drying_rack/default_deconstruction_screwdriver() + return + +/obj/machinery/smartfridge/drying_rack/exchange_parts() + return + +/obj/machinery/smartfridge/drying_rack/spawn_frame() + return + +/obj/machinery/smartfridge/drying_rack/default_deconstruction_crowbar(obj/item/weapon/crowbar/C, ignore_panel = 1) + ..() + +/obj/machinery/smartfridge/drying_rack/Topic(href, href_list) + if(..()) + return 1 + if(href_list["dryingOn"]) + drying = TRUE + use_power = 2 + update_icon() + return 1 + + if(href_list["dryingOff"]) + drying = FALSE + use_power = 1 + update_icon() + return 1 + return 0 + +/obj/machinery/smartfridge/drying_rack/power_change() + if(powered() && anchored) + stat &= ~NOPOWER + else + stat |= NOPOWER + toggle_drying(TRUE) + update_icon() + +/obj/machinery/smartfridge/drying_rack/load(obj/I, mob/user) //For updating the filled overlay + if(..()) + update_icon() + return 1 + +/obj/machinery/smartfridge/drying_rack/update_icon() + ..() + overlays.Cut() + if(drying) + overlays += "drying_rack_drying" + if(contents.len) + overlays += "drying_rack_filled" + +/obj/machinery/smartfridge/drying_rack/process() + ..() + if(drying) + if(rack_dry())//no need to update unless something got dried + update_icon() + +/obj/machinery/smartfridge/drying_rack/accept_check(obj/item/O) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/weapon/reagent_containers/food/snacks/S = O + if(S.dried_type) + return TRUE + if(istype(O, /obj/item/stack/sheet/wetleather)) + return TRUE + return FALSE + +/obj/machinery/smartfridge/drying_rack/proc/toggle_drying(forceoff) + if(drying || forceoff) + drying = FALSE + use_power = 1 + else + drying = TRUE + use_power = 2 + update_icon() + +/obj/machinery/smartfridge/drying_rack/proc/rack_dry() + for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents) + if(S.dried_type == S.type)//if the dried type is the same as the object's type, don't bother creating a whole new item... + S.color = "#ad7257" + S.dry = TRUE + item_quants[S.name]-- + S.forceMove(get_turf(src)) + else + var/dried = S.dried_type + new dried(loc) + item_quants[S.name]-- + qdel(S) + nanomanager.update_uis(src) + return TRUE + for(var/obj/item/stack/sheet/wetleather/WL in contents) + var/obj/item/stack/sheet/leather/L = new(loc) + L.amount = WL.amount + item_quants[WL.name]-- + qdel(WL) + nanomanager.update_uis(src) + return TRUE + return FALSE + +/obj/machinery/smartfridge/drying_rack/emp_act(severity) + ..() + atmos_spawn_air(SPAWN_HEAT) + /************************ * Secure SmartFridges *************************/ @@ -413,4 +549,4 @@ to_chat(usr, "Access denied.") nanomanager.update_uis(src) return 0 - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/food_and_drinks/recipes/recipes_candy.dm b/code/modules/food_and_drinks/recipes/recipes_candy.dm index 98f969a17ec..4dcecb657b8 100644 --- a/code/modules/food_and_drinks/recipes/recipes_candy.dm +++ b/code/modules/food_and_drinks/recipes/recipes_candy.dm @@ -27,14 +27,14 @@ /datum/recipe/candy/fudge_peanut reagents = list("sugar" = 5, "milk" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) - fruit = list("peanuts" = 3) + items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar, /obj/item/weapon/reagent_containers/food/snacks/grown/peanuts, + /obj/item/weapon/reagent_containers/food/snacks/grown/peanuts, /obj/item/weapon/reagent_containers/food/snacks/grown/peanuts) result = /obj/item/weapon/reagent_containers/food/snacks/candy/fudge/peanut /datum/recipe/candy/fudge_cherry reagents = list("sugar" = 5, "milk" = 5) - items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) - fruit = list("cherries" = 3) + items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar, /obj/item/weapon/reagent_containers/food/snacks/grown/cherries, + /obj/item/weapon/reagent_containers/food/snacks/grown/cherries, /obj/item/weapon/reagent_containers/food/snacks/grown/cherries) result = /obj/item/weapon/reagent_containers/food/snacks/candy/fudge/cherry /datum/recipe/candy/fudge_cookies_n_cream @@ -50,8 +50,8 @@ items = list( /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, /obj/item/weapon/reagent_containers/food/snacks/candy/caramel, + /obj/item/weapon/reagent_containers/food/snacks/grown/peanuts ) - fruit = list("peanuts" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/candy/fudge/turtle /datum/recipe/candy/fudge @@ -319,10 +319,7 @@ /datum/recipe/candy/gummybear_wtf2 reagents = list() - fruit = list("ambrosia" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/candy/gummybear, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris) result = /obj/item/weapon/reagent_containers/food/snacks/candy/gummybear/wtf // *********************************************************** @@ -386,10 +383,7 @@ result = /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/wtf /datum/recipe/candy/gummyworm_wtf2 - fruit = list("ambrosia" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris) result = /obj/item/weapon/reagent_containers/food/snacks/candy/gummyworm/wtf // *********************************************************** @@ -489,10 +483,7 @@ result = /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/wtf /datum/recipe/candy/jellybean_wtf2 - fruit = list("ambrosia" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/candy/jellybean, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris) result = /obj/item/weapon/reagent_containers/food/snacks/candy/jellybean/wtf // *********************************************************** @@ -505,7 +496,7 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/candybar, /obj/item/weapon/reagent_containers/food/snacks/candy/caramel, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel + result = /obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/caramel /datum/recipe/candy/toolerone reagents = list() @@ -513,7 +504,7 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/candybar, /obj/item/weapon/reagent_containers/food/snacks/candy/nougat, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/nougat + result = /obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/nougat /datum/recipe/candy/yumbaton reagents = list() @@ -521,14 +512,14 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/candybar, /obj/item/weapon/reagent_containers/food/snacks/candy/toffee, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/toffee + result = /obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/toffee /datum/recipe/candy/crunch reagents = list("rice" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/candy/candybar, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/rice + result = /obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/rice /datum/recipe/candy/toxinstest reagents = list() @@ -537,4 +528,4 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/caramel, /obj/item/weapon/reagent_containers/food/snacks/candy/nougat, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel_nougat + result = /obj/item/weapon/reagent_containers/food/snacks/candy/confectionery/caramel_nougat diff --git a/code/modules/food_and_drinks/recipes/recipes_microwave.dm b/code/modules/food_and_drinks/recipes/recipes_microwave.dm index 5903e191b4e..962aa5e92a4 100644 --- a/code/modules/food_and_drinks/recipes/recipes_microwave.dm +++ b/code/modules/food_and_drinks/recipes/recipes_microwave.dm @@ -10,11 +10,8 @@ result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg /datum/recipe/microwave/dionaroast - fruit = list("apple" = 1) reagents = list("facid" = 5) //It dissolves the carapace. Still poisonous, though. - items = list( - /obj/item/weapon/holder/diona, - ) + items = list(/obj/item/weapon/holder/diona, /obj/item/weapon/reagent_containers/food/snacks/grown/apple) result = /obj/item/weapon/reagent_containers/food/snacks/dionaroast /datum/recipe/microwave/jellydonut @@ -29,24 +26,24 @@ items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/slimejelly + result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly /datum/recipe/microwave/jellydonut/cherry reagents = list("cherryjelly" = 5, "sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/cherryjelly + result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/cherryjelly /datum/recipe/microwave/donut reagents = list("sugar" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) - result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal + result = /obj/item/weapon/reagent_containers/food/snacks/donut /datum/recipe/microwave/donut/sprinkles - reagents = list("sugar" = 5, "sprinkles" = 3) + reagents = list("sugar" = 5, "sprinkles" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough ) @@ -150,16 +147,16 @@ result = /obj/item/weapon/reagent_containers/food/snacks/warmdonkpocket /datum/recipe/microwave/eggplantparm - fruit = list("eggplant" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant ) result = /obj/item/weapon/reagent_containers/food/snacks/eggplantparm /datum/recipe/microwave/soylenviridians - fruit = list("soybeans" = 1) reagents = list("flour" = 10) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans) result = /obj/item/weapon/reagent_containers/food/snacks/soylenviridians /datum/recipe/microwave/soylentgreen @@ -185,25 +182,27 @@ result = /obj/item/weapon/reagent_containers/food/snacks/cheesyfries /datum/recipe/microwave/cubancarp - fruit = list("chili" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/grown/chili ) result = /obj/item/weapon/reagent_containers/food/snacks/cubancarp /datum/recipe/microwave/popcorn - fruit = list("corn" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/corn) result = /obj/item/weapon/reagent_containers/food/snacks/popcorn /datum/recipe/microwave/spacylibertyduff reagents = list("water" = 5, "vodka" = 5) - fruit = list("libertycap" = 3) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap, /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap) result = /obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff /datum/recipe/microwave/amanitajelly reagents = list("water" = 5, "vodka" = 5) - fruit = list("amanita" = 3) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita) result = /obj/item/weapon/reagent_containers/food/snacks/amanitajelly /datum/recipe/microwave/amanitajelly/make_food(obj/container) @@ -213,23 +212,18 @@ /datum/recipe/microwave/meatballsoup reagents = list("water" = 10) - fruit = list("potato" = 1, "carrot" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meatball , - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball, /obj/item/weapon/reagent_containers/food/snacks/grown/potato, /obj/item/weapon/reagent_containers/food/snacks/grown/carrot) result = /obj/item/weapon/reagent_containers/food/snacks/meatballsoup /datum/recipe/microwave/vegetablesoup reagents = list("water" = 10) - fruit = list("carrot" = 1, "corn" = 1, "eggplant" = 1, "potato" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/potato, /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, + /obj/item/weapon/reagent_containers/food/snacks/grown/corn, /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant) result = /obj/item/weapon/reagent_containers/food/snacks/vegetablesoup /datum/recipe/microwave/nettlesoup reagents = list("water" = 10) - fruit = list("nettle" = 1, "potato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/grown/nettle/basic, /obj/item/weapon/reagent_containers/food/snacks/grown/potato) result = /obj/item/weapon/reagent_containers/food/snacks/nettlesoup /datum/recipe/microwave/wishsoup @@ -237,17 +231,11 @@ result= /obj/item/weapon/reagent_containers/food/snacks/wishsoup /datum/recipe/microwave/hotchili - fruit = list("chili" = 1, "tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/grown/chili, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/hotchili /datum/recipe/microwave/coldchili - fruit = list("icechili" = 1, "tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/coldchili /datum/recipe/microwave/spellburger @@ -275,10 +263,7 @@ result = /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger /datum/recipe/microwave/enchiladas - fruit = list("chili" = 2, "corn" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/cutlet, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/cutlet, /obj/item/weapon/reagent_containers/food/snacks/grown/chili, /obj/item/weapon/reagent_containers/food/snacks/grown/corn) result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas /datum/recipe/microwave/burrito @@ -292,11 +277,8 @@ result = /obj/item/weapon/reagent_containers/food/snacks/burrito /datum/recipe/microwave/monkeysdelight - fruit = list("banana" = 1) reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/monkeycube - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube, /obj/item/weapon/reagent_containers/food/snacks/grown/banana) result = /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight /datum/recipe/microwave/fishandchips @@ -323,15 +305,14 @@ /datum/recipe/microwave/tomatosoup reagents = list("water" = 10) - fruit = list("tomato" = 2) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/tomato, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/tomatosoup /datum/recipe/microwave/stew reagents = list("water" = 10) - fruit = list("tomato" = 1, "potato" = 1, "carrot" = 1, "eggplant" = 1, "mushroom" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - ) + items= list(/obj/item/weapon/reagent_containers/food/snacks/grown/tomato, /obj/item/weapon/reagent_containers/food/snacks/grown/potato, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, /obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/stew /datum/recipe/microwave/slimetoast @@ -359,11 +340,8 @@ result = /obj/item/weapon/reagent_containers/food/snacks/milosoup /datum/recipe/microwave/stewedsoymeat - fruit = list("carrot" = 1, "tomato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/soydope, - /obj/item/weapon/reagent_containers/food/snacks/soydope, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/soydope, /obj/item/weapon/reagent_containers/food/snacks/soydope, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat /datum/recipe/microwave/boiledspagetti @@ -383,17 +361,12 @@ /datum/recipe/microwave/pastatomato reagents = list("water" = 5) - fruit = list("tomato" = 2) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato) result = /obj/item/weapon/reagent_containers/food/snacks/pastatomato /datum/recipe/microwave/poppypretzel - items = list( - /obj/item/seeds/poppyseed, - /obj/item/weapon/reagent_containers/food/snacks/dough, - ) + items = list(/obj/item/seeds/poppy, /obj/item/weapon/reagent_containers/food/snacks/dough) result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel /datum/recipe/microwave/meatballspagetti @@ -418,19 +391,19 @@ /datum/recipe/microwave/superbiteburger reagents = list("sodiumchloride" = 5, "blackpepper" = 5) - fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/boiledegg, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/superbiteburger /datum/recipe/microwave/candiedapple reagents = list("water" = 5, "sugar" = 5) - fruit = list("apple" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/apple) result = /obj/item/weapon/reagent_containers/food/snacks/candiedapple /datum/recipe/microwave/slimeburger @@ -473,19 +446,18 @@ datum/recipe/microwave/slimesandwich /datum/recipe/microwave/bloodsoup reagents = list("blood" = 10) - fruit = list("bloodtomato" = 2) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood, /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood) result = /obj/item/weapon/reagent_containers/food/snacks/bloodsoup /datum/recipe/microwave/slimesoup reagents = list("water" = 10, "slimejelly" = 5) - items = list() result = /obj/item/weapon/reagent_containers/food/snacks/slimesoup /datum/recipe/microwave/clownstears reagents = list("water" = 10) - fruit = list("banana" = 1) items = list( /obj/item/weapon/ore/bananium, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana ) result = /obj/item/weapon/reagent_containers/food/snacks/clownstears @@ -519,25 +491,26 @@ datum/recipe/microwave/slimesandwich /datum/recipe/microwave/mushroomsoup reagents = list("water" = 5, "milk" = 5) - fruit = list("mushroom" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom) result = /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup /datum/recipe/microwave/chawanmushi reagents = list("water" = 5, "soysauce" = 5) - fruit = list("mushroom" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom ) result = /obj/item/weapon/reagent_containers/food/snacks/chawanmushi /datum/recipe/microwave/beetsoup reagents = list("water" = 10) - fruit = list("whitebeet" = 1, "cabbage" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet, /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage) result = /obj/item/weapon/reagent_containers/food/snacks/beetsoup /datum/recipe/microwave/herbsalad - fruit = list("ambrosia" = 3, "apple" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, /obj/item/weapon/reagent_containers/food/snacks/grown/apple) result = /obj/item/weapon/reagent_containers/food/snacks/herbsalad /datum/recipe/microwave/herbsalad/make_food(obj/container) @@ -546,14 +519,14 @@ datum/recipe/microwave/slimesandwich return being_cooked /datum/recipe/microwave/aesirsalad - fruit = list("ambrosiadeus" = 3, "goldapple" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus, /obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold) result = /obj/item/weapon/reagent_containers/food/snacks/aesirsalad /datum/recipe/microwave/validsalad - fruit = list("ambrosia" = 3, "potato" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meatball, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, /obj/item/weapon/reagent_containers/food/snacks/grown/potato, + /obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/validsalad /datum/recipe/microwave/validsalad/make_food(obj/container) @@ -565,15 +538,12 @@ datum/recipe/microwave/slimesandwich /datum/recipe/microwave/wrap reagents = list("soysauce" = 10) - fruit = list("cabbage" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/friedegg, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/friedegg, /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage ) result = /obj/item/weapon/reagent_containers/food/snacks/wrap /datum/recipe/microwave/beans reagents = list("ketchup" = 5) - fruit = list("soybeans" = 2) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans, /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans) result = /obj/item/weapon/reagent_containers/food/snacks/beans /datum/recipe/microwave/benedict @@ -586,10 +556,10 @@ datum/recipe/microwave/slimesandwich /datum/recipe/microwave/meatbun reagents = list("soysauce" = 5) - fruit = list("cabbage" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meatball, + /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage ) result = /obj/item/weapon/reagent_containers/food/snacks/meatbun @@ -610,9 +580,9 @@ datum/recipe/microwave/slimesandwich /datum/recipe/microwave/friedbanana reagents = list("sugar" = 10, "cornoil" = 5) - fruit = list("banana" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana ) result = /obj/item/weapon/reagent_containers/food/snacks/friedbanana @@ -655,8 +625,8 @@ datum/recipe/microwave/slimesandwich result = /obj/item/weapon/reagent_containers/food/snacks/sashimi /datum/recipe/microwave/mashedtaters - fruit = list("potato" = 1) reagents = list("gravy" = 5) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/potato) result = /obj/item/weapon/reagent_containers/food/snacks/mashed_potatoes ////////////////////////////////////////// @@ -671,12 +641,6 @@ datum/recipe/microwave/slimesandwich ) result = /obj/item/weapon/reagent_containers/food/snacks/taco -/datum/recipe/microwave/meatball - items = list( - /obj/item/weapon/reagent_containers/food/snacks/rawmeatball - ) - result = /obj/item/weapon/reagent_containers/food/snacks/meatball - /datum/recipe/microwave/fries items = list( /obj/item/weapon/reagent_containers/food/snacks/rawsticks diff --git a/code/modules/food_and_drinks/recipes/recipes_oven.dm b/code/modules/food_and_drinks/recipes/recipes_oven.dm index d20c06e260f..473641c4cc8 100644 --- a/code/modules/food_and_drinks/recipes/recipes_oven.dm +++ b/code/modules/food_and_drinks/recipes/recipes_oven.dm @@ -51,11 +51,11 @@ /datum/recipe/oven/bananabread reagents = list("milk" = 5, "sugar" = 15) - fruit = list("banana" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread @@ -68,11 +68,13 @@ /datum/recipe/oven/carrotcake reagents = list("milk" = 5, "sugar" = 15) - fruit = list("carrot" = 3) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake @@ -119,24 +121,24 @@ /datum/recipe/oven/pie reagents = list("sugar" = 5) - fruit = list("banana" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana ) result = /obj/item/weapon/reagent_containers/food/snacks/pie /datum/recipe/oven/cherrypie reagents = list("sugar" = 10) - fruit = list("cherries" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/cherries ) result = /obj/item/weapon/reagent_containers/food/snacks/cherrypie /datum/recipe/oven/berryclafoutis - fruit = list("berries" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/berries ) result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis @@ -155,9 +157,9 @@ result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread /datum/recipe/oven/loadedbakedpotato - fruit = list("potato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/potato ) result = /obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato @@ -194,71 +196,80 @@ return . /datum/recipe/oven/pizzamargherita - fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita /datum/recipe/oven/meatpizza - fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza /datum/recipe/oven/syntipizza - fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza /datum/recipe/oven/mushroompizza - fruit = list("mushroom" = 5, "tomato" = 1) + items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza /datum/recipe/oven/vegetablepizza - fruit = list("eggplant" = 1, "carrot" = 1, "corn" = 1, "tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant, + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, + /obj/item/weapon/reagent_containers/food/snacks/grown/corn, + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza /datum/recipe/oven/amanita_pie - fruit = list("amanita" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita ) result = /obj/item/weapon/reagent_containers/food/snacks/amanita_pie /datum/recipe/oven/plump_pie - fruit = list("plumphelmet" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet ) result = /obj/item/weapon/reagent_containers/food/snacks/plump_pie /datum/recipe/oven/plumphelmetbiscuit - fruit = list("plumphelmet" = 1) reagents = list("water" = 5, "flour" = 5) + items = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet) result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit /datum/recipe/oven/creamcheesebread @@ -301,49 +312,53 @@ return being_cooked /datum/recipe/oven/applepie - fruit = list("apple" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple ) result = /obj/item/weapon/reagent_containers/food/snacks/applepie /datum/recipe/oven/applecake reagents = list("milk" = 5, "sugar" = 5) - fruit = list("apple" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake /datum/recipe/oven/orangecake reagents = list("milk" = 5) - fruit = list("orange" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake /datum/recipe/oven/limecake reagents = list("milk" = 5) - fruit = list("lime" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake /datum/recipe/oven/lemoncake reagents = list("milk" = 5) - fruit = list("lemon" = 2) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon, + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake @@ -370,17 +385,17 @@ /datum/recipe/oven/pumpkinpie reagents = list("milk" = 5, "sugar" = 5) - fruit = list("pumpkin" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, + /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie /datum/recipe/oven/appletart - fruit = list("goldapple" = 1) reagents = list("sugar" = 5, "milk" = 5, "flour" = 10) items = list( - /obj/item/weapon/reagent_containers/food/snacks/egg + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold ) result = /obj/item/weapon/reagent_containers/food/snacks/appletart diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm index b6c943dbdab..f7eb2fa4a68 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_table.dm @@ -6,7 +6,6 @@ tools[] = list() //type paths of items needed but not consumed time = 30 //time in deciseconds parts[] = list() //type paths of items that will be placed in the result - fruit[] = list() //grown products required by the recipe */ /datum/crafting_recipe/sandwich @@ -55,45 +54,6 @@ result = /obj/item/weapon/reagent_containers/food/snacks/jellyburger/cherry category = CAT_FOOD -/* Temporarily disabled until we can find a workaround for this fruit shit. -/datum/crafting_recipe/herbsalad - name = "herb salad" - fruit = list("ambrosia" = 3, "apple" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/herbsalad - -/datum/crafting_recipe/herbsalad/AdjustChems(var/obj/resultobj as obj) - if(istype(resultobj, /obj/item/weapon/reagent_containers)) - var/obj/item/weapon/reagent_containers/RC = resultobj - RC.reagents.del_reagent("toxin") - -/datum/crafting_recipe/aesirsalad - name = "Aesir salad" - fruit = list("ambrosiadeus" = 3, "goldapple" = 1) - result = /obj/item/weapon/reagent_containers/food/snacks/aesirsalad - -/datum/crafting_recipe/validsalad - name = "valid salad" - fruit = list("ambrosia" = 3, "potato" = 1) - reqs = list( - /obj/item/weapon/reagent_containers/food/snacks/meatball = 1, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/validsalad - -/datum/crafting_recipe/validsalad/AdjustChems(var/obj/resultobj as obj) - if(istype(resultobj, /obj/item/weapon/reagent_containers)) - var/obj/item/weapon/reagent_containers/RC = resultobj - RC.reagents.del_reagent("toxin") - -/datum/crafting_recipe/wrap - name = "egg wrap" - fruit = list("cabbage" = 1) - reqs = list( - /datum/reagent/soysauce = 10, - /obj/item/weapon/reagent_containers/food/snacks/friedegg = 1, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/wrap -*/ - /datum/crafting_recipe/notasandwich name = "not-a-sandwich" reqs = list( diff --git a/code/modules/garbage_collection/__gc_info.dm b/code/modules/garbage_collection/__gc_info.dm index be72097a8c9..e36b5fd2b1b 100644 --- a/code/modules/garbage_collection/__gc_info.dm +++ b/code/modules/garbage_collection/__gc_info.dm @@ -1,7 +1,7 @@ /* =============================================================================== - How Garbage Collection Works + How Garbage Collection Works =============================================================================== In BYOND, there are exactly two ways anything gets deleted: @@ -31,8 +31,8 @@ that can't be. There are two main procs involved in this process: /proc/qdel(datumToDelete) This is, effectively, a replacement for del that tells an object to prepare itself to be soft deleted by calling its Destroy() proc. Depending on the qdel hint returned by Destroy(), qdel will queue the object in the garbage collector - (to be hard deleted if it isn't soft deleted), directly delete the object, pool the object, or ignore the object and - assume it will handle deleting itself. An object passed into qdel will have its gcDestroyed var set, so + (to be hard deleted if it isn't soft deleted), directly delete the object, or ignore the object and + assume it will handle deleting itself. An object passed into qdel will have its gcDestroyed var set, so isnull(gcDestroyed) will be true if an object is not being destroyed, and false if it is (which means you should get rid of the reference you have to it). @@ -50,7 +50,7 @@ that can't be. There are two main procs involved in this process: should use a Del proc for any necessary cleanup, as a Destroy proc on them will not automatically get called. When called by qdel, Destroy is expected to return a qdel hint, which determines whether the object should be directly - deleted, queued for deletion, pooled, or ignored entirely; which of these are appropriate will vary, though objects + deleted, queued for deletion, or ignored entirely; which of these are appropriate will vary, though objects should be pooled or queued whenever possible. The full list of qdel hints are in the code for the qdel proc. As mentioned above, gcDestroyed can be used to tell whether an object is being destroyed. This is important, because if @@ -62,7 +62,4 @@ reference immediately. The inner workings of the GC itself and the stuff related to testing it probably don't need a detailed description - if you intend to work with them, it would be best to read the code to understand what they do. -Pooling is related to GC, in that it's meant to reduce deletion overhead, but it does so by re-using objects instead of -deleting them at all. Explaining pooling is outside the scope of this file. - */ \ No newline at end of file diff --git a/code/modules/garbage_collection/garbage_collector.dm b/code/modules/garbage_collection/garbage_collector.dm index 3d6007d313e..e2204788016 100644 --- a/code/modules/garbage_collection/garbage_collector.dm +++ b/code/modules/garbage_collection/garbage_collector.dm @@ -149,8 +149,6 @@ var/global/datum/controller/process/garbage_collector/garbageCollector del(D) if(garbageCollector) garbageCollector.dels_count++ - if(QDEL_HINT_PUTINPOOL) //qdel will put this object in the pool. - PlaceInPool(D,0) if(QDEL_HINT_FINDREFERENCE)//qdel will, if TESTING is enabled, display all references to this object, then queue the object for deletion. #ifdef TESTING D.find_references(remove_from_queue = FALSE) diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 817f002f014..18f87a8a45a 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -33,7 +33,7 @@ /obj/structure/beebox name = "apiary" desc = "Dr Miles Manners is just your average Wasp themed super hero by day, but by night he becomes DR BEES!" - icon = 'icons/obj/apiary_bees.dmi' + icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "beebox" anchored = 1 density = 1 @@ -251,4 +251,4 @@ if(!user.put_in_active_hand(QB)) QB.forceMove(get_turf(src)) visible_message("[user] removes the queen from the apiary.") - queen_bee = null \ No newline at end of file + queen_bee = null diff --git a/code/modules/hydroponics/beekeeping/beekeeper_suit.dm b/code/modules/hydroponics/beekeeping/beekeeper_suit.dm index 93b5b0c53a8..640d022c9e3 100644 --- a/code/modules/hydroponics/beekeeping/beekeeper_suit.dm +++ b/code/modules/hydroponics/beekeeping/beekeeper_suit.dm @@ -13,4 +13,5 @@ icon_state = "beekeeper" item_state = "beekeeper" flags = THICKMATERIAL - allowed = list (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle/fertilizer,/obj/item/weapon/minihoe) + allowed = list (/obj/item/weapon/reagent_containers/spray,/obj/item/device/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/cultivator) + diff --git a/code/modules/hydroponics/beekeeping/honey_frame.dm b/code/modules/hydroponics/beekeeping/honey_frame.dm index a58ab7041c7..74eec401d6d 100644 --- a/code/modules/hydroponics/beekeeping/honey_frame.dm +++ b/code/modules/hydroponics/beekeeping/honey_frame.dm @@ -1,8 +1,8 @@ /obj/item/honey_frame name = "honey frame" - desc = "a scaffold for bees to build honeycomb on" - icon = 'icons/obj/apiary_bees.dmi' + desc = "A scaffold for bees to build honeycomb on." + icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "honey_frame" var/honeycomb_capacity = 10 //10 Honeycomb per frame by default, researchable frames perhaps? diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 23588cc5c48..713e46804e7 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -1,8 +1,8 @@ /obj/item/weapon/reagent_containers/honeycomb name = "honeycomb" - desc = "a hexagonal mesh of honeycomb" - icon = 'icons/obj/apiary_bees.dmi' + desc = "A hexagonal mesh of honeycomb." + icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "honeycomb" possible_transfer_amounts = list() disease_amount = 0 @@ -22,10 +22,10 @@ overlays.Cut() var/image/honey if(honey_color) - honey = image(icon = 'icons/obj/apiary_bees.dmi', icon_state = "greyscale_honey") + honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "greyscale_honey") honey.color = honey_color else - honey = image(icon = 'icons/obj/apiary_bees.dmi', icon_state = "honey") + honey = image(icon = 'icons/obj/hydroponics/harvest.dmi', icon_state = "honey") overlays += honey @@ -37,4 +37,4 @@ reagents.add_reagent(R.id,5) else honey_color = "" - update_icon() + update_icon() \ No newline at end of file diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm new file mode 100644 index 00000000000..b5e0c826683 --- /dev/null +++ b/code/modules/hydroponics/biogenerator.dm @@ -0,0 +1,325 @@ +/obj/machinery/biogenerator + name = "Biogenerator" + desc = "Converts plants into biomass, which can be used to construct useful items." + icon = 'icons/obj/biogenerator.dmi' + icon_state = "biogen-empty" + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 40 + var/processing = 0 + var/obj/item/weapon/reagent_containers/glass/beaker = null + var/points = 0 + var/menustat = "menu" + var/efficiency = 0 + var/productivity = 0 + var/max_items = 40 + var/datum/research/files + var/list/show_categories = list("Food", "Botany Chemicals", "Leather and Cloth") + var/list/timesFiveCategories = list("Food", "Botany Chemicals") + +/obj/machinery/biogenerator/New() + ..() + files = new /datum/research/biogenerator(src) + create_reagents(1000) + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/biogenerator(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/stack/cable_coil(null, 1) + RefreshParts() + +/obj/machinery/biogenerator/Destroy() + if(beaker) + qdel(beaker) + beaker = null + return ..() + +/obj/machinery/biogenerator/ex_act(severity) + if(beaker) + beaker.ex_act(severity) + ..() + +/obj/machinery/biogenerator/RefreshParts() + var/E = 0 + var/P = 0 + var/max_storage = 40 + for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) + P += B.rating + max_storage = 40 * B.rating + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + E += M.rating + efficiency = E + productivity = P + max_items = max_storage + +/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. + update_icon() + +/obj/machinery/biogenerator/update_icon() + if(panel_open) + icon_state = "biogen-empty-o" + else if(!beaker) + icon_state = "biogen-empty" + else if(!processing) + icon_state = "biogen-stand" + else + icon_state = "biogen-work" + return + +/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params) + if(user.a_intent == I_HARM) + return ..() + + if(processing) + to_chat(user, "The biogenerator is currently processing.") + return + + if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.forceMove(loc) + beaker = null + update_icon() + return + + if(exchange_parts(user, O)) + return + + if(default_deconstruction_crowbar(O)) + return + + if(istype(O, /obj/item/weapon/reagent_containers/glass)) + . = 1 //no afterattack + if(!panel_open) + if(beaker) + to_chat(user, "A container is already loaded into the machine.") + else + if(!user.drop_item()) + return + O.forceMove(src) + beaker = O + to_chat(user, "You add the container to the machine.") + update_icon() + updateUsrDialog() + else + to_chat(user, "Close the maintenance panel first.") + return + + else if(istype(O, /obj/item/weapon/storage/bag/plants)) + var/obj/item/weapon/storage/bag/plants/PB = O + var/i = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) + i++ + if(i >= max_items) + to_chat(user, "The biogenerator is already full! Activate it.") + else + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents) + if(i >= max_items) + break + PB.remove_from_storage(G, src) + i++ + if(iYou empty the plant bag into the biogenerator.
") + else if(PB.contents.len == 0) + to_chat(user, "You empty the plant bag into the biogenerator, filling it to its capacity.") + else + to_chat(user, "You fill the biogenerator to its capacity.") + return 1 //no afterattack + + else if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) + var/i = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) + i++ + if(i >= max_items) + to_chat(user, "The biogenerator is full! Activate it.") + else + user.unEquip(O) + O.forceMove(src) + to_chat(user, "You put [O.name] in [name]") + return 1 //no afterattack + else if (istype(O, /obj/item/weapon/disk/design_disk)) + user.visible_message("[user] begins to load [O] in [src]...", + "You begin to load a design from [O]...", + "You hear the chatter of a floppy drive.") + processing = 1 + var/obj/item/weapon/disk/design_disk/D = O + if(do_after(user, 10, target = src)) + files.AddDesign2Known(D.blueprint) + processing = 0 + return 1 + else + to_chat(user, "You cannot put this in [name]!") + +/obj/machinery/biogenerator/interact(mob/user) + if(stat & BROKEN || panel_open) + return + user.set_machine(src) + var/dat + if(processing) + dat += "
Biogenerator is processing! Please wait...

" + else + switch(menustat) + if("nopoints") + dat += "
You do not have enough biomass to create products.
Please, put growns into reactor and activate it.
" + menustat = "menu" + if("complete") + dat += "
Operation complete.
" + menustat = "menu" + if("void") + dat += "
Error: No growns inside.
Please, put growns into reactor.
" + menustat = "menu" + if("nobeakerspace") + dat += "
Not enough space left in container. Unable to create product.
" + menustat = "menu" + if(beaker) + var/categories = show_categories.Copy() + for(var/V in categories) + categories[V] = list() + for(var/V in files.known_designs) + var/datum/design/D = files.known_designs[V] + for(var/C in categories) + if(C in D.category) + categories[C] += D + + dat += "
Biomass: [points] units.

" + dat += "ActivateDetach Container" + for(var/cat in categories) + dat += "

[cat]:

" + dat += "
" + for(var/V in categories[cat]) + var/datum/design/D = V + dat += "[D.name]: Make" + if(cat in timesFiveCategories) + dat += "x5" + if(ispath(D.build_path, /obj/item/stack)) + dat += "x10" + dat += "([D.materials[MAT_BIOMASS]/efficiency])
" + dat += "
" + else + dat += "
No container inside, please insert container.
" + + var/datum/browser/popup = new(user, "biogen", name, 350, 520) + popup.set_content(dat) + popup.open() + return + +/obj/machinery/biogenerator/attack_hand(mob/user) + interact(user) + +/obj/machinery/biogenerator/proc/activate() + if(usr.stat != 0) + return + if(stat != 0) //NOPOWER etc + return + if(processing) + to_chat(usr, "The biogenerator is in the process of working.") + return + var/S = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents) + S += 5 + if(I.reagents.get_reagent_amount("nutriment")+I.reagents.get_reagent_amount("plantmatter") < 0.1) + points += 1*productivity + else + points += (I.reagents.get_reagent_amount("nutriment")+I.reagents.get_reagent_amount("plantmatter"))*10*productivity + qdel(I) + if(S) + processing = 1 + update_icon() + updateUsrDialog() + playsound(loc, 'sound/machines/blender.ogg', 50, 1) + use_power(S*30) + sleep(S+15/productivity) + processing = 0 + update_icon() + else + menustat = "void" + return + +/obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = 1) + if(materials.len != 1 || materials[1] != MAT_BIOMASS) + return 0 + if (materials[MAT_BIOMASS]*multiplier/efficiency > points) + menustat = "nopoints" + return 0 + else + if(remove_points) + points -= materials[MAT_BIOMASS]*multiplier/efficiency + update_icon() + updateUsrDialog() + return 1 + +/obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1) + var/sum_reagents = 0 + for(var/R in reagents) + sum_reagents += reagents[R] + sum_reagents *= multiplier + + if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume) + menustat = "nobeakerspace" + return 0 + + return 1 + +/obj/machinery/biogenerator/proc/create_product(datum/design/D, amount) + if(!beaker || !loc) + return 0 + + if(ispath(D.build_path, /obj/item/stack)) + if(!check_container_volume(D.make_reagents, amount)) + return 0 + if(!check_cost(D.materials, amount)) + return 0 + + var/obj/item/stack/product = new D.build_path(loc) + product.amount = amount + for(var/R in D.make_reagents) + beaker.reagents.add_reagent(R, D.make_reagents[R]*amount) + else + var/i = amount + while(i > 0) + if(!check_container_volume(D.make_reagents)) + return . + if(!check_cost(D.materials)) + return . + if(D.build_path) + new D.build_path(loc) + for(var/R in D.make_reagents) + beaker.reagents.add_reagent(R, D.make_reagents[R]) + . = 1 + --i + + menustat = "complete" + update_icon() + return . + +/obj/machinery/biogenerator/proc/detach() + if(beaker) + beaker.forceMove(loc) + beaker = null + update_icon() + +/obj/machinery/biogenerator/Topic(href, href_list) + if(..() || panel_open) + return + + usr.set_machine(src) + + if(href_list["activate"]) + activate() + updateUsrDialog() + + else if(href_list["detach"]) + detach() + updateUsrDialog() + + else if(href_list["create"]) + var/amount = (text2num(href_list["amount"])) + var/datum/design/D = locate(href_list["create"]) + create_product(D, amount) + updateUsrDialog() + + else if(href_list["menu"]) + menustat = "menu" + updateUsrDialog() diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm new file mode 100644 index 00000000000..dcfd2601813 --- /dev/null +++ b/code/modules/hydroponics/gene_modder.dm @@ -0,0 +1,410 @@ +/obj/machinery/plantgenes + name = "plant DNA manipulator" + desc = "An advanced device designed to manipulate plant genetic makeup." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "dnamod" + density = 1 + anchored = 1 + + var/obj/item/seeds/seed + var/obj/item/weapon/disk/plantgene/disk + + var/list/core_genes = list() + var/list/reagent_genes = list() + var/list/trait_genes = list() + + var/datum/plant_gene/target + var/operation = "" + var/rating = 0 + var/max_extract_pot = 50 + // The cap on potency gene extraction. + // This number is for T1, each upgraded part adds 5% for a tech level above T1. + // At T4, it reaches 95%. + +/obj/machinery/plantgenes/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/plantgenes(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + RefreshParts() + +/obj/machinery/plantgenes/RefreshParts() + rating = 0 + for(var/I in component_parts) + if(istype(I, /obj/item/weapon/stock_parts)) + var/obj/item/weapon/stock_parts/S = I + rating += S.rating-1 + max_extract_pot = initial(max_extract_pot) + rating*5 + +/obj/machinery/plantgenes/update_icon() + ..() + overlays.Cut() + if((stat & (BROKEN|NOPOWER))) + icon_state = "dnamod-off" + else + icon_state = "dnamod" + if(seed) + overlays += "dnamod-dna" + if(panel_open) + overlays += "dnamod-open" + +/obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I)) + update_icon() + return + if(exchange_parts(user, I)) + return + if(default_deconstruction_crowbar(I)) + return + if(isrobot(user)) + return + + if(istype(I, /obj/item/seeds)) + if(seed) + to_chat(user, "A sample is already loaded into the machine!") + else + if(!user.drop_item()) + return + insert_seed(I) + to_chat(user, "You add [I] to the machine.") + interact(user) + return + else if(istype(I, /obj/item/weapon/disk/plantgene)) + if(disk) + to_chat(user, "A data disk is already loaded into the machine!") + else + if(!user.drop_item()) + return + disk = I + disk.forceMove(src) + to_chat(user, "You add [I] to the machine.") + interact(user) + else + ..() + + +/obj/machinery/plantgenes/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/plantgenes/interact(mob/user) + user.set_machine(src) + if(!user) + return + + var/datum/browser/popup = new(user, "plantdna", "Plant DNA Manipulator", 450, 600) + if(!(in_range(src, user) || issilicon(user))) + popup.close() + return + + var/dat = "" + + if(operation) + if(!seed || (!target && operation != "insert")) + operation = "" + target = null + interact(user) + return + if((operation == "replace" || operation == "insert") && (!disk || !disk.gene)) + operation = "" + target = null + interact(user) + return + + dat += "

Confirm Operation

" + dat += "
Are you sure you want to [operation] " + switch(operation) + if("remove") + dat += "[target.get_name()] gene from \the [seed]?
" + if("extract") + dat += "[target.get_name()] gene from \the [seed]?
" + dat += "The sample will be destroyed in process!" + if(istype(target, /datum/plant_gene/core/potency)) + var/datum/plant_gene/core/gene = target + if(gene.value > max_extract_pot) + dat += "

This device's extraction capabilities are currently limited to [max_extract_pot] potency. " + dat += "Target gene will be degraded to [max_extract_pot] potency on extraction." + if("replace") + dat += "[target.get_name()] gene with [disk.gene.get_name()]?
" + if("insert") + dat += "[disk.gene.get_name()] gene into \the [seed]?
" + dat += "
Confirm " + dat += "Abort
" + popup.set_content(dat) + popup.open() + return + + dat+= "" + + if(seed) + var/can_insert = disk && disk.gene && disk.gene.can_add(seed) + var/can_extract = disk && !disk.read_only + + dat += "

Core Genes

" + for(var/a in core_genes) + var/datum/plant_gene/G = a + if(!G) + continue + dat += "" + dat += "
[G.get_name()]" + if(can_extract) + dat += "Extract" + if(can_insert && istype(disk.gene, G.type)) + dat += "Replace" + dat += "
" + + if(seed.yield != -1) + dat += "

Content Genes

" + if(reagent_genes.len) + dat += "" + for(var/a in reagent_genes) + var/datum/plant_gene/G = a + dat += "" + dat += "
[G.get_name()]" + if(can_extract) + dat += "Extract" + dat += "Remove" + dat += "
" + else + dat += "No content-related genes detected in sample.
" + dat += "
" + if(can_insert && istype(disk.gene, /datum/plant_gene/reagent)) + dat += "Insert: [disk.gene.get_name()]" + + dat += "

Trait Genes

" + if(trait_genes.len) + dat += "" + for(var/a in trait_genes) + var/datum/plant_gene/G = a + dat += "" + dat += "
[G.get_name()]" + if(can_extract) + dat += "Extract" + dat += "Remove" + dat += "
" + else + dat += "No trait-related genes detected in sample.
" + if(can_insert && istype(disk.gene, /datum/plant_gene/trait)) + dat += "Insert: [disk.gene.get_name()]" + dat += "
" + else + dat += "
No sample found.
Please, insert a plant sample to use this device." + popup.set_content(dat) + popup.open() + + +/obj/machinery/plantgenes/Topic(var/href, var/list/href_list) + if(..()) + return + usr.set_machine(src) + + if(href_list["eject_seed"] && !operation) + if(seed) + seed.forceMove(loc) + seed.verb_pickup() + seed = null + update_genes() + update_icon() + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/seeds)) + if(!usr.drop_item()) + return + insert_seed(I) + to_chat(usr, "You add [I] to the machine.") + update_icon() + else if(href_list["eject_disk"] && !operation) + if(disk) + disk.forceMove(loc) + disk.verb_pickup() + disk = null + update_genes() + else + var/obj/item/I = usr.get_active_hand() + if(istype(I, /obj/item/weapon/disk/plantgene)) + if(!usr.drop_item()) + return + disk = I + disk.forceMove(src) + to_chat(usr, "You add [I] to the machine.") + else if(href_list["op"] == "insert" && disk && disk.gene && seed) + if(!operation) // Wait for confirmation + operation = "insert" + else + if(!istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed)) + seed.genes += disk.gene.Copy() + if(istype(disk.gene, /datum/plant_gene/reagent)) + seed.reagents_from_genes() + update_genes() + repaint_seed() + operation = "" + target = null + + else if(href_list["gene"] && seed) + var/datum/plant_gene/G = seed.get_gene(href_list["gene"]) + if(!G || !href_list["op"] || !(href_list["op"] in list("remove", "extract", "replace"))) + interact(usr) + return + + if(!operation || target != G) // Wait for confirmation + target = G + operation = href_list["op"] + + else if(operation == href_list["op"] && target == G) + switch(href_list["op"]) + if("remove") + if(!istype(G, /datum/plant_gene/core)) + seed.genes -= G + if(istype(G, /datum/plant_gene/reagent)) + seed.reagents_from_genes() + repaint_seed() + if("extract") + if(disk && !disk.read_only) + disk.gene = G + if(istype(G, /datum/plant_gene/core/potency)) + var/datum/plant_gene/core/gene = G + gene.value = min(gene.value, max_extract_pot) + disk.update_name() + qdel(seed) + seed = null + update_icon() + if("replace") + if(disk && disk.gene && istype(disk.gene, G.type) && istype(G, /datum/plant_gene/core)) + seed.genes -= G + var/datum/plant_gene/core/C = disk.gene.Copy() + seed.genes += C + C.apply_stat(seed) + repaint_seed() + if("insert") + if(disk && disk.gene && !istype(disk.gene, /datum/plant_gene/core) && disk.gene.can_add(seed)) + seed.genes += disk.gene.Copy() + if(istype(disk.gene, /datum/plant_gene/reagent)) + seed.reagents_from_genes() + repaint_seed() + + update_genes() + operation = "" + target = null + else if(href_list["abort"]) + operation = "" + target = null + + interact(usr) + +/obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S) + if(!istype(S) || seed) + return + S.forceMove(src) + seed = S + update_genes() + update_icon() + +/obj/machinery/plantgenes/proc/update_genes() + core_genes = list() + reagent_genes = list() + trait_genes = list() + + if(seed) + var/gene_paths = list( + /datum/plant_gene/core/potency, + /datum/plant_gene/core/yield, + /datum/plant_gene/core/production, + /datum/plant_gene/core/endurance, + /datum/plant_gene/core/lifespan, + /datum/plant_gene/core/weed_rate, + /datum/plant_gene/core/weed_chance + ) + for(var/a in gene_paths) + core_genes += seed.get_gene(a) + + for(var/datum/plant_gene/reagent/G in seed.genes) + reagent_genes += G + for(var/datum/plant_gene/trait/G in seed.genes) + trait_genes += G + +/obj/machinery/plantgenes/proc/repaint_seed() + if(!seed) + return + if(copytext(seed.name, 1, 13) == "experimental") + return // Already modded name and icon + seed.name = "experimental " + seed.name + seed.icon_state = "seed-x" + +/* + * Plant DNA disk + */ + +/obj/item/weapon/disk/plantgene + name = "plant data disk" + desc = "A disk for storing plant genetic data." + icon_state = "datadisk_hydro" + materials = list(MAT_METAL=30, MAT_GLASS=10) + var/datum/plant_gene/gene + var/read_only = 0 //Well, it's still a floppy disk + +/obj/item/weapon/disk/plantgene/New() + ..() + overlays += "datadisk_gene" + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + +/obj/item/weapon/disk/plantgene/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 = "plant data disk - '[t]'" + else + name = "plant data disk" + +/obj/item/weapon/disk/plantgene/proc/update_name() + if(gene) + name = "plant data disk - '[gene.get_name()]'" + else + name = "plant data disk" + +/obj/item/weapon/disk/plantgene/attack_self(mob/user) + read_only = !read_only + to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") + +/obj/item/weapon/disk/plantgene/examine(mob/user) + ..() + to_chat(user, "The write-protect tab is set to [read_only ? "protected" : "unprotected"].") + + +/* + * Plant DNA Disks Box + */ +/obj/item/weapon/storage/box/disks_plantgene + name = "plant data disks box" + icon_state = "disk_kit" + +/obj/item/weapon/storage/box/disks_plantgene/New() + ..() + for(var/i in 1 to 7) + new /obj/item/weapon/disk/plantgene(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 81d489d9da1..2322bbad5ca 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -1,535 +1,148 @@ -//Grown foods. +// *********************************************************** +// Foods that are produced from hydroponics ~~~~~~~~~~ +// Data from the seeds carry over to these grown foods +// *********************************************************** + +// Base type. Subtypes are found in /grown dir. /obj/item/weapon/reagent_containers/food/snacks/grown - - name = "fruit" - icon = 'icons/obj/hydroponics_products.dmi' - icon_state = "blank" - desc = "Nutritious! Probably." - - var/plantname - var/datum/seed/seed - var/potency = -1 - var/awakening = 0 + icon = 'icons/obj/hydroponics/harvest.dmi' + var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item. + var/plantname = "" + var/bitesize_mod = 0 + var/splat_type = /obj/effect/decal/cleanable/plant_smudge + // If set, bitesize = 1 + round(reagents.total_volume / bitesize_mod) + dried_type = -1 + // Saves us from having to define each stupid grown's dried_type as itself. + // If you don't want a plant to be driable (watermelons) set this to null in the time definition. burn_state = FLAMMABLE + origin_tech = "biotech=1" -/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc,planttype) - +/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc, var/obj/item/seeds/new_seed = null) ..() - if(!dried_type) + if(new_seed) + seed = new_seed.Copy() + else if(ispath(seed)) + // This is for adminspawn or map-placed growns. They get the default stats of their seed type. + seed = new seed() + seed.adjust_potency(50-seed.potency) + + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + + if(dried_type == -1) dried_type = type - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - - // Fill the object up with the appropriate reagents. - if(planttype) - plantname = planttype - - if(!plantname) - return - - if(!plant_controller) - sleep(250) // ugly hack, should mean roundstart plants are fine. - if(!plant_controller) - to_chat(world, "Plant controller does not exist and [src] requires it. Aborting.") - qdel(src) - return - - seed = plant_controller.seeds[plantname] - - if(!seed) - return - - name = "[seed.seed_name]" - - if(seed.modular_icon == 1) - update_icon() - else - icon = 'icons/obj/harvest.dmi' - icon_state = seed.preset_icon - - if(!seed.chems) - return - - potency = seed.get_trait(TRAIT_POTENCY) - - for(var/rid in seed.chems) - var/list/reagent_data = seed.chems[rid] - if(reagent_data && reagent_data.len) - var/rtotal = reagent_data[1] - if(reagent_data.len > 1 && potency > 0) - rtotal += round(potency/reagent_data[2]) - reagents.add_reagent(rid,max(1,rtotal)) - update_desc() - update_trash() - if(reagents.total_volume > 0) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/proc/update_trash() - if(!seed) - return - trash = seed.trash_type - if(seed.kitchen_tag) - if(seed.kitchen_tag == "watermelon") // 15% chance to leave behind a pack of watermelon seeds - if(prob(15)) - var/obj/item/seeds/seeds = new() - seeds.seed = seed - seeds.update_seed() - trash = seeds - else - trash = null - -/obj/item/weapon/reagent_containers/food/snacks/grown/proc/update_desc() - - if(!seed) - return - if(!plant_controller) - sleep(250) // ugly hack, should mean roundstart plants are fine. - if(!plant_controller) - to_chat(world, "Plant controller does not exist and [src] requires it. Aborting.") - qdel(src) - return - - if(plant_controller.product_descs["[seed.uid]"]) - desc = plant_controller.product_descs["[seed.uid]"] - else - var/list/descriptors = list() - if(reagents.has_reagent("sugar") || reagents.has_reagent("cherryjelly") || reagents.has_reagent("honey") || reagents.has_reagent("berryjuice")) - descriptors |= "sweet" - if(reagents.has_reagent("charcoal")) - descriptors |= "astringent" - if(reagents.has_reagent("frostoil")) - descriptors |= "numbing" - if(reagents.has_reagent("nutriment")) - descriptors |= "nutritious" - if(reagents.has_reagent("condensedcapsaicin") || reagents.has_reagent("capsaicin")) - descriptors |= "spicy" - if(reagents.has_reagent("cocoa")) - descriptors |= "bitter" - if(reagents.has_reagent("orangejuice") || reagents.has_reagent("lemonjuice") || reagents.has_reagent("limejuice")) - descriptors |= "sweet-sour" - if(reagents.has_reagent("radium") || reagents.has_reagent("uranium")) - descriptors |= "radioactive" - if(reagents.has_reagent("amanitin") || reagents.has_reagent("toxin") || reagents.has_reagent("carpotoxin")) - descriptors |= "poisonous" - if(reagents.has_reagent("lsd") || reagents.has_reagent("space_drugs") || reagents.has_reagent("psilocybin")) - descriptors |= "hallucinogenic" - if(reagents.has_reagent("styptic_powder")) - descriptors |= "medicinal" - if(reagents.has_reagent("gold") || reagents.has_reagent("silver")) - descriptors |= "shiny" - if(reagents.has_reagent("lube")) - descriptors |= "slippery" - if(reagents.has_reagent("facid") || reagents.has_reagent("sacid")) - descriptors |= "acidic" - if(reagents.has_reagent("fuel")) - descriptors |= "flammable" - if(reagents.has_reagent("moonshine")) - descriptors |= "intoxicating" - if(seed.get_trait(TRAIT_JUICY)) - descriptors |= "juicy" - if(seed.get_trait(TRAIT_STINGS)) - descriptors |= "stinging" - if(seed.get_trait(TRAIT_TELEPORTING)) - descriptors |= "glowing" - if(seed.get_trait(TRAIT_EXPLOSIVE)) - descriptors |= "bulbous" - - var/descriptor_num = rand(2,4) - var/descriptor_count = descriptor_num - desc = "A" - while(descriptors.len && descriptor_num > 0) - var/chosen = pick(descriptors) - descriptors -= chosen - desc += "[(descriptor_count>1 && descriptor_count!=descriptor_num) ? "," : "" ] [chosen]" - descriptor_num-- - if(seed.seed_noun == "spores") - desc += " mushroom" - else - desc += " fruit" - plant_controller.product_descs["[seed.uid]"] = desc - desc += ". Delicious! Probably." - -/obj/item/weapon/reagent_containers/food/snacks/grown/update_icon() - if(!seed || !plant_controller || !plant_controller.plant_icon_cache) - return - if(seed.modular_icon != 1) - return - overlays.Cut() - var/image/plant_icon - var/icon_key = "fruit-[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]-[seed.get_trait(TRAIT_PLANT_COLOUR)]" - if(plant_controller.plant_icon_cache[icon_key]) - plant_icon = plant_controller.plant_icon_cache[icon_key] - else - plant_icon = image('icons/obj/hydroponics_products.dmi',"blank") - var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product") - fruit_base.color = "[seed.get_trait(TRAIT_PRODUCT_COLOUR)]" - plant_icon.overlays |= fruit_base - if("[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf" in icon_states('icons/obj/hydroponics_products.dmi')) - var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf") - fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]" - plant_icon.overlays |= fruit_leaves - plant_controller.plant_icon_cache[icon_key] = plant_icon - overlays |= plant_icon - -/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(var/mob/living/M) - if(seed && seed.get_trait(TRAIT_JUICY) == 2) - if(istype(M)) - - if(M.buckled) - return - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.shoes && H.shoes.flags & NOSLIP) - return - - M.stop_pulling() - to_chat(M, "You slipped on the [name]!") - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(8) - M.Weaken(5) - seed.thrown_at(src,M) - sleep(-1) - if(src) qdel(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom) - ..() - if(seed) seed.thrown_at(src,hit_atom) - -/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/user) if(seed) - if(seed.get_trait(TRAIT_PRODUCES_POWER) && istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(C.use(5)) - //TODO: generalize this. - to_chat(user, "You add some cable to the [src.name] and slide it inside the battery casing.") - var/obj/item/weapon/stock_parts/cell/potato/pocell = new /obj/item/weapon/stock_parts/cell/potato(get_turf(user)) - if(src.loc == user && !(user.l_hand && user.r_hand) && istype(user,/mob/living/carbon/human)) - user.put_in_hands(pocell) - pocell.maxcharge = src.potency * 10 - pocell.charge = pocell.maxcharge - qdel(src) - return - else if(W.sharp) - var/reagents_per_slice - var/obj/slice - if(seed.kitchen_tag == "pumpkin") // Ugggh these checks are awful. - user.show_message("You carve a face into [src]!", 1) - new /obj/item/clothing/head/hardhat/pumpkinhead (user.loc) - qdel(src) - return - else if(seed.kitchen_tag == "potato") - to_chat(user, "You slice \the [src] into sticks.") - reagents_per_slice = reagents.total_volume - slice = new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(get_turf(src)) - reagents.trans_to(slice, reagents_per_slice) - qdel(src) - return - else if(seed.kitchen_tag == "carrot") - to_chat(user, "You slice \the [src] into sticks.") - reagents_per_slice = reagents.total_volume - slice = new /obj/item/weapon/reagent_containers/food/snacks/carrotfries(get_turf(src)) - reagents.trans_to(slice, reagents_per_slice) - qdel(src) - return - else if(seed.kitchen_tag == "watermelon") - to_chat(user, "You slice \the [src] into large slices.") - reagents_per_slice = reagents.total_volume/5 - for(var/i=0,i<5,i++) - slice = new /obj/item/weapon/reagent_containers/food/snacks/watermelonslice(get_turf(src)) - reagents.trans_to(slice, reagents_per_slice) - qdel(src) - return - else if(seed.kitchen_tag == "soybeans") - to_chat(user, "You roughly chop up \the [src].") - reagents_per_slice = reagents.total_volume - slice = new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src)) - reagents.trans_to(slice, reagents_per_slice) - qdel(src) - return - else if(seed.chems) - if(istype(W,/obj/item/weapon/hatchet) && !isnull(seed.chems["woodpulp"])) - user.show_message("You make planks out of \the [src]!", 1) - for(var/i=0,i<2,i++) - var/obj/item/stack/sheet/wood/NG = new (user.loc) - NG.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) - for(var/obj/item/stack/sheet/wood/G in user.loc) - if(G==NG) - continue - if(G.amount>=G.max_amount) - continue - G.attackby(NG, user) - to_chat(user, "You add the newly-formed wood to the stack. It now contains [NG.amount] planks.") - qdel(src) - return - else if(istype(W, /obj/item/weapon/rollingpaper)) - if(seed.kitchen_tag == "ambrosia" || seed.kitchen_tag == "ambrosiadeus" || seed.kitchen_tag == "tobacco" || seed.kitchen_tag == "stobacco") - user.unEquip(W) - if(seed.kitchen_tag == "ambrosia") - var/obj/item/clothing/mask/cigarette/joint/J = new /obj/item/clothing/mask/cigarette/joint(user.loc) - J.chem_volume = src.reagents.total_volume - src.reagents.trans_to(J, J.chem_volume) - qdel(W) - user.put_in_active_hand(J) - else if(seed.kitchen_tag == "ambrosiadeus") - var/obj/item/clothing/mask/cigarette/joint/deus/J = new /obj/item/clothing/mask/cigarette/joint/deus(user.loc) - J.chem_volume = src.reagents.total_volume - src.reagents.trans_to(J, J.chem_volume) - qdel(W) - user.put_in_active_hand(J) - else if(seed.kitchen_tag == "tobacco" || seed.kitchen_tag == "stobacco") - var/obj/item/clothing/mask/cigarette/handroll/J = new /obj/item/clothing/mask/cigarette/handroll(user.loc) - J.chem_volume = src.reagents.total_volume - src.reagents.trans_to(J, J.chem_volume) - qdel(W) - user.put_in_active_hand(J) - to_chat(user, "\blue You roll the [src] into a rolling paper.") - qdel(src) - else - to_chat(user, "\red You can't roll a smokable from the [src].") + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_new(src, newloc) + seed.prepare_result(src) + transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency! + add_juice() - ..() -/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone) - if(awakening) - to_chat(user, "The [src] is twitching and shaking, preventing you from eating it.") - return - if(user == M) - return ..() - if(user.a_intent == I_HARM) - - // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely. - // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z - if(!istype(M)) return 0 - - if(!def_zone) - def_zone = check_zone(user.zone_sel.selecting) - - user.lastattacked = M - M.lastattacker = user - user.attack_log += "\[[time_stamp()]\] Attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - M.attack_log += "\[[time_stamp()]\] Attacked by [key_name(user)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) - - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/hit = H.attacked_by(src, user, def_zone) - if(hit && hitsound) - playsound(loc, hitsound, 50, 1, -1) - //return hit - else - if(attack_verb.len) - user.visible_message("[M] has been [pick(attack_verb)] with [src] by [user]!") - else - user.visible_message("[M] has been attacked with [src] by [user]!") - - if(hitsound) - playsound(loc, hitsound, 50, 1, -1) - switch(damtype) - if("brute") - M.take_organ_damage(force) - if(prob(33)) - var/turf/simulated/location = get_turf(M) - if(istype(location)) location.add_blood_floor(M) - if("fire") - M.take_organ_damage(0, force) - M.updatehealth() - - if(seed && seed.get_trait(TRAIT_CARNIVOROUS)) - seed.do_thorns(M, src, def_zone) - - if(ishuman(M) && seed && seed.get_trait(TRAIT_STINGS)) - if(!reagents || reagents.total_volume <= 0) - return - seed.do_sting(M, src, def_zone) - reagents.remove_any(rand(1,3)) //use up some of the reagents at random - sleep(-1) - if(!src) - return - if(reagents && reagents.total_volume <= 0) //used-up fruit will be destroyed - if(user) - to_chat(user, "\The [src] has dried out and crumbles to dust.") - //user.drop_from_inventory(src) - qdel(src) - else if(prob(35)) //fruit that still has reagents has a chance of breaking each time it stings on hit - if(user) - to_chat(user, "\The [src] has fallen to bits.") - //user.drop_from_inventory(src) - qdel(src) - - add_fingerprint(user) +/obj/item/weapon/reagent_containers/food/snacks/grown/proc/add_juice() + if(reagents) + if(bitesize_mod) + bitesize = 1 + round(reagents.total_volume / bitesize_mod) return 1 + return 0 - else - ..() - -/obj/item/weapon/reagent_containers/food/snacks/grown/attack_self(mob/user as mob) - - if(!seed) - return - - if(istype(user.loc,/turf/space)) - return - - if(user.a_intent == I_HARM) - user.visible_message("\The [user] squashes \the [src]!") - seed.thrown_at(src,user) - sleep(-1) - if(src) qdel(src) - return - - if(user.a_intent == I_DISARM && seed.get_trait(TRAIT_SPREAD) > 0) //Using disarm so we can tell if you want to plant or convert non-final plants - to_chat(user, "You plant the [src.name].") - new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed) - new /obj/effect/plant(get_turf(user), src.seed) - qdel(src) - return - - - if(!seed.final_form) //This isn't even my final form! (sorry, it had to be done) - switch(seed.kitchen_tag) - if("comfrey") - var/obj/item/stack/medical/bruise_pack/comfrey/poultice = new /obj/item/stack/medical/bruise_pack/comfrey(user.loc) - poultice.heal_brute = potency - to_chat(user, "You mash the leaves into a poultice.") - qdel(src) - return - if("aloe") - var/obj/item/stack/medical/ointment/aloe/poultice = new /obj/item/stack/medical/ointment/aloe(user.loc) - poultice.heal_burn = potency - to_chat(user, "You mash the petals into a poultice.") - qdel(src) - return - if("grass") - user.show_message("You make a grass tile out of \the [src]!", 1) - for(var/i=0,i<2,i++) - var/obj/item/stack/tile/grass/G = new (user.loc) - G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) - for(var/obj/item/stack/tile/grass/NG in user.loc) - if(G==NG) - continue - if(NG.amount>=NG.max_amount) - continue - NG.attackby(G, user) - to_chat(user, "You add the newly-formed grass to the stack. It now contains [G.amount] tiles.") - qdel(src) - return - if("sunflower") - var/obj/item/weapon/grown/sunflower/SF = new /obj/item/weapon/grown/sunflower(user.loc) - user.unEquip(src) - user.put_in_hands(SF) - qdel(src) - return - if("novaflower") - var/obj/item/weapon/grown/novaflower/NF = new /obj/item/weapon/grown/novaflower(user.loc) - if(prob(10)) - user.say("PRAISE THE SUN!") - else - to_chat(user, "PRAISE THE SUN!") - user.unEquip(src) - user.put_in_hands(NF) - qdel(src) - return - if("nettle") - var/obj/item/weapon/grown/nettle/nettle = new /obj/item/weapon/grown/nettle(user.loc) - nettle.force = round((5 + potency / 5), 1) - to_chat(user, "You straighten up the plant.") - user.unEquip(src) - user.put_in_hands(nettle) - qdel(src) - return - if("deathnettle") - var/obj/item/weapon/grown/nettle/death/DN = new /obj/item/weapon/grown/nettle/death(user.loc) - DN.force = round((5 + potency / 2.5), 1) - to_chat(user, "You straighten up the plant.") - user.unEquip(src) - user.put_in_hands(DN) - qdel(src) - return - if("killertomato") - if(awakening || istype(user.loc,/turf/space)) - return - to_chat(user, "You begin to awaken the Killer Tomato...") - awakening = 1 - - spawn(30) - if(!qdeleted(src)) - var/mob/living/simple_animal/hostile/killertomato/K = new /mob/living/simple_animal/hostile/killertomato(get_turf(src.loc)) - var/endurance_value = seed.get_trait(TRAIT_ENDURANCE) - K.maxHealth += round(endurance_value / 3) - K.melee_damage_lower += round(potency / 10) - K.melee_damage_upper += round(potency / 10) - var/production_value = seed.get_trait(TRAIT_PRODUCTION) - K.move_to_delay -= round(production_value / 50) - K.health = K.maxHealth - K.visible_message("The Killer Tomato growls as it suddenly awakens.") - if(user) - user.unEquip(src) - qdel(src) - if("cashpod") - to_chat(user, "You crack open the cash pod...") - var/value = round(seed.get_trait(TRAIT_POTENCY)) - user.unEquip(src) - switch(value) - if(0) - to_chat(user, "It's empty! What a waste...") - if(1 to 10) - to_chat(user, "It has a space dollar inside. Woo.") - new /obj/item/weapon/spacecash(get_turf(user)) - if(11 to 20) - to_chat(user, "It has 10 space dollars inside!") - new /obj/item/weapon/spacecash/c10(get_turf(user)) - if(21 to 30) - to_chat(user, "It has 20 space dollars inside! Cool!") - new /obj/item/weapon/spacecash/c20(get_turf(user)) - if(31 to 40) - to_chat(user, "It has 50 space dollars inside! Nice!") - new /obj/item/weapon/spacecash/c50(get_turf(user)) - if(41 to 50) - to_chat(user, "It has 100 space dollars inside! Sweet!") - new /obj/item/weapon/spacecash/c100(get_turf(user)) - if(51 to 60) - to_chat(user, "It has 200 space dollars inside! Awesome!") - new /obj/item/weapon/spacecash/c200(get_turf(user)) - if(61 to 80) - to_chat(user, "It has 500 space dollars inside! CHA-CHING!") - new /obj/item/weapon/spacecash/c500(get_turf(user)) - else - to_chat(user, "It has 1000 space dollars inside! JACKPOT!") - new /obj/item/weapon/spacecash/c1000(get_turf(user)) - qdel(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user) +/obj/item/weapon/reagent_containers/food/snacks/grown/examine(user) ..() - if(!seed) + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + if(T.examine_line) + to_chat(user, T.examine_line) + +/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(obj/item/O, mob/user, params) + ..() + if (istype(O, /obj/item/device/plant_analyzer)) + var/msg = "*---------*\n This is \a [src].\n" + if(seed) + msg += seed.get_analyzer_text() + var/reag_txt = "" + if(seed) + for(var/reagent_id in seed.reagents_add) + var/datum/reagent/R = chemical_reagents_list[reagent_id] + var/amt = reagents.get_reagent_amount(reagent_id) + reag_txt += "\n- [R.name]: [amt]" + + if(reag_txt) + msg += reag_txt + msg += "
*---------*" + to_chat(user, msg) + else + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_attackby(src, O, user) + + +// Various gene procs +/obj/item/weapon/reagent_containers/food/snacks/grown/attack_self(mob/user) + if(seed && seed.get_gene(/datum/plant_gene/trait/squash)) + squash(user) + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom) + if(!..()) //was it caught by a mob? + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_throw_impact(src, hit_atom) + if(seed.get_gene(/datum/plant_gene/trait/squash)) + squash(hit_atom) + +/obj/item/weapon/reagent_containers/food/snacks/grown/proc/squash(atom/target) + var/turf/T = get_turf(target) + if(ispath(splat_type, /obj/effect/decal/cleanable/plant_smudge)) + if(filling_color) + var/obj/O = new splat_type(T) + O.color = filling_color + O.name = "[name] smudge" + else if(splat_type) + new splat_type(T) + + if(trash) + generate_trash(T) + + visible_message("[src] has been squashed.","You hear a smack.") + if(seed) + for(var/datum/plant_gene/trait/trait in seed.genes) + trait.on_squash(src, target) + + for(var/A in T) + if(reagents) + reagents.reaction(A) + + qdel(src) + +/obj/item/weapon/reagent_containers/food/snacks/grown/On_Consume() + if(iscarbon(usr)) + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_consume(src, usr) + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(atom/movable/AM) + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_cross(src, AM) + ..() + + +// Glow gene procs +/obj/item/weapon/reagent_containers/food/snacks/grown/generate_trash(atom/location) + if(trash && ispath(trash, /obj/item/weapon/grown)) + . = new trash(location, seed) + trash = null return - if(seed.get_trait(TRAIT_STINGS)) - var/mob/living/carbon/human/H = user - if(istype(H) && H.gloves) - return - if(!reagents || reagents.total_volume <= 0) - return - reagents.remove_any(rand(1,3)) //Todo, make it actually remove the reagents the seed uses. - seed.do_thorns(H,src) - seed.do_sting(H,src,pick("r_hand","l_hand")) + return ..() - -/obj/item/weapon/reagent_containers/food/snacks/grown/On_Consume(mob/M, mob/user) - if(seed && seed.get_trait(TRAIT_BATTERY_RECHARGE)) - if(!reagents.total_volume) - var/batteries_recharged = 0 - for(var/obj/item/weapon/stock_parts/cell/C in user.GetAllContents()) - var/newcharge = (potency*0.01)*C.maxcharge - if(C.charge < newcharge) - C.charge = newcharge - if(isobj(C.loc)) - var/obj/O = C.loc - O.update_icon() //update power meters and such - batteries_recharged = 1 - if(batteries_recharged) - to_chat(user, "Battery has recovered.") - ..() \ No newline at end of file +// For item-containing growns such as eggy or gatfruit +/obj/item/weapon/reagent_containers/food/snacks/grown/shell/attack_self(mob/user) + user.unEquip(src) + if(trash) + var/obj/item/T = generate_trash() + user.put_in_hands(T) + to_chat(user, "You open [src]\'s shell, revealing \a [T].") + qdel(src) diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm new file mode 100644 index 00000000000..f1dac422fad --- /dev/null +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -0,0 +1,86 @@ +// Ambrosia - base type +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia + seed = /obj/item/seeds/ambrosia + name = "ambrosia branch" + desc = "This is a plant." + icon_state = "ambrosiavulgaris" + slot_flags = SLOT_HEAD + filling_color = "#008000" + bitesize_mod = 2 + +// Ambrosia Vulgaris +/obj/item/seeds/ambrosia + name = "pack of ambrosia vulgaris seeds" + desc = "These seeds grow into common ambrosia, a plant grown by and from medicine." + icon_state = "seed-ambrosiavulgaris" + species = "ambrosiavulgaris" + plantname = "Ambrosia Vulgaris" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris + lifespan = 60 + endurance = 25 + yield = 6 + potency = 5 + icon_dead = "ambrosia-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/ambrosia/deus) + reagents_add = list("space_drugs" = 0.15, "bicaridine" = 0.1, "kelotane" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05, "toxin" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris + seed = /obj/item/seeds/ambrosia + name = "ambrosia vulgaris branch" + desc = "This is a plant containing various healing chemicals." + origin_tech = "biotech=2" + +// Ambrosia Deus +/obj/item/seeds/ambrosia/deus + name = "pack of ambrosia deus seeds" + desc = "These seeds grow into ambrosia deus. Could it be the food of the gods..?" + icon_state = "seed-ambrosiadeus" + species = "ambrosiadeus" + plantname = "Ambrosia Deus" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus + mutatelist = list(/obj/item/seeds/ambrosia/gaia) + reagents_add = list("weak_omnizine" = 0.15, "synaptizine" = 0.15, "space_drugs" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05) + rarity = 40 + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus + seed = /obj/item/seeds/ambrosia/deus + name = "ambrosia deus branch" + desc = "Eating this makes you feel immortal!" + icon_state = "ambrosiadeus" + filling_color = "#008B8B" + origin_tech = "biotech=4;materials=3" + +//Ambrosia Gaia +/obj/item/seeds/ambrosia/gaia + name = "pack of ambrosia gaia seeds" + desc = "These seeds grow into ambrosia gaia, filled with infinite potential." + icon_state = "seed-ambrosia_gaia" + species = "ambrosia_gaia" + plantname = "Ambrosia Gaia" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia + mutatelist = list() + reagents_add = list("earthsblood" = 0.05, "nutriment" = 0.06, "vitamin" = 0.05) + rarity = 30 //These are some pretty good plants right here + genes = list() + weed_rate = 4 + weed_chance = 100 + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia + name = "ambrosia gaia branch" + desc = "Eating this makes you immortal." + icon_state = "ambrosia_gaia" + filling_color = rgb(255, 175, 0) + origin_tech = "biotech=6;materials=5" + light_range = 3 + seed = /obj/item/seeds/ambrosia/gaia + +// Ambrosia Cruciatus +/obj/item/seeds/ambrosia/cruciatus + product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/cruciatus + potency = 10 + mutatelist = list() + reagents_add = list("thc" = 0.15, "kelotane" = 0.15, "bicaridine" = 0.1, "bath_salts" = 0.20, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/cruciatus + seed = /obj/item/seeds/ambrosia/cruciatus \ No newline at end of file diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm new file mode 100644 index 00000000000..9300eb73fef --- /dev/null +++ b/code/modules/hydroponics/grown/apple.dm @@ -0,0 +1,57 @@ +// Apple +/obj/item/seeds/apple + name = "pack of apple seeds" + desc = "These seeds grow into apple trees." + icon_state = "seed-apple" + species = "apple" + plantname = "Apple Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple + lifespan = 55 + endurance = 35 + yield = 5 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "apple-grow" + icon_dead = "apple-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/apple/gold) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/apple + seed = /obj/item/seeds/apple + name = "apple" + desc = "It's a little piece of Eden." + icon_state = "apple" + filling_color = "#FF4500" + bitesize = 100 // Always eat the apple in one bite + +// Posioned Apple +/obj/item/seeds/apple/poisoned + product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned + mutatelist = list() + reagents_add = list("cyanide" = 0.5, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 50 // Source of cyanide, and hard (almost impossible) to obtain normally. + +/obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned + seed = /obj/item/seeds/apple/poisoned + +// Gold Apple +/obj/item/seeds/apple/gold + name = "pack of golden apple seeds" + desc = "These seeds grow into golden apple trees. Good thing there are no firebirds in space." + icon_state = "seed-goldapple" + species = "goldapple" + plantname = "Golden Apple Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold + maturation = 10 + production = 10 + mutatelist = list() + reagents_add = list("gold" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 40 // Alchemy! + +/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold + seed = /obj/item/seeds/apple/gold + name = "golden apple" + desc = "Emblazoned upon the apple is the word 'Kallisti'." + icon_state = "goldapple" + filling_color = "#FFD700" + origin_tech = "biotech=4;materials=5" diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm new file mode 100644 index 00000000000..dbdffffda29 --- /dev/null +++ b/code/modules/hydroponics/grown/banana.dm @@ -0,0 +1,121 @@ +// Banana +/obj/item/seeds/banana + name = "pack of banana seeds" + desc = "They're seeds that grow into banana trees. When grown, keep away from clown." + icon_state = "seed-banana" + species = "banana" + plantname = "Banana Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana + lifespan = 50 + endurance = 30 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_dead = "banana-dead" + genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace) + reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.02) + +/obj/item/weapon/reagent_containers/food/snacks/grown/banana + seed = /obj/item/seeds/banana + name = "banana" + desc = "It's an excellent prop for a clown." + icon_state = "banana" + item_state = "banana" + trash = /obj/item/weapon/grown/bananapeel + filling_color = "#FFFF00" + bitesize = 5 + +/obj/item/weapon/reagent_containers/food/snacks/grown/banana/suicide_act(mob/user) + user.visible_message("[user] is aiming the [src.name] at themself! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) + sleep(25) + if(!user) + return (OXYLOSS) + user.say("BANG!") + sleep(25) + if(!user) + return (OXYLOSS) + user.visible_message("[user] laughs so hard they begin to suffocate!") + return (OXYLOSS) + +/obj/item/weapon/grown/bananapeel + seed = /obj/item/seeds/banana + name = "banana peel" + desc = "A peel from a banana." + icon_state = "banana_peel" + item_state = "banana_peel" + w_class = 1 + throwforce = 0 + throw_speed = 3 + throw_range = 7 + +/obj/item/weapon/grown/bananapeel/suicide_act(mob/user) + user.visible_message("[user] is deliberately slipping on the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/misc/slip.ogg', 50, 1, -1) + return (BRUTELOSS) + + +// Mimana - invisible sprites are totally a feature! +/obj/item/seeds/banana/mime + name = "pack of mimana seeds" + desc = "They're seeds that grow into mimana trees. When grown, keep away from mime." + icon_state = "seed-mimana" + species = "mimana" + plantname = "Mimana Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana/mime + growthstages = 4 + mutatelist = list() + reagents_add = list("nothing" = 0.1, "capulettium_plus" = 0.1, "nutriment" = 0.02) + rarity = 15 + +/obj/item/weapon/reagent_containers/food/snacks/grown/banana/mime + seed = /obj/item/seeds/banana/mime + name = "mimana" + desc = "It's an excellent prop for a mime." + icon_state = "mimana" + trash = /obj/item/weapon/grown/bananapeel/mimanapeel + filling_color = "#FFFFEE" + +/obj/item/weapon/grown/bananapeel/mimanapeel + seed = /obj/item/seeds/banana/mime + name = "mimana peel" + desc = "A mimana peel." + icon_state = "mimana_peel" + +// Bluespace Banana +/obj/item/seeds/banana/bluespace + name = "pack of bluespace banana seeds" + desc = "They're seeds that grow into bluespace banana trees. When grown, keep away from bluespace clown." + icon_state = "seed-banana-blue" + species = "bluespacebanana" + icon_grow = "banana-grow" + plantname = "Bluespace Banana Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace + mutatelist = list() + genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/teleport, /datum/plant_gene/trait/repeated_harvest) + reagents_add = list("singulo" = 0.2, "banana" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.02) + rarity = 30 + +/obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace + seed = /obj/item/seeds/banana/bluespace + name = "bluespace banana" + icon_state = "banana_blue" + trash = /obj/item/weapon/grown/bananapeel/bluespace + filling_color = "#0000FF" + origin_tech = "biotech=3;bluespace=5" + +/obj/item/weapon/grown/bananapeel/bluespace + seed = /obj/item/seeds/banana/bluespace + name = "bluespace banana peel" + desc = "A peel from a bluespace banana." + icon_state = "banana_peel_blue" + +// Other +/obj/item/weapon/grown/bananapeel/specialpeel //used by /obj/item/clothing/shoes/clown_shoes/banana_shoes + name = "synthesized banana peel" + desc = "A synthetic banana peel." + +/obj/item/weapon/grown/bananapeel/specialpeel/Crossed(AM) + if(iscarbon(AM)) + var/mob/living/carbon/carbon = AM + if(carbon.slip("[src]", 2, 2)) + qdel(src) diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm new file mode 100644 index 00000000000..d939387fe2b --- /dev/null +++ b/code/modules/hydroponics/grown/beans.dm @@ -0,0 +1,48 @@ +// Soybeans +/obj/item/seeds/soya + name = "pack of soybean seeds" + desc = "These seeds grow into soybean plants." + icon_state = "seed-soybean" + species = "soybean" + plantname = "Soybean Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans + maturation = 4 + production = 4 + potency = 15 + growthstages = 4 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "soybean-grow" + icon_dead = "soybean-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/soya/koi) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans + seed = /obj/item/seeds/soya + name = "soybeans" + desc = "It's pretty bland, but oh the possibilities..." + gender = PLURAL + icon_state = "soybeans" + filling_color = "#F0E68C" + bitesize_mod = 2 + +// Koibean +/obj/item/seeds/soya/koi + name = "pack of koibean seeds" + desc = "These seeds grow into koibean plants." + icon_state = "seed-koibean" + species = "koibean" + plantname = "Koibean Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/koibeans + potency = 10 + mutatelist = list() + reagents_add = list("carpotoxin" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/koibeans + seed = /obj/item/seeds/soya/koi + name = "koibean" + desc = "Something about these seems fishy." + icon_state = "koibeans" + filling_color = "#F0E68C" + bitesize_mod = 2 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm new file mode 100644 index 00000000000..ff411e0b990 --- /dev/null +++ b/code/modules/hydroponics/grown/berries.dm @@ -0,0 +1,188 @@ +// Berries +/obj/item/seeds/berry + name = "pack of berry seeds" + desc = "These seeds grow into berry bushes." + icon_state = "seed-berry" + species = "berry" + plantname = "Berry Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries + lifespan = 20 + maturation = 5 + production = 5 + yield = 2 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "berry-grow" // Uses one growth icons set for all the subtypes + icon_dead = "berry-dead" // Same for the dead icon + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/berry/glow, /obj/item/seeds/berry/poison) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/berries + seed = /obj/item/seeds/berry + name = "bunch of berries" + desc = "Nutritious!" + icon_state = "berrypile" + gender = PLURAL + filling_color = "#FF00FF" + bitesize_mod = 2 + +// Poison Berries +/obj/item/seeds/berry/poison + name = "pack of poison-berry seeds" + desc = "These seeds grow into poison-berry bushes." + icon_state = "seed-poisonberry" + species = "poisonberry" + plantname = "Poison-Berry Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison + mutatelist = list(/obj/item/seeds/berry/death) + reagents_add = list("cyanide" = 0.15, "tirizene" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 10 // Mildly poisonous berries are common in reality + +/obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison + seed = /obj/item/seeds/berry/poison + name = "bunch of poison-berries" + desc = "Taste so good, you could die!" + icon_state = "poisonberrypile" + filling_color = "#C71585" + +// Death Berries +/obj/item/seeds/berry/death + name = "pack of death-berry seeds" + desc = "These seeds grow into death berries." + icon_state = "seed-deathberry" + species = "deathberry" + plantname = "Death Berry Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/death + lifespan = 30 + potency = 50 + mutatelist = list() + reagents_add = list("coniine" = 0.08, "tirizene" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 30 + +/obj/item/weapon/reagent_containers/food/snacks/grown/berries/death + seed = /obj/item/seeds/berry/death + name = "bunch of death-berries" + desc = "Taste so good, you could die!" + icon_state = "deathberrypile" + filling_color = "#708090" + +// Glow Berries +/obj/item/seeds/berry/glow + name = "pack of glow-berry seeds" + desc = "These seeds grow into glow-berry bushes." + icon_state = "seed-glowberry" + species = "glowberry" + plantname = "Glow-Berry Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow + lifespan = 30 + endurance = 25 + mutatelist = list() + genes = list(/datum/plant_gene/trait/glow/berry , /datum/plant_gene/trait/noreact, /datum/plant_gene/trait/repeated_harvest) + reagents_add = list("uranium" = 0.25, "iodine" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow + seed = /obj/item/seeds/berry/glow + name = "bunch of glow-berries" + desc = "Nutritious!" + icon_state = "glowberrypile" + filling_color = "#7CFC00" + origin_tech = "plasmatech=6" + light_color = "#006622" + +// Cherries +/obj/item/seeds/cherry + name = "pack of cherry pits" + desc = "Careful not to crack a tooth on one... That'd be the pits." + icon_state = "seed-cherry" + species = "cherry" + plantname = "Cherry Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherries + lifespan = 35 + endurance = 35 + maturation = 5 + production = 5 + growthstages = 5 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "cherry-grow" + icon_dead = "cherry-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/cherry/blue) + reagents_add = list("plantmatter" = 0.07, "sugar" = 0.07) + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherries + seed = /obj/item/seeds/cherry + name = "cherries" + desc = "Great for toppings!" + icon_state = "cherry" + gender = PLURAL + filling_color = "#FF0000" + bitesize_mod = 2 + +// Blue Cherries +/obj/item/seeds/cherry/blue + name = "pack of blue cherry pits" + desc = "The blue kind of cherries" + icon_state = "seed-bluecherry" + species = "bluecherry" + plantname = "Blue Cherry Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries + mutatelist = list() + reagents_add = list("plantmatter" = 0.07, "sugar" = 0.07) + rarity = 10 + +/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries + seed = /obj/item/seeds/cherry/blue + name = "blue cherries" + desc = "They're cherries that are blue." + icon_state = "bluecherry" + filling_color = "#6495ED" + bitesize_mod = 2 + +// Grapes +/obj/item/seeds/grape + name = "pack of grape seeds" + desc = "These seeds grow into grape vines." + icon_state = "seed-grapes" + species = "grape" + plantname = "Grape Vine" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/grapes + lifespan = 50 + endurance = 25 + maturation = 3 + production = 5 + yield = 4 + growthstages = 2 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "grape-grow" + icon_dead = "grape-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/grape/green) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1, "sugar" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/grapes + seed = /obj/item/seeds/grape + name = "bunch of grapes" + desc = "Nutritious!" + icon_state = "grapes" + dried_type = /obj/item/weapon/reagent_containers/food/snacks/no_raisin + filling_color = "#FF1493" + bitesize_mod = 2 + +// Green Grapes +/obj/item/seeds/grape/green + name = "pack of green grape seeds" + desc = "These seeds grow into green-grape vines." + icon_state = "seed-greengrapes" + species = "greengrape" + plantname = "Green-Grape Vine" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green + reagents_add = list("kelotane" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1, "sugar" = 0.1) + // No rarity: technically it's a beneficial mutant, but it's not exactly "new"... + mutatelist = list() + +/obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green + seed = /obj/item/seeds/grape/green + name = "bunch of green grapes" + icon_state = "greengrapes" + filling_color = "#7FFF00" diff --git a/code/modules/hydroponics/grown/cannabis.dm b/code/modules/hydroponics/grown/cannabis.dm new file mode 100644 index 00000000000..ab1dff988e8 --- /dev/null +++ b/code/modules/hydroponics/grown/cannabis.dm @@ -0,0 +1,121 @@ +// Cannabis +/obj/item/seeds/cannabis + name = "pack of cannabis seeds" + desc = "Taxable." + icon_state = "seed-cannabis" + species = "cannabis" + plantname = "Cannabis Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cannabis + maturation = 8 + potency = 20 + growthstages = 1 + growing_icon = 'icons/goonstation/objects/hydroponics.dmi' + icon_grow = "cannabis-grow" // Uses one growth icons set for all the subtypes + icon_dead = "cannabis-dead" // Same for the dead icon + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/cannabis/rainbow, + /obj/item/seeds/cannabis/death, + /obj/item/seeds/cannabis/white, + /obj/item/seeds/cannabis/ultimate) + reagents_add = list("thc" = 0.15) + + +/obj/item/seeds/cannabis/rainbow + name = "pack of rainbow weed seeds" + desc = "These seeds grow into rainbow weed. Groovy." + icon_state = "seed-megacannabis" + species = "megacannabis" + plantname = "Rainbow Weed" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/rainbow + mutatelist = list() + reagents_add = list("lsd" = 0.15, "thc" = 0.15) + rarity = 40 + +/obj/item/seeds/cannabis/death + name = "pack of deathweed seeds" + desc = "These seeds grow into deathweed. Not groovy." + icon_state = "seed-blackcannabis" + species = "blackcannabis" + plantname = "Deathweed" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/death + mutatelist = list() + reagents_add = list("cyanide" = 0.35, "thc" = 0.15) + rarity = 40 + +/obj/item/seeds/cannabis/white + name = "pack of lifeweed seeds" + desc = "I will give unto him that is munchies of the fountain of the cravings of life, freely." + icon_state = "seed-whitecannabis" + species = "whitecannabis" + plantname = "Lifeweed" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/white + mutatelist = list() + reagents_add = list("omnizine" = 0.35, "thc" = 0.15) + rarity = 40 + + +/obj/item/seeds/cannabis/ultimate + name = "pack of omega weed seeds" + desc = "These seeds grow into omega weed." + icon_state = "seed-ocannabis" + species = "ocannabis" + plantname = "Omega Weed" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/ultimate + mutatelist = list() + reagents_add = list("lsd" = 0.15, + "suicider" = 0.15, + "space_drugs" = 0.15, + "mercury" = 0.15, + "lithium" = 0.15, + "atropine" = 0.15, + "ephedrine" = 0.15, + "haloperidol" = 0.15, + "methamphetamine" = 0.15, + "thc" = 0.15, + "psilocybin" = 0.15, + "hairgrownium" = 0.15, + "ectoplasm" = 0.15, + "bath_salts" = 0.15, + "itching_powder" = 0.15, + "crank" = 0.15, + "krokodil" = 0.15, + "histamine" = 0.15) + rarity = 69 + + +// --------------------------------------------------------------- + +/obj/item/weapon/reagent_containers/food/snacks/grown/cannabis + seed = /obj/item/seeds/cannabis + icon = 'icons/goonstation/objects/hydroponics.dmi' + name = "cannabis leaf" + desc = "Recently legalized in most galaxies." + icon_state = "cannabis" + filling_color = "#00FF00" + bitesize_mod = 2 + + +/obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/rainbow + seed = /obj/item/seeds/cannabis/rainbow + name = "rainbow cannabis leaf" + desc = "Is it supposed to be glowing like that...?" + icon_state = "megacannabis" + +/obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/death + seed = /obj/item/seeds/cannabis/death + name = "death cannabis leaf" + desc = "Looks a bit dark. Oh well." + icon_state = "blackcannabis" + +/obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/white + seed = /obj/item/seeds/cannabis/white + name = "white cannabis leaf" + desc = "It feels smooth and nice to the touch." + icon_state = "whitecannabis" + +/obj/item/weapon/reagent_containers/food/snacks/grown/cannabis/ultimate + seed = /obj/item/seeds/cannabis/ultimate + name = "omega cannibas leaf" + desc = "You feel dizzy looking at it. What the fuck?" + icon_state = "ocannabis" + volume = 420 diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm new file mode 100644 index 00000000000..040e557352c --- /dev/null +++ b/code/modules/hydroponics/grown/cereals.dm @@ -0,0 +1,91 @@ +// Wheat +/obj/item/seeds/wheat + name = "pack of wheat seeds" + desc = "These may, or may not, grow into wheat." + icon_state = "seed-wheat" + species = "wheat" + plantname = "Wheat Stalks" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat + production = 1 + yield = 4 + potency = 15 + icon_dead = "wheat-dead" + mutatelist = list(/obj/item/seeds/wheat/oat, /obj/item/seeds/wheat/meat) + reagents_add = list("plantmatter" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/wheat + seed = /obj/item/seeds/wheat + name = "wheat" + desc = "Sigh... wheat... a-grain?" + gender = PLURAL + icon_state = "wheat" + filling_color = "#F0E68C" + bitesize_mod = 2 + +// Oat +/obj/item/seeds/wheat/oat + name = "pack of oat seeds" + desc = "These may, or may not, grow into oat." + icon_state = "seed-oat" + species = "oat" + plantname = "Oat Stalks" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/oat + mutatelist = list() + +/obj/item/weapon/reagent_containers/food/snacks/grown/oat + seed = /obj/item/seeds/wheat/oat + name = "oat" + desc = "Eat oats, do squats." + gender = PLURAL + icon_state = "oat" + filling_color = "#556B2F" + bitesize_mod = 2 + +// Rice +/obj/item/seeds/wheat/rice + name = "pack of rice seeds" + desc = "These may, or may not, grow into rice." + icon_state = "seed-rice" + species = "rice" + plantname = "Rice Stalks" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/rice + mutatelist = list() + growthstages = 3 + +/obj/item/weapon/reagent_containers/food/snacks/grown/rice + seed = /obj/item/seeds/wheat/rice + name = "rice" + desc = "Rice to meet you." + gender = PLURAL + icon_state = "rice" + filling_color = "#FAFAD2" + bitesize_mod = 2 + +//Meatwheat - grows into synthetic meat +/obj/item/seeds/wheat/meat + name = "pack of meatwheat seeds" + desc = "If you ever wanted to drive a vegetarian to insanity, here's how." + icon_state = "seed-meatwheat" + species = "meatwheat" + plantname = "Meatwheat" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/meatwheat + mutatelist = list() + reagents_add = list("protein" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/meatwheat + name = "meatwheat" + desc = "Some blood-drenched wheat stalks. You can crush them into what passes for meat if you squint hard enough." + icon_state = "meatwheat" + gender = PLURAL + filling_color = rgb(150, 0, 0) + bitesize_mod = 2 + seed = /obj/item/seeds/wheat/meat + +/obj/item/weapon/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) + user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") + playsound(user, 'sound/effects/blobattack.ogg', 50, 1) + var/obj/item/weapon/reagent_containers/food/snacks/meat/meatwheat/M = new(get_turf(user)) + user.drop_item() + qdel(src) + user.put_in_hands(M) + return 1 diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm new file mode 100644 index 00000000000..c80ffa561d3 --- /dev/null +++ b/code/modules/hydroponics/grown/chili.dm @@ -0,0 +1,76 @@ +// Chili +/obj/item/seeds/chili + name = "pack of chili seeds" + desc = "These seeds grow into chili plants. HOT! HOT! HOT!" + icon_state = "seed-chili" + species = "chili" + plantname = "Chili Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/chili + lifespan = 20 + maturation = 5 + production = 5 + yield = 4 + potency = 20 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "chili-grow" // Uses one growth icons set for all the subtypes + icon_dead = "chili-dead" // Same for the dead icon + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/chili/ice, /obj/item/seeds/chili/ghost) + reagents_add = list("capsaicin" = 0.25, "vitamin" = 0.04, "plantmatter" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/chili + seed = /obj/item/seeds/chili + name = "chili" + desc = "It's spicy! Wait... IT'S BURNING ME!!" + icon_state = "chilipepper" + filling_color = "#FF0000" + bitesize_mod = 2 + +// Ice Chili +/obj/item/seeds/chili/ice + name = "pack of ice pepper seeds" + desc = "These seeds grow into ice pepper plants." + icon_state = "seed-icepepper" + species = "chiliice" + plantname = "Ice Pepper Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper + lifespan = 25 + maturation = 4 + production = 4 + rarity = 20 + mutatelist = list() + reagents_add = list("frostoil" = 0.25, "vitamin" = 0.02, "plantmatter" = 0.02) + +/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper + seed = /obj/item/seeds/chili/ice + name = "ice pepper" + desc = "It's a mutant strain of chili" + icon_state = "icepepper" + filling_color = "#0000CD" + bitesize_mod = 2 + origin_tech = "biotech=4" + +// Ghost Chili +/obj/item/seeds/chili/ghost + name = "pack of ghost chili seeds" + desc = "These seeds grow into a chili said to be the hottest in the galaxy." + icon_state = "seed-chilighost" + species = "chilighost" + plantname = "Ghost Chili Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili + endurance = 10 + maturation = 10 + production = 10 + yield = 3 + rarity = 20 + mutatelist = list() + reagents_add = list("condensedcapsaicin" = 0.3, "capsaicin" = 0.55, "plantmatter" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili + seed = /obj/item/seeds/chili/ghost + name = "ghost chili" + desc = "It seems to be vibrating gently." + icon_state = "ghostchilipepper" + filling_color = "#F8F8FF" + bitesize_mod = 4 + origin_tech = "biotech=4;magnets=5" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm new file mode 100644 index 00000000000..1657dd0e955 --- /dev/null +++ b/code/modules/hydroponics/grown/citrus.dm @@ -0,0 +1,155 @@ +// Citrus - base type +/obj/item/weapon/reagent_containers/food/snacks/grown/citrus + seed = /obj/item/seeds/lime + name = "citrus" + desc = "It's so sour, your face will twist." + icon_state = "lime" + bitesize_mod = 2 + +// Lime +/obj/item/seeds/lime + name = "pack of lime seeds" + desc = "These are very sour seeds." + icon_state = "seed-lime" + species = "lime" + plantname = "Lime Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime + lifespan = 55 + endurance = 50 + yield = 4 + potency = 15 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/orange) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime + seed = /obj/item/seeds/lime + name = "lime" + desc = "It's so sour, your face will twist." + icon_state = "lime" + filling_color = "#00FF00" + +// Orange +/obj/item/seeds/orange + name = "pack of orange seeds" + desc = "Sour seeds." + icon_state = "seed-orange" + species = "orange" + plantname = "Orange Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange + lifespan = 60 + endurance = 50 + yield = 5 + potency = 20 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "lime-grow" + icon_dead = "lime-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/lime) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange + seed = /obj/item/seeds/orange + name = "orange" + desc = "It's an tangy fruit." + icon_state = "orange" + filling_color = "#FFA500" + +// Lemon +/obj/item/seeds/lemon + name = "pack of lemon seeds" + desc = "These are sour seeds." + icon_state = "seed-lemon" + species = "lemon" + plantname = "Lemon Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon + lifespan = 55 + endurance = 45 + yield = 4 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "lime-grow" + icon_dead = "lime-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/firelemon) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon + seed = /obj/item/seeds/lemon + name = "lemon" + desc = "When life gives you lemons, make lemonade." + icon_state = "lemon" + filling_color = "#FFD700" + +// Combustible lemon +/obj/item/seeds/firelemon //combustible lemon is too long so firelemon + name = "pack of combustible lemon seeds" + desc = "When life gives you lemons, don't make lemonade. Make life take the lemons back! Get mad! I don't want your damn lemons!" + icon_state = "seed-firelemon" + species = "firelemon" + plantname = "Combustible Lemon Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/firelemon + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "lime-grow" + icon_dead = "lime-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + lifespan = 55 + endurance = 45 + yield = 4 + reagents_add = list("plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon + seed = /obj/item/seeds/firelemon + name = "Combustible Lemon" + desc = "Made for burning houses down." + icon_state = "firelemon" + bitesize_mod = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon/attack_self(mob/living/user) + var/area/A = get_area(user) + user.visible_message("[user] primes the [src]!", "You prime the [src]!") + var/message = "[ADMIN_LOOKUPFLW(user)] primed a combustible lemon for detonation at [A] [ADMIN_COORDJMP(user)]" + bombers += message + message_admins(message) + log_game("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].") + if(iscarbon(user)) + var/mob/living/carbon/C = user + C.throw_mode_on() + icon_state = "firelemon_active" + playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) + addtimer(src, "prime", rand(10, 60)) + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon/burn() + prime() + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon/proc/update_mob() + if(ismob(loc)) + var/mob/M = loc + M.unEquip(src) + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon/ex_act(severity) + qdel(src) //Ensuring that it's deleted by its own explosion + +/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon/proc/prime() + switch(seed.potency) //Combustible lemons are alot like IEDs, lots of flame, very little bang. + if(0 to 30) + update_mob() + explosion(loc,-1,-1,2, flame_range = 1) + qdel(src) + if(31 to 50) + update_mob() + explosion(loc,-1,-1,2, flame_range = 2) + qdel(src) + if(51 to 70) + update_mob() + explosion(loc,-1,-1,2, flame_range = 3) + qdel(src) + if(71 to 90) + update_mob() + explosion(loc,-1,-1,2, flame_range = 4) + qdel(src) + else + update_mob() + explosion(loc,-1,-1,2, flame_range = 5) + qdel(src) diff --git a/code/modules/hydroponics/grown/cocoa_vanilla.dm b/code/modules/hydroponics/grown/cocoa_vanilla.dm new file mode 100644 index 00000000000..74754fac13e --- /dev/null +++ b/code/modules/hydroponics/grown/cocoa_vanilla.dm @@ -0,0 +1,46 @@ +// Cocoa Pod +/obj/item/seeds/cocoapod + name = "pack of cocoa pod seeds" + desc = "These seeds grow into cacao trees. They look fattening." //SIC: cocoa is the seeds. The trees are spelled cacao. + icon_state = "seed-cocoapod" + species = "cocoapod" + plantname = "Cocao Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod + lifespan = 20 + maturation = 5 + production = 5 + yield = 2 + growthstages = 5 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "cocoapod-grow" + icon_dead = "cocoapod-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/cocoapod/vanillapod) + reagents_add = list("cocoa" = 0.25, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod + seed = /obj/item/seeds/cocoapod + name = "cocoa pod" + desc = "Fattening... Mmmmm... chucklate." + icon_state = "cocoapod" + filling_color = "#FFD700" + bitesize_mod = 2 + +// Vanilla Pod +/obj/item/seeds/cocoapod/vanillapod + name = "pack of vanilla pod seeds" + desc = "These seeds grow into vanilla trees. They look fattening." + icon_state = "seed-vanillapod" + species = "vanillapod" + plantname = "Vanilla Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list() + reagents_add = list("vanilla" = 0.25, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod + seed = /obj/item/seeds/cocoapod/vanillapod + name = "vanilla pod" + desc = "Fattening... Mmmmm... vanilla." + icon_state = "vanillapod" + filling_color = "#FFD700" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm new file mode 100644 index 00000000000..a7ef947a5ce --- /dev/null +++ b/code/modules/hydroponics/grown/corn.dm @@ -0,0 +1,84 @@ +// Corn +/obj/item/seeds/corn + name = "pack of corn seeds" + desc = "I don't mean to sound corny..." + icon_state = "seed-corn" + species = "corn" + plantname = "Corn Stalks" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/corn + maturation = 8 + potency = 20 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "corn-grow" // Uses one growth icons set for all the subtypes + icon_dead = "corn-dead" // Same for the dead icon + mutatelist = list(/obj/item/seeds/corn/snapcorn) + reagents_add = list("cornoil" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/corn + seed = /obj/item/seeds/corn + name = "ear of corn" + desc = "Needs some butter!" + icon_state = "corn" + cooked_type = /obj/item/weapon/reagent_containers/food/snacks/popcorn + filling_color = "#FFFF00" + trash = /obj/item/weapon/grown/corncob + bitesize_mod = 2 + +/obj/item/weapon/grown/corncob + name = "corn cob" + desc = "A reminder of meals gone by." + icon_state = "corncob" + item_state = "corncob" + w_class = 1 + throwforce = 0 + throw_speed = 3 + throw_range = 7 + +/obj/item/weapon/grown/corncob/attackby(obj/item/weapon/grown/W, mob/user, params) + if(is_sharp(W)) + to_chat(user, "You use [W] to fashion a pipe out of the corn cob!") + new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc) + user.unEquip(src) + qdel(src) + return + else + return ..() + +// Snapcorn +/obj/item/seeds/corn/snapcorn + name = "pack of snapcorn seeds" + desc = "Oh snap!" + icon_state = "seed-snapcorn" + species = "snapcorn" + plantname = "Snapcorn Stalks" + product = /obj/item/weapon/grown/snapcorn + mutatelist = list() + rarity = 10 + +/obj/item/weapon/grown/snapcorn + seed = /obj/item/seeds/corn/snapcorn + name = "snap corn" + desc = "A cob with snap pops" + icon_state = "snapcorn" + item_state = "corncob" + w_class = 1 + throwforce = 0 + throw_speed = 3 + throw_range = 7 + var/snap_pops = 1 + +/obj/item/weapon/grown/snapcorn/add_juice() + ..() + snap_pops = max(round(seed.potency/8), 1) + +/obj/item/weapon/grown/snapcorn/attack_self(mob/user) + ..() + to_chat(user, "You pick a snap pop from the cob.") + var/obj/item/toy/snappop/S = new /obj/item/toy/snappop(user.loc) + if(ishuman(user)) + user.put_in_hands(S) + snap_pops -= 1 + if(!snap_pops) + new /obj/item/weapon/grown/corncob(user.loc) + qdel(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/eggplant.dm b/code/modules/hydroponics/grown/eggplant.dm new file mode 100644 index 00000000000..6fb991b9d32 --- /dev/null +++ b/code/modules/hydroponics/grown/eggplant.dm @@ -0,0 +1,44 @@ +// Eggplant +/obj/item/seeds/eggplant + name = "pack of eggplant seeds" + desc = "These seeds grow to produce berries that look nothing like eggs." + icon_state = "seed-eggplant" + species = "eggplant" + plantname = "Eggplants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant + yield = 2 + potency = 20 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "eggplant-grow" + icon_dead = "eggplant-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/eggplant/eggy) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant + seed = /obj/item/seeds/eggplant + name = "eggplant" + desc = "Maybe there's a chicken inside?" + icon_state = "eggplant" + filling_color = "#800080" + bitesize_mod = 2 + +// Egg-Plant +/obj/item/seeds/eggplant/eggy + desc = "These seeds grow to produce berries that look a lot like eggs." + icon_state = "seed-eggy" + species = "eggy" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy + lifespan = 75 + production = 12 + mutatelist = list() + reagents_add = list("nutriment" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy + seed = /obj/item/seeds/eggplant/eggy + name = "Egg-plant" + desc = "There MUST be a chicken inside." + icon_state = "eggyplant" + trash = /obj/item/weapon/reagent_containers/food/snacks/egg + filling_color = "#F8F8FF" + bitesize_mod = 2 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm new file mode 100644 index 00000000000..7deb961e67a --- /dev/null +++ b/code/modules/hydroponics/grown/flowers.dm @@ -0,0 +1,202 @@ +// Poppy +/obj/item/seeds/poppy + name = "pack of poppy seeds" + desc = "These seeds grow into poppies." + icon_state = "seed-poppy" + species = "poppy" + plantname = "Poppy Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy + endurance = 10 + maturation = 8 + yield = 6 + potency = 20 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi' + icon_grow = "poppy-grow" + icon_dead = "poppy-dead" + mutatelist = list(/obj/item/seeds/poppy/geranium, /obj/item/seeds/poppy/lily) + reagents_add = list("bicaridine" = 0.2, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/poppy + seed = /obj/item/seeds/poppy + name = "poppy" + desc = "Long-used as a symbol of rest, peace, and death." + icon_state = "poppy" + slot_flags = SLOT_HEAD + filling_color = "#FF6347" + bitesize_mod = 3 + +// Lily +/obj/item/seeds/poppy/lily + name = "pack of lily seeds" + desc = "These seeds grow into lilies." + icon_state = "seed-lily" + species = "lily" + plantname = "Lily Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/lily + mutatelist = list() + +/obj/item/weapon/reagent_containers/food/snacks/grown/poppy/lily + seed = /obj/item/seeds/poppy/lily + name = "lily" + desc = "A beautiful orange flower" + icon_state = "lily" + filling_color = "#FFA500" + +// Geranium +/obj/item/seeds/poppy/geranium + name = "pack of geranium seeds" + desc = "These seeds grow into geranium." + icon_state = "seed-geranium" + species = "geranium" + plantname = "Geranium Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/poppy/geranium + mutatelist = list() + +/obj/item/weapon/reagent_containers/food/snacks/grown/poppy/geranium + seed = /obj/item/seeds/poppy/geranium + name = "geranium" + desc = "A beautiful blue flower" + icon_state = "geranium" + filling_color = "#008B8B" + + +// Harebell +/obj/item/seeds/harebell + name = "pack of harebell seeds" + desc = "These seeds grow into pretty little flowers." + icon_state = "seed-harebell" + species = "harebell" + plantname = "Harebells" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/harebell + lifespan = 100 + endurance = 20 + maturation = 7 + production = 1 + yield = 2 + potency = 30 + growthstages = 4 + genes = list(/datum/plant_gene/trait/plant_type/weed_hardy) + growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi' + reagents_add = list("plantmatter" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/harebell + seed = /obj/item/seeds/harebell + name = "harebell" + desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten'd not thy breath.\"" + icon_state = "harebell" + slot_flags = SLOT_HEAD + filling_color = "#E6E6FA" + bitesize_mod = 3 + + +// Sunflower +/obj/item/seeds/sunflower + name = "pack of sunflower seeds" + desc = "These seeds grow into sunflowers." + icon_state = "seed-sunflower" + species = "sunflower" + plantname = "Sunflowers" + product = /obj/item/weapon/grown/sunflower + endurance = 20 + production = 2 + yield = 2 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi' + icon_grow = "sunflower-grow" + icon_dead = "sunflower-dead" + mutatelist = list(/obj/item/seeds/sunflower/moonflower, /obj/item/seeds/sunflower/novaflower) + reagents_add = list("cornoil" = 0.08, "plantmatter" = 0.04) + +/obj/item/weapon/grown/sunflower // FLOWER POWER! + seed = /obj/item/seeds/sunflower + name = "sunflower" + desc = "It's beautiful! A certain person might beat you to death if you trample these." + icon_state = "sunflower" + damtype = "fire" + force = 0 + slot_flags = SLOT_HEAD + throwforce = 0 + w_class = 1 + throw_speed = 1 + throw_range = 3 + +/obj/item/weapon/grown/sunflower/attack(mob/M, mob/user) + to_chat(M, " [user] smacks you with a sunflower!FLOWER POWER") + to_chat(user, "Your sunflower's FLOWER POWERstrikes [M]") + +// Moonflower +/obj/item/seeds/sunflower/moonflower + name = "pack of moonflower seeds" + desc = "These seeds grow into moonflowers." + icon_state = "seed-moonflower" + species = "moonflower" + plantname = "Moonflowers" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/moonflower + mutatelist = list() + reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "plantmatter" = 0.02) + rarity = 15 + +/obj/item/weapon/reagent_containers/food/snacks/grown/moonflower + seed = /obj/item/seeds/sunflower/moonflower + name = "moonflower" + desc = "Store in a location at least 50 yards away from werewolves." + icon_state = "moonflower" + slot_flags = SLOT_HEAD + filling_color = "#E6E6FA" + bitesize_mod = 2 + +// Novaflower +/obj/item/seeds/sunflower/novaflower + name = "pack of novaflower seeds" + desc = "These seeds grow into novaflowers." + icon_state = "seed-novaflower" + species = "novaflower" + plantname = "Novaflowers" + product = /obj/item/weapon/grown/novaflower + mutatelist = list() + reagents_add = list("condensedcapsaicin" = 0.25, "capsaicin" = 0.3, "plantmatter" = 0) + rarity = 20 + +/obj/item/weapon/grown/novaflower + seed = /obj/item/seeds/sunflower/novaflower + name = "novaflower" + desc = "These beautiful flowers have a crisp smokey scent, like a summer bonfire." + icon_state = "novaflower" + damtype = "fire" + force = 0 + slot_flags = SLOT_HEAD + throwforce = 0 + w_class = 1 + throw_speed = 1 + throw_range = 3 + attack_verb = list("roasted", "scorched", "burned") + +/obj/item/weapon/grown/novaflower/add_juice() + ..() + force = round((5 + seed.potency / 5), 1) + +/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M, mob/user) + ..() + if(isliving(M)) + to_chat(M, "You are lit on fire from the intense heat of the [name]!") + M.adjust_fire_stacks(seed.potency / 20) + if(M.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(M)] on fire") + log_game("[key_name(user)] set [key_name(M)] on fire") + +/obj/item/weapon/grown/novaflower/afterattack(atom/A as mob|obj, mob/user,proximity) + if(!proximity) + return + if(force > 0) + force -= rand(1, (force / 3) + 1) + else + to_chat(usr, "All the petals have fallen off the [name] from violent whacking!") + usr.unEquip(src) + qdel(src) + +/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user) + ..() + if(!user.gloves) + to_chat(user, "The [name] burns your bare hand!") + user.adjustFireLoss(rand(1, 5)) diff --git a/code/modules/hydroponics/grown/grass_carpet.dm b/code/modules/hydroponics/grown/grass_carpet.dm new file mode 100644 index 00000000000..24c0a9f9df2 --- /dev/null +++ b/code/modules/hydroponics/grown/grass_carpet.dm @@ -0,0 +1,67 @@ +// Grass +/obj/item/seeds/grass + name = "pack of grass seeds" + desc = "These seeds grow into grass. Yummy!" + icon_state = "seed-grass" + species = "grass" + plantname = "Grass" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/grass + lifespan = 40 + endurance = 40 + maturation = 2 + production = 5 + yield = 5 + growthstages = 2 + icon_grow = "grass-grow" + icon_dead = "grass-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/grass/carpet) + reagents_add = list("plantmatter" = 0.02, "hydrogen" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/grass + seed = /obj/item/seeds/grass + name = "grass" + desc = "Green and lush." + icon_state = "grassclump" + filling_color = "#32CD32" + bitesize_mod = 2 + var/stacktype = /obj/item/stack/tile/grass + var/tile_coefficient = 0.02 // 1/50 + +/obj/item/weapon/reagent_containers/food/snacks/grown/grass/attack_self(mob/user) + to_chat(user, "You prepare the astroturf.") + var/grassAmt = 1 + round(seed.potency * tile_coefficient) // The grass we're holding + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/grass/G in user.loc) // The grass on the floor + if(G.type != type) + continue + grassAmt += 1 + round(G.seed.potency * tile_coefficient) + qdel(G) + var/obj/item/stack/tile/GT = new stacktype(user.loc) + while(grassAmt > GT.max_amount) + GT.amount = GT.max_amount + grassAmt -= GT.max_amount + GT = new stacktype(user.loc) + GT.amount = grassAmt + for(var/obj/item/stack/tile/T in user.loc) + if((T.type == stacktype) && (T.amount < T.max_amount) && (T != GT)) + T.attackby(GT, user) + qdel(src) + return + +// Carpet +/obj/item/seeds/grass/carpet + name = "pack of carpet seeds" + desc = "These seeds grow into stylish carpet samples." + icon_state = "seed-carpet" + species = "carpet" + plantname = "Carpet" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/grass/carpet + mutatelist = list() + rarity = 10 + +/obj/item/weapon/reagent_containers/food/snacks/grown/grass/carpet + seed = /obj/item/seeds/grass/carpet + name = "carpet" + desc = "The textile industry's dark secret." + icon_state = "carpetclump" + stacktype = /obj/item/stack/tile/carpet diff --git a/code/modules/hydroponics/grown/herbals.dm b/code/modules/hydroponics/grown/herbals.dm new file mode 100644 index 00000000000..f47d84a8edd --- /dev/null +++ b/code/modules/hydroponics/grown/herbals.dm @@ -0,0 +1,53 @@ +/obj/item/seeds/comfrey + name = "pack of comfrey seeds" + desc = "These seeds grow into comfrey." + icon_state = "seed-cabbage" + species = "cabbage" + plantname = "comfrey" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/comfrey + yield = 2 + maturation = 3 + growthstages = 1 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + reagents_add = list("styptic_powder" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey + seed = /obj/item/seeds/comfrey + name = "comfrey leaf" + desc = "Mash to turn into a poultice." + icon_state = "tea_astra_leaves" + color = "#378C61" + bitesize_mod = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey/attack_self(mob/user) + var/obj/item/stack/medical/bruise_pack/comfrey/C = new(get_turf(user)) + C.heal_brute = seed.potency + to_chat(user, "You mash [src] into a poultice.") + user.drop_item() + qdel(src) + +/obj/item/seeds/aloe + name = "pack of aloe seeds" + desc = "These seeds grow into aloe vera plant." + icon_state = "seed-ambrosiavulgaris" + species = "ambrosiavulgaris" + plantname = "Aloe Vera Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/aloe + yield = 2 + icon_dead = "ambrosia-dead" + reagents_add = list("silver_sulfadiazine" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/aloe + seed = /obj/item/seeds/aloe + name = "aloe leaf" + desc = "Mash to turn into a poultice." + icon_state = "ambrosiavulgaris" + color = "#4CC5C7" + bitesize_mod = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grown/aloe/attack_self(mob/user) + var/obj/item/stack/medical/ointment/aloe/A = new(get_turf(user)) + A.heal_burn = seed.potency + to_chat(user, "You mash [src] into a poultice.") + user.drop_item() + qdel(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/kudzu.dm b/code/modules/hydroponics/grown/kudzu.dm new file mode 100644 index 00000000000..e62d2df093e --- /dev/null +++ b/code/modules/hydroponics/grown/kudzu.dm @@ -0,0 +1,97 @@ +// A very special plant, deserving it's own file. + +/obj/item/seeds/kudzu + name = "pack of kudzu seeds" + desc = "These seeds grow into a weed that grows incredibly fast." + icon_state = "seed-kudzu" + species = "kudzu" + plantname = "Kudzu" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod + genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/plant_type/weed_hardy) + lifespan = 20 + endurance = 10 + yield = 4 + growthstages = 4 + rarity = 30 + var/list/mutations = list() + reagents_add = list("charcoal" = 0.04, "plantmatter" = 0.02) + +/obj/item/seeds/kudzu/Copy() + var/obj/item/seeds/kudzu/S = ..() + S.mutations = mutations.Copy() + return S + +/obj/item/seeds/kudzu/suicide_act(mob/user) + user.visible_message("[user] swallows the pack of kudzu seeds! It looks like \he's trying to commit suicide..") + plant(user) + return (BRUTELOSS) + +/obj/item/seeds/kudzu/proc/plant(mob/user) + if(istype(user.loc, /turf/space)) + return + var/turf/T = get_turf(src) + message_admins("Kudzu planted by [key_name_admin(user)](?) (FLW) at ([T.x],[T.y],[T.z] - (JMP))",0,1) + investigate_log("was planted by [key_name(user)] at ([T.x],[T.y],[T.z])","kudzu") + new /obj/effect/spacevine_controller(user.loc, mutations, potency, production) + user.drop_item() + qdel(src) + +/obj/item/seeds/kudzu/attack_self(mob/user) + plant(user) + to_chat(user, "You plant the kudzu. You monster.") + +/obj/item/seeds/kudzu/get_analyzer_text() + var/text = ..() + var/text_string = "" + for(var/datum/spacevine_mutation/SM in mutations) + text_string += "[(text_string == "") ? "" : ", "][SM.name]" + text += "\n- Plant Mutations: [(text_string == "") ? "None" : text_string]" + return text + +/obj/item/seeds/kudzu/on_chem_reaction(datum/reagents/S) + var/list/temp_mut_list = list() + + if(S.has_reagent("sterilizine", 5)) + for(var/datum/spacevine_mutation/SM in mutations) + if(SM.quality == NEGATIVE) + temp_mut_list += SM + if(prob(20) && temp_mut_list.len) + mutations.Remove(pick(temp_mut_list)) + temp_mut_list.Cut() + + if(S.has_reagent("welding_fuel", 5)) + for(var/datum/spacevine_mutation/SM in mutations) + if(SM.quality == POSITIVE) + temp_mut_list += SM + if(prob(20) && temp_mut_list.len) + mutations.Remove(pick(temp_mut_list)) + temp_mut_list.Cut() + + if(S.has_reagent("phenol", 5)) + for(var/datum/spacevine_mutation/SM in mutations) + if(SM.quality == MINOR_NEGATIVE) + temp_mut_list += SM + if(prob(20) && temp_mut_list.len) + mutations.Remove(pick(temp_mut_list)) + temp_mut_list.Cut() + + if(S.has_reagent("blood", 15)) + adjust_production(rand(15, -5)) + + if(S.has_reagent("amanitin", 5)) + adjust_production(rand(5, -15)) + + if(S.has_reagent("plasma", 5)) + adjust_potency(rand(5, -15)) + + if(S.has_reagent("holywater", 10)) + adjust_potency(rand(15, -5)) + + +/obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod + seed = /obj/item/seeds/kudzu + name = "kudzu pod" + desc = "Pueraria Virallis: An invasive species with vines that rapidly creep and wrap around whatever they contact." + icon_state = "kudzupod" + filling_color = "#6B8E23" + bitesize_mod = 2 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm new file mode 100644 index 00000000000..5a229148a17 --- /dev/null +++ b/code/modules/hydroponics/grown/melon.dm @@ -0,0 +1,47 @@ +// Watermelon +/obj/item/seeds/watermelon + name = "pack of watermelon seeds" + desc = "These seeds grow into watermelon plants." + icon_state = "seed-watermelon" + species = "watermelon" + plantname = "Watermelon Vines" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon + lifespan = 50 + endurance = 40 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_dead = "watermelon-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/watermelon/holy) + reagents_add = list("water" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.2) + +/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon + seed = /obj/item/seeds/watermelon + name = "watermelon" + desc = "It's full of watery goodness." + icon_state = "watermelon" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/watermelonslice + slices_num = 5 + dried_type = null + w_class = 3 + filling_color = "#008000" + bitesize_mod = 3 + +// Holymelon +/obj/item/seeds/watermelon/holy + name = "pack of holymelon seeds" + desc = "These seeds grow into holymelon plants." + icon_state = "seed-holymelon" + species = "holymelon" + plantname = "Holy Melon Vines" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/holymelon + mutatelist = list() + reagents_add = list("holywater" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/holymelon + seed = /obj/item/seeds/watermelon/holy + name = "holymelon" + desc = "The water within this melon has been blessed by some deity that's particularly fond of watermelon." + icon_state = "holymelon" + filling_color = "#FFD700" + dried_type = null diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm new file mode 100644 index 00000000000..2e05e3f18a0 --- /dev/null +++ b/code/modules/hydroponics/grown/misc.dm @@ -0,0 +1,139 @@ +// Weeds +/obj/item/seeds/weeds + name = "pack of weed seeds" + desc = "Yo mang, want some weeds?" + icon_state = "seed" + species = "weeds" + plantname = "Starthistle" + lifespan = 100 + endurance = 50 // damm pesky weeds + maturation = 5 + production = 1 + yield = -1 + potency = -1 + growthstages = 4 + genes = list(/datum/plant_gene/trait/plant_type/weed_hardy) + + +// Cabbage +/obj/item/seeds/cabbage + name = "pack of cabbage seeds" + desc = "These seeds grow into cabbages." + icon_state = "seed-cabbage" + species = "cabbage" + plantname = "Cabbages" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage + lifespan = 50 + endurance = 25 + maturation = 3 + production = 5 + yield = 4 + growthstages = 1 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/replicapod) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage + seed = /obj/item/seeds/cabbage + name = "cabbage" + desc = "Ewwwwwwwwww. Cabbage." + icon_state = "cabbage" + filling_color = "#90EE90" + bitesize_mod = 2 + + +// Sugarcane +/obj/item/seeds/sugarcane + name = "pack of sugarcane seeds" + desc = "These seeds grow into sugarcane." + icon_state = "seed-sugarcane" + species = "sugarcane" + plantname = "Sugarcane" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/sugarcane + genes = list(/datum/plant_gene/trait/repeated_harvest) + lifespan = 60 + endurance = 50 + maturation = 3 + yield = 4 + growthstages = 3 + reagents_add = list("sugar" = 0.25) + +/obj/item/weapon/reagent_containers/food/snacks/grown/sugarcane + seed = /obj/item/seeds/sugarcane + name = "sugarcane" + desc = "Sickly sweet." + icon_state = "sugarcane" + filling_color = "#FFD700" + bitesize_mod = 2 + + +// Gatfruit +/obj/item/seeds/gatfruit + name = "pack of gatfruit seeds" + desc = "These seeds grow into .357 revolvers." + icon_state = "seed-gatfruit" + species = "gatfruit" + plantname = "Gatfruit Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/shell/gatfruit + genes = list(/datum/plant_gene/trait/repeated_harvest) + lifespan = 20 + endurance = 20 + maturation = 40 + production = 10 + yield = 2 + potency = 60 + growthstages = 2 + rarity = 60 // Obtainable only with xenobio+superluck. + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + reagents_add = list("sulfur" = 0.1, "carbon" = 0.1, "nitrogen" = 0.07, "potassium" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/shell/gatfruit + seed = /obj/item/seeds/gatfruit + name = "gatfruit" + desc = "It smells like burning." + icon_state = "gatfruit" + origin_tech = "combat=6" + trash = /obj/item/weapon/gun/projectile/revolver + bitesize_mod = 2 + +//Cherry Bombs +/obj/item/seeds/cherry/bomb + name = "pack of cherry bomb pits" + desc = "They give you vibes of dread and frustration." + icon_state = "seed-cherry_bomb" + species = "cherry_bomb" + plantname = "Cherry Bomb Tree" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb + mutatelist = list() + reagents_add = list("plantmatter" = 0.1, "sugar" = 0.1, "blackpowder" = 0.7) + rarity = 60 //See above + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb + name = "cherry bombs" + desc = "You think you can hear the hissing of a tiny fuse." + icon_state = "cherry_bomb" + filling_color = rgb(20, 20, 20) + seed = /obj/item/seeds/cherry/bomb + bitesize_mod = 2 + volume = 125 //Gives enough room for the black powder at max potency + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/attack_self(mob/living/user) + var/area/A = get_area(user) + user.visible_message("[user] plucks the stem from [src]!", "You pluck the stem from [src], which begins to hiss loudly!") + message_admins("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x], [user.y], [user.z]) (JMP)") + log_game("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x],[user.y],[user.z]).") + prime() + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/burn() + prime() + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/ex_act(severity) + qdel(src) //Ensuring that it's deleted by its own explosion. Also prevents mass chain reaction with piles of cherry bombs + +/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/proc/prime() + icon_state = "cherry_bomb_lit" + playsound(src, 'sound/goonstation/misc/fuse.ogg', seed.potency, 0) + reagents.chem_temp = 1000 //Sets off the black powder + reagents.handle_reactions() diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm new file mode 100644 index 00000000000..346e8344ca9 --- /dev/null +++ b/code/modules/hydroponics/grown/mushrooms.dm @@ -0,0 +1,294 @@ +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom + name = "mushroom" + bitesize_mod = 2 + + +// Reishi +/obj/item/seeds/reishi + name = "pack of reishi mycelium" + desc = "This mycelium grows into something medicinal and relaxing." + icon_state = "mycelium-reishi" + species = "reishi" + plantname = "Reishi" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi + lifespan = 35 + endurance = 35 + maturation = 10 + production = 5 + yield = 4 + potency = 15 + growthstages = 4 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + reagents_add = list("morphine" = 0.35, "charcoal" = 0.35, "nutriment" = 0) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi + seed = /obj/item/seeds/reishi + name = "reishi" + desc = "Ganoderma lucidum: A special fungus known for its medicinal and stress relieving properties." + icon_state = "reishi" + filling_color = "#FF4500" + + +// Fly Amanita +/obj/item/seeds/amanita + name = "pack of fly amanita mycelium" + desc = "This mycelium grows into something horrible." + icon_state = "mycelium-amanita" + species = "amanita" + plantname = "Fly Amanitas" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita + lifespan = 50 + endurance = 35 + maturation = 10 + production = 5 + yield = 4 + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + mutatelist = list(/obj/item/seeds/angel) + reagents_add = list("psilocybin" = 0.04, "amanitin" = 0.35, "nutriment" = 0, "growthserum" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita + seed = /obj/item/seeds/amanita + name = "fly amanita" + desc = "Amanita Muscaria: Learn poisonous mushrooms by heart. Only pick mushrooms you know." + icon_state = "amanita" + filling_color = "#FF0000" + + +// Destroying Angel +/obj/item/seeds/angel + name = "pack of destroying angel mycelium" + desc = "This mycelium grows into something devastating." + icon_state = "mycelium-angel" + species = "angel" + plantname = "Destroying Angels" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/angel + lifespan = 50 + endurance = 35 + maturation = 12 + production = 5 + yield = 2 + potency = 35 + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + reagents_add = list("psilocybin" = 0.04, "nutriment" = 0, "amanitin" = 0.3) + rarity = 30 + origin_tech = "biotech=5" + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/angel + seed = /obj/item/seeds/angel + name = "destroying angel" + desc = "Amanita Virosa: Deadly poisonous basidiomycete fungus filled with alpha amatoxins." + icon_state = "angel" + filling_color = "#C0C0C0" + + +// Liberty Cap +/obj/item/seeds/liberty + name = "pack of liberty-cap mycelium" + desc = "This mycelium grows into liberty-cap mushrooms." + icon_state = "mycelium-liberty" + species = "liberty" + plantname = "Liberty-Caps" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap + maturation = 7 + production = 1 + yield = 5 + potency = 15 + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + reagents_add = list("psilocybin" = 0.25, "nutriment" = 0.02) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap + seed = /obj/item/seeds/liberty + name = "liberty-cap" + desc = "Psilocybe Semilanceata: Liberate yourself!" + icon_state = "libertycap" + filling_color = "#DAA520" + + +// Plump Helmet +/obj/item/seeds/plump + name = "pack of plump-helmet mycelium" + desc = "This mycelium grows into helmets... maybe." + icon_state = "mycelium-plump" + species = "plump" + plantname = "Plump-Helmet Mushrooms" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet + maturation = 8 + production = 1 + yield = 4 + potency = 15 + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + mutatelist = list(/obj/item/seeds/plump/walkingmushroom) + reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet + seed = /obj/item/seeds/plump + name = "plump-helmet" + desc = "Plumus Hellmus: Plump, soft and s-so inviting~" + icon_state = "plumphelmet" + filling_color = "#9370DB" + + +// Walking Mushroom +/obj/item/seeds/plump/walkingmushroom + name = "pack of walking mushroom mycelium" + desc = "This mycelium will grow into huge stuff!" + icon_state = "mycelium-walkingmushroom" + species = "walkingmushroom" + plantname = "Walking Mushrooms" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom + lifespan = 30 + endurance = 30 + maturation = 5 + yield = 1 + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + mutatelist = list() + reagents_add = list("vitamin" = 0.05, "nutriment" = 0.15) + rarity = 30 + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom + seed = /obj/item/seeds/plump/walkingmushroom + name = "walking mushroom" + desc = "Plumus Locomotus: The beginning of the great walk." + icon_state = "walkingmushroom" + filling_color = "#9370DB" + origin_tech = "biotech=4;programming=5" + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user) + if(istype(user.loc, /turf/space)) + return + var/mob/living/simple_animal/hostile/mushroom/M = new /mob/living/simple_animal/hostile/mushroom(user.loc) + M.maxHealth += round(seed.endurance / 4) + M.melee_damage_lower += round(seed.potency / 20) + M.melee_damage_upper += round(seed.potency / 20) + M.move_to_delay -= round(seed.production / 50) + M.health = M.maxHealth + qdel(src) + to_chat(user, "You plant the walking mushroom.") + + +// Chanterelle +/obj/item/seeds/chanter + name = "pack of chanterelle mycelium" + desc = "This mycelium grows into chanterelle mushrooms." + icon_state = "mycelium-chanter" + species = "chanter" + plantname = "Chanterelle Mushrooms" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle + lifespan = 35 + endurance = 20 + maturation = 7 + production = 1 + yield = 5 + potency = 15 + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + reagents_add = list("nutriment" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle + seed = /obj/item/seeds/chanter + name = "chanterelle cluster" + desc = "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!" + icon_state = "chanterelle" + filling_color = "#FFA500" + + +// Glowshroom +/obj/item/seeds/glowshroom + name = "pack of glowshroom mycelium" + desc = "This mycelium -glows- into mushrooms!" + icon_state = "mycelium-glowshroom" + species = "glowshroom" + plantname = "Glowshrooms" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom + lifespan = 100 //ten times that is the delay + endurance = 30 + maturation = 15 + production = 1 + yield = 3 //-> spread + potency = 30 //-> brightness + growthstages = 4 + rarity = 20 + genes = list(/datum/plant_gene/trait/glow, /datum/plant_gene/trait/plant_type/fungal_metabolism) + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + mutatelist = list(/obj/item/seeds/glowshroom/glowcap) + reagents_add = list("radium" = 0.1, "phosphorus" = 0.1, "nutriment" = 0.04) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom + seed = /obj/item/seeds/glowshroom + name = "glowshroom cluster" + desc = "Mycena Bregprox: This species of mushroom glows in the dark." + icon_state = "glowshroom" + filling_color = "#00FA9A" + var/effect_path = /obj/effect/glowshroom + origin_tech = "biotech=4;plasmatech=6" + light_color = "#006622" + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user) + if(istype(user.loc, /turf/space)) + return + var/obj/effect/glowshroom/planted = new effect_path(user.loc) + planted.delay = planted.delay - seed.production * 100 //So the delay goes DOWN with better stats instead of up. :I + planted.endurance = seed.endurance + planted.yield = seed.yield + planted.potency = seed.potency + to_chat(user, "You plant [src].") + qdel(src) + + +// Glowcap +/obj/item/seeds/glowshroom/glowcap + name = "pack of glowcap mycelium" + desc = "This mycelium -powers- into mushrooms!" + icon_state = "mycelium-glowcap" + species = "glowcap" + icon_grow = "glowshroom-grow" + icon_dead = "glowshroom-dead" + plantname = "Glowcaps" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap + genes = list(/datum/plant_gene/trait/glow, /datum/plant_gene/trait/cell_charge, /datum/plant_gene/trait/plant_type/fungal_metabolism) + mutatelist = list() + reagents_add = list("teslium" = 0.1, "nutriment" = 0.04) + rarity = 30 + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap + seed = /obj/item/seeds/glowshroom/glowcap + name = "glowcap cluster" + desc = "Mycena Ruthenia: This species of mushroom glows in the dark, but aren't bioluminescent. They're warm to the touch..." + icon_state = "glowcap" + filling_color = "#00FA9A" + effect_path = /obj/effect/glowshroom/glowcap + origin_tech = "biotech=4;powerstorage=6;plasmatech=4" + light_color = "#8E0300" + +// Fungus/Mold +/obj/item/seeds/fungus + name = "pack of fungus spores" + desc = "These spores grow into fungus." + icon_state = "mycelium-tower" + species = "mold" + plantname = "Fungus" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/fungus + yield = 4 + icon_grow = "mold-grow" + icon_dead = "mold-dead" + icon_harvest = "mold-harvest" + growthstages = 3 + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + reagents_add = list("fungus" = 0.35) + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/fungus + seed = /obj/item/seeds/fungus + name = "fungus" + desc = "A fungus ideal for making antibacterials." + icon_state = "angel" + color = "#4f4331" diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm new file mode 100644 index 00000000000..f6d9be51b4a --- /dev/null +++ b/code/modules/hydroponics/grown/nettle.dm @@ -0,0 +1,113 @@ +/obj/item/seeds/nettle + name = "pack of nettle seeds" + desc = "These seeds grow into nettles." + icon_state = "seed-nettle" + species = "nettle" + plantname = "Nettles" + product = /obj/item/weapon/grown/nettle/basic + lifespan = 30 + endurance = 40 // tuff like a toiger + yield = 4 + growthstages = 5 + genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/plant_type/weed_hardy) + mutatelist = list(/obj/item/seeds/nettle/death) + reagents_add = list("sacid" = 0.5) + +/obj/item/seeds/nettle/death + name = "pack of death-nettle seeds" + desc = "These seeds grow into death-nettles." + icon_state = "seed-deathnettle" + species = "deathnettle" + plantname = "Death Nettles" + product = /obj/item/weapon/grown/nettle/death + endurance = 25 + maturation = 8 + yield = 2 + genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/plant_type/weed_hardy, /datum/plant_gene/trait/stinging) + mutatelist = list() + reagents_add = list("facid" = 0.5, "sacid" = 0.5) + rarity = 20 + +/obj/item/weapon/grown/nettle //abstract type + name = "nettle" + desc = "It's probably not wise to touch it with bare hands..." + icon = 'icons/obj/weapons.dmi' + icon_state = "nettle" + damtype = "fire" + force = 15 + hitsound = 'sound/weapons/bladeslice.ogg' + throwforce = 5 + w_class = 1 + throw_speed = 1 + throw_range = 3 + origin_tech = "combat=3" + attack_verb = list("stung") + +/obj/item/weapon/grown/nettle/suicide_act(mob/user) + user.visible_message("[user] is eating some of the [src.name]! It looks like \he's trying to commit suicide.") + return (BRUTELOSS|TOXLOSS) + +/obj/item/weapon/grown/nettle/pickup(mob/living/user) + ..() + if(!ishuman(user)) + return 0 + var/mob/living/carbon/human/H = user + if(H.gloves) + return 0 + var/organ = ((H.hand ? "l_":"r_") + "arm") + var/obj/item/organ/external/affecting = H.get_organ(organ) + if(affecting) + if(affecting.take_damage(0, force)) + H.UpdateDamageIcon() + to_chat(H, "The nettle burns your bare hand!") + return 1 + + + +/obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user,proximity) + if(!proximity) + return + if(force > 0) + force -= rand(1, (force / 3) + 1) // When you whack someone with it, leaves fall off + else + to_chat(usr, "All the leaves have fallen off the nettle from violent whacking.") + usr.unEquip(src) + qdel(src) + +/obj/item/weapon/grown/nettle/basic + seed = /obj/item/seeds/nettle + +/obj/item/weapon/grown/nettle/basic/add_juice() + ..() + force = round((5 + seed.potency / 5), 1) + +/obj/item/weapon/grown/nettle/death + seed = /obj/item/seeds/nettle/death + name = "deathnettle" + desc = "The glowing nettle incites rage in you just from looking at it!" + icon_state = "deathnettle" + force = 30 + throwforce = 15 + origin_tech = "combat=5" + +/obj/item/weapon/grown/nettle/death/add_juice() + ..() + force = round((5 + seed.potency / 2.5), 1) + +/obj/item/weapon/grown/nettle/death/pickup(mob/living/carbon/user) + if(..()) + if(prob(50)) + user.Paralyse(5) + to_chat(user, "You are stunned by the Deathnettle when you try picking it up!") + +/obj/item/weapon/grown/nettle/death/attack(mob/living/carbon/M, mob/user) + ..() + if(isliving(M)) + to_chat(M, "You are stunned by the powerful acid of the Deathnettle!") + add_logs(user, M, "attacked", src) + + M.AdjustEyeBlurry(force/7) + if(prob(20)) + M.Paralyse(force / 6) + M.Weaken(force / 15) + M.drop_item() diff --git a/code/modules/hydroponics/grown/nymph.dm b/code/modules/hydroponics/grown/nymph.dm new file mode 100644 index 00000000000..acea5497fea --- /dev/null +++ b/code/modules/hydroponics/grown/nymph.dm @@ -0,0 +1,26 @@ +/obj/item/seeds/nymph + name = "pack of diona nymph seeds" + desc = "These seeds grow into diona nymphs." + icon_state = "seed-replicapod" + species = "replicapod" + plantname = "Nymph Pod" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/nymph_pod + lifespan = 50 + endurance = 8 + maturation = 10 + production = 1 + yield = 1 + reagents_add = list("plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/nymph_pod + seed = /obj/item/seeds/nymph + name = "nymph pod" + desc = "A peculiar wriggling pod with a grown nymph inside. Crack it open to let the nymph out." + icon_state = "mushy" + bitesize_mod = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grown/nymph_pod/attack_self(mob/user) + new /mob/living/simple_animal/diona(get_turf(user)) + to_chat(user, "You crack open [src] letting the nymph out.") + user.drop_item() + qdel(src) \ No newline at end of file diff --git a/code/modules/hydroponics/grown/peanut.dm b/code/modules/hydroponics/grown/peanut.dm new file mode 100644 index 00000000000..146c1ecfacf --- /dev/null +++ b/code/modules/hydroponics/grown/peanut.dm @@ -0,0 +1,25 @@ +// Peanuts +/obj/item/seeds/peanuts + name = "pack of peanut seeds" + desc = "These seeds grow into peanuts." + icon_state = "seed-potato" + species = "potato" + plantname = "Peanut Vines" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/peanuts + lifespan = 30 + maturation = 10 + production = 1 + yield = 4 + growthstages = 4 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "potato-grow" + icon_dead = "potato-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + reagents_add = list("plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/peanuts + seed = /obj/item/seeds/peanuts + name = "patch of peanuts" + desc = "Best avoided if you have spess allergies." + icon_state = "peanuts" + gender = PLURAL \ No newline at end of file diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm new file mode 100644 index 00000000000..5335346b713 --- /dev/null +++ b/code/modules/hydroponics/grown/potato.dm @@ -0,0 +1,65 @@ +// Potato +/obj/item/seeds/potato + name = "pack of potato seeds" + desc = "Boil 'em! Mash 'em! Stick 'em in a stew!" + icon_state = "seed-potato" + species = "potato" + plantname = "Potato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/potato + lifespan = 30 + maturation = 10 + production = 1 + yield = 4 + growthstages = 4 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_grow = "potato-grow" + icon_dead = "potato-dead" + genes = list(/datum/plant_gene/trait/battery) + mutatelist = list(/obj/item/seeds/potato/sweet) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/potato + seed = /obj/item/seeds/potato + name = "potato" + desc = "Boil 'em! Mash 'em! Stick 'em in a stew!" + icon_state = "potato" + filling_color = "#E9967A" + bitesize = 100 + + +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges + name = "potato wedges" + desc = "Slices of neatly cut potato." + icon_state = "potato_wedges" + filling_color = "#E9967A" + bitesize = 100 + + +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W, mob/user, params) + if(is_sharp(W)) + to_chat(user, "You cut the potato into wedges with [W].") + var/obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges/Wedges = new /obj/item/weapon/reagent_containers/food/snacks/grown/potato/wedges + if(!remove_item_from_storage(user)) + user.unEquip(src) + user.put_in_hands(Wedges) + qdel(src) + else + return ..() + + +// Sweet Potato +/obj/item/seeds/potato/sweet + name = "pack of sweet potato seeds" + desc = "These seeds grow into sweet potato plants." + icon_state = "seed-sweetpotato" + species = "sweetpotato" + plantname = "Sweet Potato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet + mutatelist = list() + reagents_add = list("vitamin" = 0.1, "sugar" = 0.1, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet + seed = /obj/item/seeds/potato/sweet + name = "sweet potato" + desc = "It's sweet." + icon_state = "sweetpotato" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm new file mode 100644 index 00000000000..93da0b28fac --- /dev/null +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -0,0 +1,54 @@ +// Pumpkin +/obj/item/seeds/pumpkin + name = "pack of pumpkin seeds" + desc = "These seeds grow into pumpkin vines." + icon_state = "seed-pumpkin" + species = "pumpkin" + plantname = "Pumpkin Vines" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin + lifespan = 50 + endurance = 40 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "pumpkin-grow" + icon_dead = "pumpkin-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/pumpkin/blumpkin) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.2) + +/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin + seed = /obj/item/seeds/pumpkin + name = "pumpkin" + desc = "It's large and scary." + icon_state = "pumpkin" + filling_color = "#FFA500" + bitesize_mod = 2 + +/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(is_sharp(W)) + user.show_message("You carve a face into [src]!", 1) + new /obj/item/clothing/head/hardhat/pumpkinhead(user.loc) + qdel(src) + return + else + return ..() + +// Blumpkin +/obj/item/seeds/pumpkin/blumpkin + name = "pack of blumpkin seeds" + desc = "These seeds grow into blumpkin vines." + icon_state = "seed-blumpkin" + species = "blumpkin" + plantname = "Blumpkin Vines" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin + mutatelist = list() + reagents_add = list("ammonia" = 0.2, "chlorine" = 0.1, "plasma" = 0.1, "plantmatter" = 0.2) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin + seed = /obj/item/seeds/pumpkin/blumpkin + name = "blumpkin" + desc = "The pumpkin's toxic sibling." + icon_state = "blumpkin" + filling_color = "#87CEFA" + bitesize_mod = 2 diff --git a/code/modules/hydroponics/grown/random.dm b/code/modules/hydroponics/grown/random.dm new file mode 100644 index 00000000000..1f48f83c9a5 --- /dev/null +++ b/code/modules/hydroponics/grown/random.dm @@ -0,0 +1,29 @@ +//Random seeds; stats, traits, and plant type are randomized for each seed. + +/obj/item/seeds/random + name = "pack of strange seeds" + desc = "Mysterious seeds as strange as their name implies. Spooky" + icon_state = "seed-x" + species = "?????" + plantname = "strange plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/random + icon_grow = "xpod-grow" + icon_dead = "xpod-dead" + icon_harvest = "xpod-harvest" + growthstages = 4 + +/obj/item/seeds/random/New() + randomize_stats() + ..() + if(prob(60)) + add_random_reagents() + if(prob(50)) + add_random_traits() + add_random_plant_type(35) + +/obj/item/weapon/reagent_containers/food/snacks/grown/random + seed = /obj/item/seeds/random + name = "strange plant" + desc = "What could this even be?" + icon_state = "crunchy" + bitesize_mod = 2 \ No newline at end of file diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm new file mode 100644 index 00000000000..8b90d28aa67 --- /dev/null +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -0,0 +1,106 @@ +// A very special plant, deserving it's own file. + +/obj/item/seeds/replicapod + name = "pack of replica pod seeds" + desc = "These seeds grow into replica pods. They say these are used to harvest humans." + icon_state = "seed-replicapod" + species = "replicapod" + plantname = "Replica Pod" + product = /mob/living/carbon/human/diona //verrry special -- Urist + lifespan = 50 + endurance = 8 + maturation = 10 + production = 1 + yield = 1 //seeds if there isn't a dna inside + potency = 30 + var/ckey = null + var/realName = null + var/datum/mind/mind = null + var/blood_gender = null + var/blood_type = null + var/factions = null + var/contains_sample = 0 + +/obj/item/seeds/replicapod/Destroy() + mind = null + return ..() + +/obj/item/seeds/replicapod/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W,/obj/item/weapon/reagent_containers/syringe)) + if(!contains_sample) + for(var/datum/reagent/blood/bloodSample in W.reagents.reagent_list) + if(bloodSample.data["mind"] && bloodSample.data["cloneable"] == 1) + mind = bloodSample.data["mind"] + ckey = bloodSample.data["ckey"] + realName = bloodSample.data["real_name"] + blood_gender = bloodSample.data["gender"] + blood_type = bloodSample.data["blood_type"] + factions = bloodSample.data["factions"] + W.reagents.clear_reagents() + to_chat(user, "You inject the contents of the syringe into the seeds.") + contains_sample = 1 + else + to_chat(user, "The seeds reject the sample!") + else + to_chat(user, "The seeds already contain a genetic sample!") + else + return ..() + +/obj/item/seeds/replicapod/get_analyzer_text() + var/text = ..() + if(contains_sample) + text += "\n It contains a blood sample!" + return text + + +/obj/item/seeds/replicapod/harvest(mob/user = usr) //now that one is fun -- Urist + var/obj/machinery/hydroponics/parent = loc + var/make_podman = 0 + var/ckey_holder = null + if(config.revival_pod_plants) + if(ckey) + for(var/mob/M in player_list) + if(isobserver(M)) + var/mob/dead/observer/O = M + if(O.ckey == ckey && O.can_reenter_corpse) + make_podman = 1 + break + else + if(M.ckey == ckey && M.stat == DEAD && !M.suiciding) + make_podman = 1 + break + else //If the player has ghosted from his corpse before blood was drawn, his ckey is no longer attached to the mob, so we need to match up the cloned player through the mind key + for(var/mob/M in player_list) + if(mind && M.mind && ckey(M.mind.key) == ckey(mind.key) && M.ckey && M.client && M.stat == DEAD && !M.suiciding) + if(isobserver(M)) + var/mob/dead/observer/O = M + if(!O.can_reenter_corpse) + break + make_podman = 1 + ckey_holder = M.ckey + break + + if(make_podman) //all conditions met! + var/mob/living/carbon/human/diona/podman = new /mob/living/carbon/human/diona(parent.loc) + if(realName) + podman.real_name = realName + mind.transfer_to(podman) + if(ckey) + podman.ckey = ckey + else + podman.ckey = ckey_holder + podman.gender = blood_gender + podman.faction |= factions + podman.faction |= "plants" + podman.faction |= "vines" //Pod grown Diona are allied with plants and vines alike. + + else //else, one packet of seeds. maybe two + var/seed_count = 1 + if(prob(getYield() * 20)) + seed_count++ + var/output_loc = parent.Adjacent(user) ? user.loc : parent.loc //needed for TK + for(var/i=0,iYou sharpen the carrot into a shiv with [I].
") + var/obj/item/weapon/kitchen/knife/carrotshiv/Shiv = new /obj/item/weapon/kitchen/knife/carrotshiv + if(!remove_item_from_storage(user)) + user.unEquip(src) + user.put_in_hands(Shiv) + qdel(src) + else + return ..() + +// Parsnip +/obj/item/seeds/carrot/parsnip + name = "pack of parsnip seeds" + desc = "These seeds grow into parsnips." + icon_state = "seed-parsnip" + species = "parsnip" + plantname = "Parsnip" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/parsnip + icon_dead = "carrot-dead" + mutatelist = list() + reagents_add = list("vitamin" = 0.05, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/parsnip + seed = /obj/item/seeds/carrot/parsnip + name = "parsnip" + desc = "Closely related to carrots." + icon_state = "parsnip" + bitesize_mod = 2 + + +// White-Beet +/obj/item/seeds/whitebeet + name = "pack of white-beet seeds" + desc = "These seeds grow into sugary beet producing plants." + icon_state = "seed-whitebeet" + species = "whitebeet" + plantname = "White-Beet Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet + lifespan = 60 + endurance = 50 + yield = 6 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_dead = "whitebeet-dead" + mutatelist = list(/obj/item/seeds/redbeet) + reagents_add = list("vitamin" = 0.04, "sugar" = 0.2, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet + seed = /obj/item/seeds/whitebeet + name = "white-beet" + desc = "You can't beat white-beet." + icon_state = "whitebeet" + filling_color = "#F4A460" + bitesize_mod = 2 + +// Red Beet +/obj/item/seeds/redbeet + name = "pack of redbeet seeds" + desc = "These seeds grow into red beet producing plants." + icon_state = "seed-redbeet" + species = "redbeet" + plantname = "Red-Beet Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/redbeet + lifespan = 60 + endurance = 50 + yield = 6 + growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi' + icon_dead = "whitebeet-dead" + genes = list(/datum/plant_gene/trait/maxchem) + reagents_add = list("vitamin" = 0.05, "plantmatter" = 0.05) + +/obj/item/weapon/reagent_containers/food/snacks/grown/redbeet + seed = /obj/item/seeds/redbeet + name = "red beet" + desc = "You can't beat red beet." + icon_state = "redbeet" + bitesize_mod = 2 diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm new file mode 100644 index 00000000000..2f1d6c97bda --- /dev/null +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -0,0 +1,87 @@ +// Tea +/obj/item/seeds/tea + name = "pack of tea aspera seeds" + desc = "These seeds grow into tea plants." + icon_state = "seed-teaaspera" + species = "teaaspera" + plantname = "Tea Aspera Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tea + lifespan = 20 + maturation = 5 + production = 5 + yield = 5 + growthstages = 5 + icon_dead = "tea-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/tea/astra) + reagents_add = list("vitamin" = 0.04, "teapowder" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/tea + seed = /obj/item/seeds/tea + name = "Tea Aspera tips" + desc = "These aromatic tips of the tea plant can be dried to make tea." + icon_state = "tea_aspera_leaves" + filling_color = "#008000" + +// Tea Astra +/obj/item/seeds/tea/astra + name = "pack of tea astra seeds" + icon_state = "seed-teaastra" + species = "teaastra" + plantname = "Tea Astra Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra + mutatelist = list() + reagents_add = list("synaptizine" = 0.1, "vitamin" = 0.04, "teapowder" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra + seed = /obj/item/seeds/tea/astra + name = "Tea Astra tips" + icon_state = "tea_astra_leaves" + filling_color = "#4582B4" + + +// Coffee +/obj/item/seeds/coffee + name = "pack of coffee arabica seeds" + desc = "These seeds grow into coffee arabica bushes." + icon_state = "seed-coffeea" + species = "coffeea" + plantname = "Coffee Arabica Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/coffee + lifespan = 30 + endurance = 20 + maturation = 5 + production = 5 + yield = 5 + growthstages = 5 + icon_dead = "coffee-dead" + genes = list(/datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/coffee/robusta) + reagents_add = list("vitamin" = 0.04, "coffeepowder" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/coffee + seed = /obj/item/seeds/coffee + name = "coffee arabica beans" + desc = "Dry them out to make coffee." + icon_state = "coffee_arabica" + filling_color = "#DC143C" + bitesize_mod = 2 + +// Coffee Robusta +/obj/item/seeds/coffee/robusta + name = "pack of coffee robusta seeds" + desc = "These seeds grow into coffee robusta bushes." + icon_state = "seed-coffeer" + species = "coffeer" + plantname = "Coffee Robusta Bush" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta + mutatelist = list() + reagents_add = list("ephedrine" = 0.1, "vitamin" = 0.04, "coffeepowder" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta + seed = /obj/item/seeds/coffee/robusta + name = "coffee robusta beans" + desc = "Increases robustness by 37 percent!" + icon_state = "coffee_robusta" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/tobacco.dm b/code/modules/hydroponics/grown/tobacco.dm new file mode 100644 index 00000000000..e08f1f0b9f4 --- /dev/null +++ b/code/modules/hydroponics/grown/tobacco.dm @@ -0,0 +1,41 @@ +// Tobacco +/obj/item/seeds/tobacco + name = "pack of tobacco seeds" + desc = "These seeds grow into tobacco plants." + icon_state = "seed-tobacco" + species = "tobacco" + plantname = "Tobacco Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tobacco + lifespan = 20 + maturation = 5 + production = 5 + yield = 10 + growthstages = 3 + icon_dead = "tobacco-dead" + mutatelist = list(/obj/item/seeds/tobacco/space) + reagents_add = list("nicotine" = 0.03, "plantmatter" = 0.03) + +/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco + seed = /obj/item/seeds/tobacco + name = "tobacco leaves" + desc = "Dry them out to make some smokes." + icon_state = "tobacco_leaves" + filling_color = "#008000" + +// Space Tobacco +/obj/item/seeds/tobacco/space + name = "pack of space tobacco seeds" + desc = "These seeds grow into space tobacco plants." + icon_state = "seed-stobacco" + species = "stobacco" + plantname = "Space Tobacco Plant" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tobacco/space + mutatelist = list() + reagents_add = list("salbutamol" = 0.05, "nicotine" = 0.08, "plantmatter" = 0.03) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco/space + seed = /obj/item/seeds/tobacco/space + name = "space tobacco leaves" + desc = "Dry them out to make some space-smokes." + icon_state = "stobacco_leaves" \ No newline at end of file diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm new file mode 100644 index 00000000000..78c3e3dfded --- /dev/null +++ b/code/modules/hydroponics/grown/tomato.dm @@ -0,0 +1,144 @@ +// Tomato +/obj/item/seeds/tomato + name = "pack of tomato seeds" + desc = "These seeds grow into tomato plants." + icon_state = "seed-tomato" + species = "tomato" + plantname = "Tomato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato + maturation = 8 + growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi' + icon_grow = "tomato-grow" + icon_dead = "tomato-dead" + genes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/repeated_harvest) + mutatelist = list(/obj/item/seeds/tomato/blue, /obj/item/seeds/tomato/blood) + reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato + seed = /obj/item/seeds/tomato + name = "tomato" + desc = "I say to-mah-to, you say tom-mae-to." + icon_state = "tomato" + splat_type = /obj/effect/decal/cleanable/tomato_smudge + filling_color = "#FF6347" + bitesize_mod = 2 + +// Blood Tomato +/obj/item/seeds/tomato/blood + name = "pack of blood-tomato seeds" + desc = "These seeds grow into blood-tomato plants." + icon_state = "seed-bloodtomato" + species = "bloodtomato" + plantname = "Blood-Tomato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood + mutatelist = list(/obj/item/seeds/tomato/killer) + reagents_add = list("blood" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood + seed = /obj/item/seeds/tomato/blood + name = "blood-tomato" + desc = "So bloody...so...very...bloody....AHHHH!!!!" + icon_state = "bloodtomato" + splat_type = /obj/effect/gibspawner/generic + filling_color = "#FF0000" + origin_tech = "biotech=5" + + +// Blue Tomato +/obj/item/seeds/tomato/blue + name = "pack of blue-tomato seeds" + desc = "These seeds grow into blue-tomato plants." + icon_state = "seed-bluetomato" + species = "bluetomato" + plantname = "Blue-Tomato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue + yield = 2 + icon_grow = "bluetomato-grow" + mutatelist = list(/obj/item/seeds/tomato/blue/bluespace) + genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) + reagents_add = list("lube" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 20 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue + seed = /obj/item/seeds/tomato/blue + name = "blue-tomato" + desc = "I say blue-mah-to, you say blue-mae-to." + icon_state = "bluetomato" + splat_type = /obj/effect/decal/cleanable/blood/oil + filling_color = "#0000FF" + + +// Bluespace Tomato +/obj/item/seeds/tomato/blue/bluespace + name = "pack of bluespace tomato seeds" + desc = "These seeds grow into bluespace tomato plants." + icon_state = "seed-bluespacetomato" + species = "bluespacetomato" + plantname = "Bluespace Tomato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue/bluespace + yield = 2 + mutatelist = list() + genes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/slip, /datum/plant_gene/trait/teleport, /datum/plant_gene/trait/repeated_harvest) + reagents_add = list("lube" = 0.2, "singulo" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1) + rarity = 50 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue/bluespace + seed = /obj/item/seeds/tomato/blue/bluespace + name = "bluespace tomato" + desc = "So lubricated, you might slip through space-time." + icon_state = "bluespacetomato" + origin_tech = "biotech=4;bluespace=5" + + +// Killer Tomato +/obj/item/seeds/tomato/killer + name = "pack of killer-tomato seeds" + desc = "These seeds grow into killer-tomato plants." + icon_state = "seed-killertomato" + species = "killertomato" + plantname = "Killer-Tomato Plants" + product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer + yield = 2 + genes = list(/datum/plant_gene/trait/squash) + growthstages = 2 + icon_grow = "killertomato-grow" + icon_harvest = "killertomato-harvest" + icon_dead = "killertomato-dead" + mutatelist = list() + reagents_add = list("vitamin" = 0.04, "protein" = 0.1) + rarity = 30 + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer + seed = /obj/item/seeds/tomato/killer + name = "killer-tomato" + desc = "I say to-mah-to, you say tom-mae-to... OH GOD IT'S EATING MY LEGS!!" + icon_state = "killertomato" + var/awakening = 0 + filling_color = "#FF0000" + origin_tech = "biotech=4;combat=5" + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer/attack(mob/M, mob/user, def_zone) + if(awakening) + to_chat(user, "The tomato is twitching and shaking, preventing you from eating it.") + return + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer/attack_self(mob/user) + if(awakening || istype(user.loc, /turf/space)) + return + to_chat(user, "You begin to awaken the Killer Tomato...") + awakening = 1 + + spawn(30) + if(!qdeleted(src)) + var/mob/living/simple_animal/hostile/killertomato/K = new /mob/living/simple_animal/hostile/killertomato(get_turf(loc)) + K.maxHealth += round(seed.endurance / 3) + K.melee_damage_lower += round(seed.potency / 10) + K.melee_damage_upper += round(seed.potency / 10) + K.move_to_delay -= round(seed.production / 50) + K.health = K.maxHealth + K.visible_message("The Killer Tomato growls as it suddenly awakens.") + if(user) + user.unEquip(src) + qdel(src) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm new file mode 100644 index 00000000000..961fe7c4096 --- /dev/null +++ b/code/modules/hydroponics/grown/towercap.dm @@ -0,0 +1,194 @@ +/obj/item/seeds/tower + name = "pack of tower-cap mycelium" + desc = "This mycelium grows into tower-cap mushrooms." + icon_state = "mycelium-tower" + species = "towercap" + plantname = "Tower Caps" + product = /obj/item/weapon/grown/log + lifespan = 80 + endurance = 50 + maturation = 15 + production = 1 + yield = 5 + potency = 50 + growthstages = 3 + growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' + icon_dead = "towercap-dead" + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism) + mutatelist = list(/obj/item/seeds/tower/steel) + +/obj/item/seeds/tower/steel + name = "pack of steel-cap mycelium" + desc = "This mycelium grows into steel logs." + icon_state = "mycelium-steelcap" + species = "steelcap" + plantname = "Steel Caps" + product = /obj/item/weapon/grown/log/steel + mutatelist = list() + rarity = 20 + + + + +/obj/item/weapon/grown/log + seed = /obj/item/seeds/tower + name = "tower-cap log" + desc = "It's better than bad, it's good!" + icon_state = "logs" + force = 5 + throwforce = 5 + w_class = 3 + throw_speed = 2 + throw_range = 3 + origin_tech = "materials=1" + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + var/plank_type = /obj/item/stack/sheet/wood + var/plank_name = "wooden planks" + var/list/accepted = list(/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco, + /obj/item/weapon/reagent_containers/food/snacks/grown/tea, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris, + /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus, + /obj/item/weapon/reagent_containers/food/snacks/grown/wheat) + + +/obj/item/weapon/grown/log/attackby(obj/item/weapon/W, mob/user, params) + if(is_sharp(W)) + user.show_message("You make [plank_name] out of \the [src]!", 1) + var/seed_modifier = 0 + if(seed) + seed_modifier = round(seed.potency / 25) + var/obj/item/stack/plank = new plank_type(user.loc, 1 + seed_modifier) + var/old_plank_amount = plank.amount + for(var/obj/item/stack/ST in user.loc) + if(ST != plank && istype(ST, plank_type) && ST.amount < ST.max_amount) + ST.attackby(plank, user) //we try to transfer all old unfinished stacks to the new stack we created. + if(plank.amount > old_plank_amount) + to_chat(user, "You add the newly-formed [plank_name] to the stack. It now contains [plank.amount] [plank_name].") + qdel(src) + + if(is_type_in_list(W,accepted)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/leaf = W + if(leaf.dry) + user.show_message("You wrap \the [W] around the log, turning it into a torch!") + var/obj/item/device/flashlight/flare/torch/T = new /obj/item/device/flashlight/flare/torch(user.loc) + usr.unEquip(W) + usr.put_in_active_hand(T) + qdel(leaf) + qdel(src) + return + else + to_chat(usr, "You must dry this first!") + else + return ..() + +/obj/item/weapon/grown/log/tree + seed = null + name = "wood log" + desc = "TIMMMMM-BERRRRRRRRRRR!" + +/obj/item/weapon/grown/log/steel + seed = /obj/item/seeds/tower/steel + name = "steel-cap log" + desc = "It's made of metal." + icon_state = "steellogs" + accepted = list() + plank_type = /obj/item/stack/rods + plank_name = "rods" + + +/////////BONFIRES////////// + +/obj/structure/bonfire + name = "bonfire" + desc = "For grilling, broiling, charring, smoking, heating, roasting, toasting, simmering, searing, melting, and occasionally burning things." + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "bonfire" + density = FALSE + anchored = TRUE + buckle_lying = 0 + var/burning = 0 + var/fire_stack_strength = 5 + +/obj/structure/bonfire/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/stack/rods) && !can_buckle) + var/obj/item/stack/rods/R = W + R.use(1) + can_buckle = 1 + buckle_requires_restraints = 1 + to_chat(user, "You add a rod to [src].") + var/image/U = image(icon='icons/obj/hydroponics/equipment.dmi',icon_state="bonfire_rod",pixel_y=16) + underlays += U + if(is_hot(W)) + StartBurning() + + +/obj/structure/bonfire/attack_hand(mob/user) + if(burning) + to_chat(user, "You need to extinguish [src] before removing the logs!") + return + if(!has_buckled_mobs() && do_after(user, 50, target = src)) + for(var/I in 1 to 5) + var/obj/item/weapon/grown/log/L = new /obj/item/weapon/grown/log(loc) + L.pixel_x += rand(1,4) + L.pixel_y += rand(1,4) + qdel(src) + return + ..() + + +/obj/structure/bonfire/proc/CheckOxygen() + var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment + if(G.oxygen > 16) + return 1 + return 0 + +/obj/structure/bonfire/proc/StartBurning() + if(!burning && CheckOxygen()) + icon_state = "bonfire_on_fire" + burning = 1 + set_light(6, l_color = "#ED9200") + Burn() + processing_objects.Add(src) + +/obj/structure/bonfire/fire_act(exposed_temperature, exposed_volume) + StartBurning() + +/obj/structure/bonfire/Crossed(atom/movable/AM) + if(burning) + Burn() + +/obj/structure/bonfire/proc/Burn() + var/turf/current_location = get_turf(src) + current_location.hotspot_expose(1000,500,1) + for(var/A in current_location) + if(A == src) + continue + if(isobj(A)) + var/obj/O = A + O.fire_act(1000, 500) + else if(isliving(A)) + var/mob/living/L = A + L.adjust_fire_stacks(fire_stack_strength) + L.IgniteMob() + +/obj/structure/bonfire/process() + if(!CheckOxygen()) + extinguish() + return + Burn() + +/obj/structure/bonfire/extinguish() + if(burning) + icon_state = "bonfire" + burning = 0 + set_light(0) + processing_objects.Remove(src) + +/obj/structure/bonfire/buckle_mob(mob/living/M, force = 0) + if(..()) + M.pixel_y += 13 + +/obj/structure/bonfire/unbuckle_mob(force=0) + if(buckled_mob) + buckled_mob.pixel_y -= 13 + . = ..() \ No newline at end of file diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm deleted file mode 100644 index 712f368a078..00000000000 --- a/code/modules/hydroponics/grown_inedible.dm +++ /dev/null @@ -1,181 +0,0 @@ -// ********************** -// Other harvested materials from plants (that are not food) -// ********************** - -/obj/item/weapon/grown // Grown weapons - name = "grown_weapon" - icon = 'icons/obj/weapons.dmi' - var/plantname - var/potency = 1 - burn_state = FLAMMABLE - -/obj/item/weapon/grown/New(newloc,planttype) - - ..() - - create_reagents(50) - - //Handle some post-spawn var stuff. - if(planttype) - plantname = planttype - var/datum/seed/S = plant_controller.seeds[plantname] - if(!S || !S.chems) - return - - potency = S.get_trait(TRAIT_POTENCY) - - for(var/rid in S.chems) - var/list/reagent_data = S.chems[rid] - var/rtotal = reagent_data[1] - if(reagent_data.len > 1 && potency > 0) - rtotal += round(potency/reagent_data[2]) - reagents.add_reagent(rid,max(1,rtotal)) - -/obj/item/weapon/grown/nettle //abstract type - name = "nettle" - desc = "It's probably not wise to touch it with bare hands..." - icon = 'icons/obj/weapons.dmi' - icon_state = "nettle" - damtype = "fire" - force = 15 - hitsound = 'sound/weapons/bladeslice.ogg' - throwforce = 5 - w_class = 1 - throw_speed = 1 - throw_range = 3 - origin_tech = "combat=1" - attack_verb = list("stung") - -/obj/item/weapon/grown/nettle/suicide_act(mob/user) - user.visible_message("[user] is eating some of the [src.name]! It looks like \he's trying to commit suicide.") - return (BRUTELOSS|TOXLOSS) - -/obj/item/weapon/grown/nettle/pickup(mob/living/user) - if(!iscarbon(user)) - return 0 - var/mob/living/carbon/C = user - if(ishuman(user)) - var/mob/living/carbon/human/H = C - if(H.gloves) - return 0 - var/organ = ((user.hand ? "l_":"r_") + "arm") - var/obj/item/organ/external/affecting = H.get_organ(organ) - if(affecting.take_damage(0,force)) - user.UpdateDamageIcon() - else - C.take_organ_damage(0,force) - to_chat(C, "The nettle burns your bare hand!") - return 1 - -/obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user,proximity) - if(!proximity) return - if(force > 0) - force -= rand(1, (force / 3) + 1) // When you whack someone with it, leaves fall off - else - to_chat(usr, "All the leaves have fallen off the nettle from violent whacking.") - usr.unEquip(src) - qdel(src) - - -/obj/item/weapon/grown/nettle/death - name = "deathnettle" - desc = "The glowing nettle incites rage in you just from looking at it!" - icon_state = "deathnettle" - force = 30 - throwforce = 15 - origin_tech = "combat=3" - -/obj/item/weapon/grown/nettle/death/pickup(mob/living/carbon/user) - if(..()) - if(prob(50)) - user.Paralyse(5) - to_chat(user, "You are stunned by the Deathnettle when you try picking it up!") - -/obj/item/weapon/grown/nettle/death/afterattack(mob/living/carbon/M, mob/user) - if(istype(M, /mob/living)) - to_chat(M, "You are stunned by the powerful acid of the Deathnettle!") - add_logs(user, M, "attacked", src) - - M.AdjustEyeBlurry(force/7) - if(prob(20)) - M.Paralyse(force / 6) - M.Weaken(force / 15) - M.drop_item() - ..() - -/obj/item/weapon/corncob - name = "corn cob" - desc = "A reminder of meals gone by." - icon = 'icons/obj/trash.dmi' - icon_state = "corncob" - item_state = "corncob" - w_class = 2 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/knife)) - to_chat(user, "You use [W] to fashion a pipe out of the corn cob!") - new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc) - qdel(src) - return - -/obj/item/weapon/bananapeel - name = "banana peel" - desc = "A peel from a banana." - icon = 'icons/obj/items.dmi' - icon_state = "banana_peel" - item_state = "banana_peel" - w_class = 2 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - - -// Sunflower - -/obj/item/weapon/grown/sunflower - name = "sunflower" - desc = "A large, fresh-grown sunflower. How cheery!" - icon = 'icons/obj/harvest.dmi' - icon_state = "sunflower" - item_state = "sunflower" - w_class = 2 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob) - to_chat(M, " [user] smacks you with a [name]!FLOWER POWER") - to_chat(user, " Your [name]'s FLOWER POWER strikes [M]") - - -// Novaflower - -/obj/item/weapon/grown/novaflower - name = "novaflower" - desc = "A large, fresh-grown novaflower. It seems to radiate heat." - icon = 'icons/obj/harvest.dmi' - icon_state = "novaflower" - item_state = "sunflower" - w_class = 2 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M as mob, mob/user as mob) - to_chat(M, "[user] smacks you with a [name]!FLOWER POWER") - to_chat(user, " Your [name]'s FLOWER POWER strikes [M]") - if(istype(M, /mob/living)) - to_chat(M, "You are lit on fire from the intense heat of the [name]!") - M.adjust_fire_stacks(potency / 20) - if(M.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(M)] on fire") - log_game("[key_name(user)] set [key_name(M)] on fire") - -/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user as mob) - if(!user.gloves) - to_chat(user, "The [name] burns your bare hand!") - user.adjustFireLoss(rand(1,5)) diff --git a/code/modules/hydroponics/grown_predefined.dm b/code/modules/hydroponics/grown_predefined.dm deleted file mode 100644 index a7a9254db66..00000000000 --- a/code/modules/hydroponics/grown_predefined.dm +++ /dev/null @@ -1,55 +0,0 @@ -// Predefined types for placing on the map. - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap - plantname = "libertycap" - -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris - plantname = "ambrosia" - -/obj/item/weapon/reagent_containers/food/snacks/grown/potato - plantname = "potato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/tomato - plantname = "tomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer - plantname = "killertomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/carrot - plantname = "carrot" - -/obj/item/weapon/reagent_containers/food/snacks/grown/berries - plantname = "berries" - -/obj/item/weapon/reagent_containers/food/snacks/grown/banana - plantname = "banana" - -/obj/item/weapon/reagent_containers/food/snacks/grown/chili - plantname = "chili" - -/obj/item/weapon/reagent_containers/food/snacks/grown/lemon - plantname = "lemon" - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherries - plantname = "cherry" - -/obj/item/weapon/reagent_containers/food/snacks/grown/orange - plantname = "orange" - -/obj/item/weapon/reagent_containers/food/snacks/grown/corn - plantname = "corn" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita - plantname = "amanita" - -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus - plantname = "ambrosiadeus" - -/obj/item/weapon/reagent_containers/food/snacks/grown/aloe - plantname = "aloe" - -/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey - plantname = "comfrey" - -/obj/item/weapon/reagent_containers/food/snacks/grown/glowcap - plantname = "glowcap" \ No newline at end of file diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm new file mode 100644 index 00000000000..64d2eff90b7 --- /dev/null +++ b/code/modules/hydroponics/growninedible.dm @@ -0,0 +1,61 @@ +// ********************** +// Other harvested materials from plants (that are not food) +// ********************** + +/obj/item/weapon/grown // Grown weapons + name = "grown_weapon" + icon = 'icons/obj/hydroponics/harvest.dmi' + burn_state = FLAMMABLE + var/obj/item/seeds/seed = null // type path, gets converted to item on New(). It's safe to assume it's always a seed item. + +/obj/item/weapon/grown/New(newloc, var/obj/item/seeds/new_seed = null) + ..() + create_reagents(50) + + if(new_seed) + seed = new_seed.Copy() + else if(ispath(seed)) + // This is for adminspawn or map-placed growns. They get the default stats of their seed type. + seed = new seed() + seed.adjust_potency(50-seed.potency) + + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_new(src, newloc) + + if(istype(src, seed.product)) // no adding reagents if it is just a trash item + seed.prepare_result(src) + transform *= TransformUsingVariable(seed.potency, 100, 0.5) + add_juice() + + +/obj/item/weapon/grown/attackby(obj/item/O, mob/user, params) + ..() + if (istype(O, /obj/item/device/plant_analyzer)) + var/msg = "*---------*\n This is \a [src]\n" + if(seed) + msg += seed.get_analyzer_text() + msg += "" + to_chat(usr, msg) + return + +/obj/item/weapon/grown/proc/add_juice() + if(reagents) + return 1 + return 0 + + +/obj/item/weapon/grown/Crossed(atom/movable/AM) + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_cross(src, AM) + ..() + +/obj/item/weapon/grown/throw_impact(atom/hit_atom) + if(!..()) //was it caught by a mob? + if(seed) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_throw_impact(src, hit_atom) \ No newline at end of file diff --git a/code/modules/hydroponics/hydro_reagents.dm b/code/modules/hydroponics/hydro_reagents.dm deleted file mode 100644 index 20d175b2939..00000000000 --- a/code/modules/hydroponics/hydro_reagents.dm +++ /dev/null @@ -1,124 +0,0 @@ - -/obj/item/weapon/plantspray - icon = 'icons/obj/hydroponics_machines.dmi' - item_state = "spray" - flags = OPENCONTAINER | NOBLUDGEON - slot_flags = SLOT_BELT - throwforce = 4 - w_class = 2 - throw_speed = 2 - throw_range = 10 - var/toxicity = 4 - var/pest_kill_str = 0 - var/weed_kill_str = 0 - -/obj/item/weapon/plantspray/weeds // -- Skie - - name = "weed-spray" - desc = "It's a toxic mixture, in spray form, to kill small weeds." - icon_state = "weedspray" - weed_kill_str = 6 - -/obj/item/weapon/plantspray/pests - name = "pest-spray" - desc = "It's some pest eliminator spray! Do not inhale!" - icon_state = "pestspray" - pest_kill_str = 6 - -/obj/item/weapon/plantspray/pests/old - name = "bottle of pestkiller" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - -/obj/item/weapon/plantspray/pests/old/carbaryl - name = "bottle of carbaryl" - toxicity = 4 - pest_kill_str = 2 - -/obj/item/weapon/plantspray/pests/old/lindane - name = "bottle of lindane" - icon_state = "bottle18" - toxicity = 6 - pest_kill_str = 4 - -/obj/item/weapon/plantspray/pests/old/phosmet - name = "bottle of phosmet" - icon_state = "bottle15" - toxicity = 8 - pest_kill_str = 7 - - -// ************************************* -// Weedkiller defines for hydroponics -// ************************************* - -/obj/item/weedkiller - name = "bottle of weedkiller" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - flags = OPENCONTAINER | NOBLUDGEON - var/toxicity = 0 - var/weed_kill_str = 0 - -/obj/item/weedkiller/triclopyr - name = "bottle of glyphosate" - icon = 'icons/obj/chemical.dmi' - toxicity = 4 - weed_kill_str = 2 - -/obj/item/weedkiller/lindane - name = "bottle of triclopyr" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle18" - toxicity = 6 - weed_kill_str = 4 - -/obj/item/weedkiller/D24 - name = "bottle of 2,4-D" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle15" - toxicity = 8 - weed_kill_str = 7 - -// ************************************* -// Nutrient defines for hydroponics -// ************************************* - -/obj/item/weapon/reagent_containers/glass/bottle/fertilizer - name = "fertilizer bottle" - desc = "A small glass bottle. Can hold up to 10 units." - icon = 'icons/obj/chemical.dmi' - icon_state = "round_bottle" - flags = OPENCONTAINER - possible_transfer_amounts = null - w_class = 2 - - var/fertilizer //Reagent contained, if any. - - //Like a shot glass! - amount_per_transfer_from_this = 10 - volume = 10 - -/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/New() - ..() - - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - - if(fertilizer) - reagents.add_reagent(fertilizer,10) - -/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/ez - name = "bottle of E-Z-Nutrient" - icon_state = "round_bottle" - fertilizer = "eznutrient" - -/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/l4z - name = "bottle of Left 4 Zed" - icon_state = "round_bottle" - fertilizer = "left4zed" - -/obj/item/weapon/reagent_containers/glass/bottle/fertilizer/rh - name = "bottle of Robust Harvest" - icon_state = "round_bottle" - fertilizer = "robustharvest" diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm new file mode 100644 index 00000000000..7ff1d4ae0d9 --- /dev/null +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -0,0 +1,215 @@ +// Plant analyzer +/obj/item/device/plant_analyzer + name = "plant analyzer" + desc = "A scanner used to evaluate a plant's various areas of growth." + icon = 'icons/obj/device.dmi' + icon_state = "hydro" + item_state = "analyzer" + w_class = 1 + slot_flags = SLOT_BELT + origin_tech = "magnets=2;biotech=2" + materials = list(MAT_METAL=30, MAT_GLASS=20) + +// ************************************* +// Hydroponics Tools +// ************************************* + +/obj/item/weapon/reagent_containers/spray/weedspray // -- Skie + desc = "It's a toxic mixture, in spray form, to kill small weeds." + icon = 'icons/obj/hydroponics/equipment.dmi' + name = "weed spray" + icon_state = "weedspray" + item_state = "plantbgone" + volume = 100 + flags = OPENCONTAINER + slot_flags = SLOT_BELT + throwforce = 0 + w_class = 2 + throw_speed = 3 + throw_range = 10 + +/obj/item/weapon/reagent_containers/spray/weedspray/New() + ..() + reagents.add_reagent("atrazine", 100) + +/obj/item/weapon/reagent_containers/spray/weedspray/suicide_act(mob/user) + user.visible_message("[user] is huffing the [src.name]! It looks like \he's trying to commit suicide.") + return (TOXLOSS) + +/obj/item/weapon/reagent_containers/spray/pestspray // -- Skie + desc = "It's some pest eliminator spray! Do not inhale!" + icon = 'icons/obj/hydroponics/equipment.dmi' + name = "pest spray" + icon_state = "pestspray" + item_state = "plantbgone" + volume = 100 + flags = OPENCONTAINER + slot_flags = SLOT_BELT + throwforce = 0 + w_class = 2 + throw_speed = 3 + throw_range = 10 + +/obj/item/weapon/reagent_containers/spray/pestspray/New() + ..() + reagents.add_reagent("pestkiller", 100) + +/obj/item/weapon/reagent_containers/spray/pestspray/suicide_act(mob/user) + user.visible_message("[user] is huffing the [src.name]! It looks like \he's trying to commit suicide.") + return (TOXLOSS) + +/obj/item/weapon/cultivator + name = "cultivator" + desc = "It's used for removing weeds or scratching your back." + icon = 'icons/obj/weapons.dmi' + icon_state = "cultivator" + item_state = "cultivator" + origin_tech = "engineering=2;biotech=2" + flags = CONDUCT + force = 5 + throwforce = 7 + w_class = 2 + materials = list(MAT_METAL=50) + attack_verb = list("slashed", "sliced", "cut", "clawed") + hitsound = 'sound/weapons/bladeslice.ogg' + +/obj/item/weapon/hatchet + name = "hatchet" + desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." + icon = 'icons/obj/weapons.dmi' + icon_state = "hatchet" + flags = CONDUCT + force = 12 + w_class = 1 + throwforce = 15 + throw_speed = 3 + throw_range = 4 + materials = list(MAT_METAL = 15000) + origin_tech = "materials=2;combat=2" + attack_verb = list("chopped", "torn", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + sharp = 1 + edge = 1 + +/obj/item/weapon/hatchet/suicide_act(mob/user) + user.visible_message("[user] is chopping at \himself with the [src.name]! It looks like \he's trying to commit suicide.") + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/weapon/hatchet/unathiknife + name = "duelling knife" + desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude." + icon = 'icons/obj/weapons.dmi' + icon_state = "unathiknife" + attack_verb = list("ripped", "torn", "cut") + +/obj/item/weapon/scythe + icon_state = "scythe0" + name = "scythe" + desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." + force = 13 + throwforce = 5 + throw_speed = 2 + throw_range = 3 + w_class = 4 + flags = CONDUCT + armour_penetration = 20 + slot_flags = SLOT_BACK + origin_tech = "materials=3;combat=2" + attack_verb = list("chopped", "sliced", "cut", "reaped") + hitsound = 'sound/weapons/bladeslice.ogg' + sharp = 1 + edge = 1 + +/obj/item/weapon/scythe/suicide_act(mob/user) + user.visible_message("[user] is beheading \himself with the [src.name]! It looks like \he's trying to commit suicide.") + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/affecting = H.get_organ("head") + if(affecting) + affecting.droplimb(1, DROPLIMB_EDGE) + playsound(loc, pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg'), 50, 1, -1) + return (BRUTELOSS) + +// ************************************* +// Nutrient defines for hydroponics +// ************************************* + + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient + name = "bottle of nutrient" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + volume = 50 + w_class = 1 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(1,2,5,10,15,25,50) + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/New() + ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez + name = "bottle of E-Z-Nutrient" + desc = "Contains a fertilizer that causes mild mutations with each harvest." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez/New() + ..() + reagents.add_reagent("eznutriment", 50) + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/l4z + name = "bottle of Left 4 Zed" + desc = "Contains a fertilizer that limits plant yields to no more than one and causes significant mutations in plants." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle18" + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/l4z/New() + ..() + reagents.add_reagent("left4zednutriment", 50) + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh + name = "bottle of Robust Harvest" + desc = "Contains a fertilizer that increases the yield of a plant by 30% while causing no mutations." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle15" + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh/New() + ..() + reagents.add_reagent("robustharvestnutriment", 50) + +/obj/item/weapon/reagent_containers/glass/bottle/nutrient/empty + name = "bottle" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + +/obj/item/weapon/reagent_containers/glass/bottle/killer + name = "bottle" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + volume = 50 + w_class = 1 + amount_per_transfer_from_this = 10 + possible_transfer_amounts = list(1,2,5,10,15,25,50) + +/obj/item/weapon/reagent_containers/glass/bottle/killer/weedkiller + name = "bottle of weed killer" + desc = "Contains a herbicide." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + +/obj/item/weapon/reagent_containers/glass/bottle/killer/weedkiller/New() + ..() + reagents.add_reagent("atrazine", 50) + +/obj/item/weapon/reagent_containers/glass/bottle/killer/pestkiller + name = "bottle of pest spray" + desc = "Contains a pesticide." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle20" + +/obj/item/weapon/reagent_containers/glass/bottle/killer/pestkiller/New() + ..() + reagents.add_reagent("pestkiller", 50) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm new file mode 100644 index 00000000000..5eae76ea446 --- /dev/null +++ b/code/modules/hydroponics/hydroponics.dm @@ -0,0 +1,1016 @@ +/obj/machinery/hydroponics + name = "hydroponics tray" + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "hydrotray" + density = 1 + anchored = 1 + pixel_y = 8 + var/waterlevel = 100 //The amount of water in the tray (max 100) + var/maxwater = 100 //The maximum amount of water in the tray + var/nutrilevel = 10 //The amount of nutrient in the tray (max 10) + var/maxnutri = 10 //The maximum nutrient of water in the tray + var/pestlevel = 0 //The amount of pests in the tray (max 10) + var/weedlevel = 0 //The amount of weeds in the tray (max 10) + var/yieldmod = 1 //Nutriment's effect on yield + var/mutmod = 1 //Nutriment's effect on mutations + var/toxic = 0 //Toxicity in the tray? + var/age = 0 //Current age + var/dead = 0 //Is it dead? + var/plant_health //Its health + var/lastproduce = 0 //Last time it was harvested + var/lastcycle = 0 //Used for timing of cycles. + var/cycledelay = 200 //About 10 seconds / cycle + var/harvest = 0 //Ready to harvest? + var/obj/item/seeds/myseed = null //The currently planted seed + var/rating = 1 + var/wrenchable = 1 + var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpollinate one plant + var/using_irrigation = FALSE //If the tray is connected to other trays via irrigation hoses + var/self_sustaining = FALSE //If the tray generates nutrients and water on its own + hud_possible = list (PLANT_NUTRIENT_HUD, PLANT_WATER_HUD, PLANT_STATUS_HUD, PLANT_HEALTH_HUD, PLANT_TOXIN_HUD, PLANT_PEST_HUD, PLANT_WEED_HUD) + +/obj/machinery/hydroponics/New() + ..() + var/datum/atom_hud/data/hydroponic/hydro_hud = huds[DATA_HUD_HYDROPONIC] + prepare_huds() + hydro_hud.add_to_hud(src) + plant_hud_set_nutrient() + plant_hud_set_water() + plant_hud_set_status() + plant_hud_set_health() + plant_hud_set_toxin() + plant_hud_set_pest() + plant_hud_set_weed() + +/obj/machinery/hydroponics/constructable + name = "hydroponics tray" + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "hydrotray3" + +/obj/machinery/hydroponics/constructable/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/hydroponics(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + RefreshParts() + +/obj/machinery/hydroponics/constructable/RefreshParts() + var/tmp_capacity = 0 + for (var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) + tmp_capacity += M.rating + for (var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + rating = M.rating + maxwater = tmp_capacity * 50 // Up to 300 + maxnutri = tmp_capacity * 5 // Up to 30 + waterlevel = maxwater + nutrilevel = 3 + plant_hud_set_nutrient() + plant_hud_set_water() + +/obj/machinery/hydroponics/Destroy() + if(myseed) + qdel(myseed) + myseed = null + return ..() + +/obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "hydrotray3", "hydrotray3", I)) + return + + if(exchange_parts(user, I)) + return + + if(iscrowbar(I)) + if(using_irrigation) + to_chat(user, "Disconnect the hoses first!") + else if(default_deconstruction_crowbar(I, 1)) + return + else + return ..() + +/obj/machinery/hydroponics/proc/FindConnected() + var/list/connected = list() + var/list/processing_atoms = list(src) + + while(processing_atoms.len) + var/atom/a = processing_atoms[1] + for(var/step_dir in cardinal) + var/obj/machinery/hydroponics/h = locate() in get_step(a, step_dir) + // Soil plots aren't dense + if(h && h.using_irrigation && h.density && !(h in connected) && !(h in processing_atoms)) + processing_atoms += h + + processing_atoms -= a + connected += a + + return connected + + +/obj/machinery/hydroponics/bullet_act(obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables. + if(!myseed) + return ..() + if(istype(Proj ,/obj/item/projectile/energy/floramut)) + mutate() + else if(istype(Proj ,/obj/item/projectile/energy/florayield)) + return myseed.bullet_act(Proj) + else + return ..() + +/obj/machinery/hydroponics/process() + var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time + + if(myseed && (myseed.loc != src)) + myseed.forceMove(src) + + if(self_sustaining) + adjustNutri(1) + adjustWater(rand(3,5)) + adjustWeeds(-2) + adjustPests(-2) + adjustToxic(-2) + + if(world.time > (lastcycle + cycledelay)) + lastcycle = world.time + if(myseed && !dead) + // Advance age + age++ + if(age < myseed.maturation) + lastproduce = age + + needs_update = 1 + +//Nutrients////////////////////////////////////////////////////////////// + // Nutrients deplete slowly + if(prob(50)) + adjustNutri(-1 / rating) + + // Lack of nutrients hurts non-weeds + if(nutrilevel <= 0 && !myseed.get_gene(/datum/plant_gene/trait/plant_type/weed_hardy)) + adjustHealth(-rand(1,3)) + +//Photosynthesis///////////////////////////////////////////////////////// + // Lack of light hurts non-mushrooms + if(isturf(loc)) + var/turf/currentTurf = loc + var/lightAmt = currentTurf.get_lumcount() * 10 + if(myseed.get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) + if(lightAmt < 2) + adjustHealth(-1 / rating) + else // Non-mushroom + if(lightAmt < 4) + adjustHealth(-2 / rating) + +//Water////////////////////////////////////////////////////////////////// + // Drink random amount of water + adjustWater(-rand(1,6) / rating) + + // If the plant is dry, it loses health pretty fast, unless mushroom + if(waterlevel <= 10 && !myseed.get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) + adjustHealth(-rand(0,1) / rating) + if(waterlevel <= 0) + adjustHealth(-rand(0,2) / rating) + + // Sufficient water level and nutrient level = plant healthy but also spawns weeds + else if(waterlevel > 10 && nutrilevel > 0) + adjustHealth(rand(1,2) / rating) + if(myseed && prob(myseed.weed_chance)) + adjustWeeds(myseed.weed_rate) + else if(prob(5)) //5 percent chance the weed population will increase + adjustWeeds(1 / rating) + +//Toxins///////////////////////////////////////////////////////////////// + + // Too much toxins cause harm, but when the plant drinks the contaiminated water, the toxins disappear slowly + if(toxic >= 40 && toxic < 80) + adjustHealth(-1 / rating) + adjustToxic(-rand(1,10) / rating) + else if(toxic >= 80) // I don't think it ever gets here tbh unless above is commented out + adjustHealth(-3) + adjustToxic(-rand(1,10) / rating) + +//Pests & Weeds////////////////////////////////////////////////////////// + + else if(pestlevel >= 5) + adjustHealth(-1 / rating) + + // If it's a weed, it doesn't stunt the growth + if(weedlevel >= 5 && !myseed.get_gene(/datum/plant_gene/trait/plant_type/weed_hardy)) + adjustHealth(-1 / rating) + +//Health & Age/////////////////////////////////////////////////////////// + + // Plant dies if plant_health <= 0 + if(plant_health <= 0) + plantdies() + adjustWeeds(1 / rating) // Weeds flourish + + // If the plant is too old, lose health fast + if(age > myseed.lifespan) + adjustHealth(-rand(1,5) / rating) + + // Harvest code + if(age > myseed.production && (age - lastproduce) > myseed.production && (!harvest && !dead)) + nutrimentMutation() + if(myseed && myseed.yield != -1) // Unharvestable shouldn't be harvested + harvest = 1 + plant_hud_set_status() + else + lastproduce = age + if(prob(5)) // On each tick, there's a 5 percent chance the pest population will increase + adjustPests(1 / rating) + else + if(waterlevel > 10 && nutrilevel > 0 && prob(10)) // If there's no plant, the percentage chance is 10% + adjustWeeds(1 / rating) + + // Weeeeeeeeeeeeeeedddssss + if(weedlevel >= 10 && prob(50)) // At this point the plant is kind of fucked. Weeds can overtake the plant spot. + if(myseed) + if(!myseed.get_gene(/datum/plant_gene/trait/plant_type/weed_hardy) && !myseed.get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) // If a normal plant + weedinvasion() + else + weedinvasion() // Weed invasion into empty tray + needs_update = 1 + if (needs_update) + update_icon() + return + +/obj/machinery/hydroponics/proc/nutrimentMutation() + if (mutmod == 0) + return + if (mutmod == 1) + if(prob(80)) //80% + mutate() + else if(prob(75)) //15% + hardmutate() + return + if (mutmod == 2) + if(prob(50)) //50% + mutate() + else if(prob(50)) //25% + hardmutate() + else if(prob(50)) //12.5% + mutatespecie() + return + return + +/obj/machinery/hydroponics/update_icon() + //Refreshes the icon and sets the luminosity + overlays.Cut() + + if(self_sustaining) + if(istype(src, /obj/machinery/hydroponics/soil)) + color = rgb(255, 175, 0) + else + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing") + set_light(3) + + update_icon_hoses() + + if(myseed) + update_icon_plant() + update_icon_lights() + + if(!self_sustaining) + if(myseed && myseed.get_gene(/datum/plant_gene/trait/glow)) + var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow) + set_light(G.get_lum(myseed)) + else + set_light(0) + + return + +/obj/machinery/hydroponics/proc/update_icon_hoses() + var/n = 0 + for(var/Dir in cardinal) + var/obj/machinery/hydroponics/t = locate() in get_step(src,Dir) + if(t && t.using_irrigation && using_irrigation) + n += Dir + + icon_state = "hoses-[n]" + +/obj/machinery/hydroponics/proc/update_icon_plant() + var/image/I + if(dead) + I = image(icon = myseed.growing_icon, icon_state = myseed.icon_dead) + else if(harvest) + if(!myseed.icon_harvest) + I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][myseed.growthstages]") + else + I = image(icon = myseed.growing_icon, icon_state = myseed.icon_harvest) + else + var/t_growthstate = min(round((age / myseed.maturation) * myseed.growthstages), myseed.growthstages) + I = image(icon = myseed.growing_icon, icon_state = "[myseed.icon_grow][t_growthstate]") + I.layer = OBJ_LAYER + 0.01 + overlays += I + +/obj/machinery/hydroponics/proc/update_icon_lights() + if(waterlevel <= 10) + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowwater3") + if(nutrilevel <= 2) + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lownutri3") + if(plant_health <= (myseed.endurance / 2)) + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_lowhealth3") + if(weedlevel >= 5 || pestlevel >= 5 || toxic >= 40) + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_alert3") + if(harvest) + overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "over_harvest3") + + +/obj/machinery/hydroponics/examine(user) + ..() + if(myseed) + to_chat(user, "It has [myseed.plantname] planted.") + if (dead) + to_chat(user, "It's dead!") + else if (harvest) + to_chat(user, "It's ready to harvest.") + else if (plant_health <= (myseed.endurance / 2)) + to_chat(user, "It looks unhealthy.") + else + to_chat(user, "[src] is empty.") + + if(!self_sustaining) + to_chat(user, "Water: [waterlevel]/[maxwater]") + to_chat(user, "Nutrient: [nutrilevel]/[maxnutri]") + else + to_chat(user, "It doesn't require any water or nutrients.") + + if(weedlevel >= 5) + to_chat(user, "[src] is filled with weeds!") + if(pestlevel >= 5) + to_chat(user, "[src] is filled with tiny worms!") + to_chat(user, "") // Empty line for readability. + + +/obj/machinery/hydroponics/proc/weedinvasion() // If a weed growth is sufficient, this happens. + dead = 0 + var/oldPlantName + if(myseed) // In case there's nothing in the tray beforehand + oldPlantName = myseed.plantname + qdel(myseed) + myseed = null + else + oldPlantName = "empty tray" + switch(rand(1,18)) // randomly pick predominative weed + if(16 to 18) + myseed = new /obj/item/seeds/reishi(src) + if(14 to 15) + myseed = new /obj/item/seeds/nettle(src) + if(12 to 13) + myseed = new /obj/item/seeds/harebell(src) + if(10 to 11) + myseed = new /obj/item/seeds/amanita(src) + if(8 to 9) + myseed = new /obj/item/seeds/chanter(src) + if(6 to 7) + myseed = new /obj/item/seeds/tower(src) + if(4 to 5) + myseed = new /obj/item/seeds/plump(src) + else + myseed = new /obj/item/seeds/weeds(src) + age = 0 + plant_health = myseed.endurance + lastcycle = world.time + harvest = 0 + adjustWeeds(-10) // Reset + adjustPests(-10) // Reset + update_icon() + plant_hud_set_health() + plant_hud_set_status() + visible_message("The [oldPlantName] is overtaken by some [myseed.plantname]!") + + +/obj/machinery/hydroponics/proc/mutate(lifemut = 2, endmut = 5, productmut = 1, yieldmut = 2, potmut = 25, wrmut = 2, wcmut = 5, traitmut = 0) // Mutates the current seed + if(!myseed) + return + myseed.mutate(lifemut, endmut, productmut, yieldmut, potmut, wrmut, wcmut, traitmut) + +/obj/machinery/hydroponics/proc/hardmutate() + mutate(4, 10, 2, 4, 50, 4, 10, 3) + + +/obj/machinery/hydroponics/proc/mutatespecie() // Mutagent produced a new plant! + if(!myseed || dead) + return + + var/oldPlantName = myseed.plantname + if(myseed.mutatelist.len > 0) + var/mutantseed = pick(myseed.mutatelist) + qdel(myseed) + myseed = null + myseed = new mutantseed + else + return + + hardmutate() + age = 0 + plant_health = myseed.endurance + lastcycle = world.time + harvest = 0 + plant_hud_set_health() + plant_hud_set_status() + adjustWeeds(-10) // Reset + + sleep(5) // Wait a while + update_icon() + visible_message("[oldPlantName] suddenly mutates into [myseed.plantname]!") + + +/obj/machinery/hydroponics/proc/mutateweed() // If the weeds gets the mutagent instead. Mind you, this pretty much destroys the old plant + if( weedlevel > 5 ) + if(myseed) + qdel(myseed) + myseed = null + var/newWeed = pick(/obj/item/seeds/liberty, /obj/item/seeds/angel, /obj/item/seeds/nettle/death, /obj/item/seeds/kudzu) + myseed = new newWeed + dead = 0 + hardmutate() + age = 0 + plant_health = myseed.endurance + lastcycle = world.time + harvest = 0 + plant_hud_set_health() + plant_hud_set_status() + adjustWeeds(-10) // Reset + + sleep(5) // Wait a while + update_icon() + visible_message("The mutated weeds in [src] spawn some [myseed.plantname]!") + else + to_chat(usr, "The few weeds in [src] seem to react, but only for a moment...") + + +/obj/machinery/hydroponics/proc/plantdies() // OH NOES!!!!! I put this all in one function to make things easier + plant_health = 0 + harvest = 0 + adjustPests(-10) // Pests die + if(!dead) + update_icon() + dead = 1 + plant_hud_set_health() + plant_hud_set_status() + + + +/obj/machinery/hydroponics/proc/mutatepest(mob/user) + if(pestlevel > 5) + message_admins("[ADMIN_LOOKUPFLW(user)] caused spiderling pests to spawn in a hydro tray") + log_game("[key_name(user)] caused spiderling pests to spawn in a hydro tray") + visible_message("The pests seem to behave oddly...") + for(var/i in 1 to 3) + var/obj/effect/spider/spiderling/S = new(get_turf(src)) + S.grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter + else + to_chat(user, "The pests seem to behave oddly, but quickly settle down...") + +/obj/machinery/hydroponics/proc/applyChemicals(datum/reagents/S, mob/user) + if(myseed) + myseed.on_chem_reaction(S) //In case seeds have some special interactions with special chems, currently only used by vines + + // Requires 5 mutagen to possibly change species.// Poor man's mutagen. + if(S.has_reagent("mutagen", 5) || S.has_reagent("radium", 10) || S.has_reagent("uranium", 10)) + switch(rand(100)) + if(91 to 100) + adjustHealth(-10) + to_chat(user, "The plant shrivels and burns.") + if(81 to 90) + mutatespecie() + if(66 to 80) + hardmutate() + if(41 to 65) + mutate() + if(21 to 41) + to_chat(user, "The plants don't seem to react...") + if(11 to 20) + mutateweed() + if(1 to 10) + mutatepest(user) + else + to_chat(user, "Nothing happens...") + + // 2 or 1 units is enough to change the yield and other stats.// Can change the yield and other stats, but requires more than mutagen + else if(S.has_reagent("mutagen", 2) || S.has_reagent("radium", 5) || S.has_reagent("uranium", 5)) + hardmutate() + else if(S.has_reagent("mutagen", 1) || S.has_reagent("radium", 2) || S.has_reagent("uranium", 2)) + mutate() + + // After handling the mutating, we now handle the damage from adding crude radioactives... + if(S.has_reagent("uranium", 1)) + adjustHealth(-round(S.get_reagent_amount("uranium") * 1)) + adjustToxic(round(S.get_reagent_amount("uranium") * 2)) + if(S.has_reagent("radium", 1)) + adjustHealth(-round(S.get_reagent_amount("radium") * 1)) + adjustToxic(round(S.get_reagent_amount("radium") * 3)) // Radium is harsher (OOC: also easier to produce) + + // Nutriments + if(S.has_reagent("eznutriment", 1)) + yieldmod = 1 + mutmod = 1 + adjustNutri(round(S.get_reagent_amount("eznutriment") * 1)) + + if(S.has_reagent("left4zednutriment", 1)) + yieldmod = 0 + mutmod = 2 + adjustNutri(round(S.get_reagent_amount("left4zednutriment") * 1)) + + if(S.has_reagent("robustharvestnutriment", 1)) + yieldmod = 1.3 + mutmod = 0 + adjustNutri(round(S.get_reagent_amount("robustharvestnutriment") *1 )) + + + //Fish Water is both an excellent fertilizer and waters + if(S.has_reagent("fishwater", 1)) + adjustNutri(round(S.get_reagent_amount("fishwater") * 0.75)) + adjustWater(round(S.get_reagent_amount("fishwater") * 1)) + + // Antitoxin binds shit pretty well. So the tox goes significantly down + if(S.has_reagent("charcoal", 1)) + adjustToxic(-round(S.get_reagent_amount("charcoal") * 2)) + + // NIGGA, YOU JUST WENT ON FULL RETARD. + if(S.has_reagent("toxin", 1)) + adjustToxic(round(S.get_reagent_amount("toxin") * 2)) + + // Milk is good for humans, but bad for plants. The sugars canot be used by plants, and the milk fat fucks up growth. Not shrooms though. I can't deal with this now... + if(S.has_reagent("milk", 1)) + adjustNutri(round(S.get_reagent_amount("milk") * 0.1)) + adjustWater(round(S.get_reagent_amount("milk") * 0.9)) + + // Beer is a chemical composition of alcohol and various other things. It's a shitty nutrient but hey, it's still one. Also alcohol is bad, mmmkay? + if(S.has_reagent("beer", 1)) + adjustHealth(-round(S.get_reagent_amount("beer") * 0.05)) + adjustNutri(round(S.get_reagent_amount("beer") * 0.25)) + adjustWater(round(S.get_reagent_amount("beer") * 0.7)) + + // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial + if(S.has_reagent("fluorine", 1)) + adjustHealth(-round(S.get_reagent_amount("fluorine") * 2)) + adjustToxic(round(S.get_reagent_amount("flourine") * 2.5)) + adjustWater(-round(S.get_reagent_amount("flourine") * 0.5)) + adjustWeeds(-rand(1,4)) + + // You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial + if(S.has_reagent("chlorine", 1)) + adjustHealth(-round(S.get_reagent_amount("chlorine") * 1)) + adjustToxic(round(S.get_reagent_amount("chlorine") * 1.5)) + adjustWater(-round(S.get_reagent_amount("chlorine") * 0.5)) + adjustWeeds(-rand(1,3)) + + // White Phosphorous + water -> phosphoric acid. That's not a good thing really. + // Phosphoric salts are beneficial though. And even if the plant suffers, in the long run the tray gets some nutrients. The benefit isn't worth that much. + if(S.has_reagent("phosphorus", 1)) + adjustHealth(-round(S.get_reagent_amount("phosphorus") * 0.75)) + adjustNutri(round(S.get_reagent_amount("phosphorus") * 0.1)) + adjustWater(-round(S.get_reagent_amount("phosphorus") * 0.5)) + adjustWeeds(-rand(1,2)) + + // Plants should not have sugar, they can't use it and it prevents them getting water/ nutients, it is good for mold though... + if(S.has_reagent("sugar", 1)) + adjustWeeds(rand(1,2)) + adjustPests(rand(1,2)) + adjustNutri(round(S.get_reagent_amount("sugar") * 0.1)) + + // It is water! + if(S.has_reagent("water", 1)) + adjustWater(round(S.get_reagent_amount("water") * 1)) + + // Holy water. Mostly the same as water, it also heals the plant a little with the power of the spirits~ + if(S.has_reagent("holywater", 1)) + adjustWater(round(S.get_reagent_amount("holywater") * 1)) + adjustHealth(round(S.get_reagent_amount("holywater") * 0.1)) + + // A variety of nutrients are dissolved in club soda, without sugar. + // These nutrients include carbon, oxygen, hydrogen, phosphorous, potassium, sulfur and sodium, all of which are needed for healthy plant growth. + if(S.has_reagent("sodawater", 1)) + adjustWater(round(S.get_reagent_amount("sodawater") * 1)) + adjustHealth(round(S.get_reagent_amount("sodawater") * 0.1)) + adjustNutri(round(S.get_reagent_amount("sodawater") * 0.1)) + + // Man, you guys are retards + if(S.has_reagent("sacid", 1)) + adjustHealth(-round(S.get_reagent_amount("sacid") * 1)) + adjustToxic(round(S.get_reagent_amount("sacid") * 1.5)) + adjustWeeds(-rand(1,2)) + + // SERIOUSLY + if(S.has_reagent("facid", 1)) + adjustHealth(-round(S.get_reagent_amount("facid") * 2)) + adjustToxic(round(S.get_reagent_amount("facid") * 3)) + adjustWeeds(-rand(1,4)) + + // Glyphosate is just as bad + if(S.has_reagent("glyphosate", 1)) + adjustHealth(-round(S.get_reagent_amount("glyphosate") * 5)) + adjustToxic(round(S.get_reagent_amount("glyphosate") * 6)) + adjustWeeds(-rand(4,8)) + + // why, just why + if(S.has_reagent("napalm", 1)) + adjustHealth(-round(S.get_reagent_amount("napalm") * 6)) + adjustToxic(round(S.get_reagent_amount("napalm") * 7)) + adjustWeeds(-rand(5,9)) + + //Weed Spray + if(S.has_reagent("atrazine", 1)) + adjustToxic(round(S.get_reagent_amount("atrazine") * 0.5)) + //old toxicity was 4, each spray is default 10 (minimal of 5) so 5 and 2.5 are the new ammounts + adjustWeeds(-rand(1,2)) + + //Pest Spray + if(S.has_reagent("pestkiller", 1)) + adjustToxic(round(S.get_reagent_amount("pestkiller") * 0.5)) + adjustPests(-rand(1,2)) + + // Healing + if(S.has_reagent("cryoxadone", 1)) + adjustHealth(round(S.get_reagent_amount("cryoxadone") * 3)) + adjustToxic(-round(S.get_reagent_amount("cryoxadone") * 3)) + + // Ammonia is bad ass. + if(S.has_reagent("ammonia", 1)) + adjustHealth(round(S.get_reagent_amount("ammonia") * 0.5)) + adjustNutri(round(S.get_reagent_amount("ammonia") * 1)) + if(myseed) + myseed.adjust_yield(round(S.get_reagent_amount("ammonia") * 0.01)) + + // Saltpetre is used for gardening IRL, to simplify highly, it speeds up growth and strengthens plants + if(S.has_reagent("saltpetre", 1)) + var/salt = S.get_reagent_amount("saltpetre") + adjustHealth(round(salt * 0.25)) + if (myseed) + myseed.adjust_production(-round(salt/100)-prob(salt%100)) + myseed.adjust_potency(round(salt*0.50)) + // Ash is also used IRL in gardening, as a fertilizer enhancer and weed killer + if(S.has_reagent("ash", 1)) + adjustHealth(round(S.get_reagent_amount("ash") * 0.25)) + adjustNutri(round(S.get_reagent_amount("ash") * 0.5)) + adjustWeeds(-1) + + // This is more bad ass, and pests get hurt by the corrosive nature of it, not the plant. + if(S.has_reagent("diethylamine", 1)) + adjustHealth(round(S.get_reagent_amount("diethylamine") * 1)) + adjustNutri(round(S.get_reagent_amount("diethylamine") * 2)) + if(myseed) + myseed.adjust_yield(round(S.get_reagent_amount("diethylamine") * 0.02)) + adjustPests(-rand(1,2)) + + // Compost, effectively + if(S.has_reagent("nutriment", 1)) + adjustHealth(round(S.get_reagent_amount("nutriment") * 0.5)) + adjustNutri(round(S.get_reagent_amount("nutriment") * 1)) + + if(S.has_reagent("plantmatter", 1)) + adjustHealth(round(S.get_reagent_amount("plantmatter") * 0.5)) + adjustNutri(round(S.get_reagent_amount("plantmatter") * 1)) + + // Compost for EVERYTHING + if(S.has_reagent("virusfood", 1)) + adjustNutri(round(S.get_reagent_amount("virusfood") * 0.5)) + adjustHealth(-round(S.get_reagent_amount("virusfood") * 0.5)) + + // FEED ME + if(S.has_reagent("blood", 1)) + adjustNutri(round(S.get_reagent_amount("blood") * 1)) + adjustPests(rand(2,4)) + + // FEED ME SEYMOUR + if(S.has_reagent("strangereagent", 1)) + spawnplant() + + // The best stuff there is. For testing/debugging. + if(S.has_reagent("adminordrazine", 1)) + adjustWater(round(S.get_reagent_amount("adminordrazine") * 1)) + adjustHealth(round(S.get_reagent_amount("adminordrazine") * 1)) + adjustNutri(round(S.get_reagent_amount("adminordrazine") * 1)) + adjustPests(-rand(1,5)) + adjustWeeds(-rand(1,5)) + if(S.has_reagent("adminordrazine", 5)) + switch(rand(100)) + if(66 to 100) + mutatespecie() + if(33 to 65) + mutateweed() + if(1 to 32) + mutatepest(user) + else + to_chat(user, "Nothing happens...") + +/obj/machinery/hydroponics/attackby(obj/item/O, mob/user, params) + //Called when mob user "attacks" it with object O + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia)) //Checked early on so it doesn't have to deal with composting checks + if(self_sustaining) + to_chat(user, "This [name] is already self-sustaining!") + return + if(myseed || weedlevel) + to_chat(user, "[src] needs to be clear of plants and weeds!") + return + if(alert(user, "This will make [src] self-sustaining but consume [O] forever. Are you sure?", "[name]", "I'm Sure", "Abort") == "Abort" || !user) + return + if(!O || qdeleted(O)) + return + if(!Adjacent(user)) + return + if(self_sustaining) + to_chat(user, "This [name] is already self-sustaining!") + return + if(myseed || weedlevel) + to_chat(user, "[src] needs to be clear of plants and weeds!") + return + user.visible_message("[user] gently pulls open the soil for [O] and places it inside.", "You tenderly root [O] into [src].") + user.drop_item() + qdel(O) + visible_message("[src] begins to glow with a beautiful light!") + self_sustaining = TRUE + update_icon() + + else if(istype(O, /obj/item/weapon/reagent_containers) ) // Syringe stuff (and other reagent containers now too) + var/obj/item/weapon/reagent_containers/reagent_source = O + + if(istype(reagent_source, /obj/item/weapon/reagent_containers/syringe)) + var/obj/item/weapon/reagent_containers/syringe/syr = reagent_source + if(syr.mode != 1) + to_chat(user, "You can't get any extract out of this plant.") //That. Gives me an idea... + return + + if(!reagent_source.reagents.total_volume) + to_chat(user, "[reagent_source] is empty.") + return 1 + + var/list/trays = list(src)//makes the list just this in cases of syringes and compost etc + var/target = myseed ? myseed.plantname : src + var/visi_msg = "" + var/irrigate = 0 //How am I supposed to irrigate pill contents? + + if(istype(reagent_source, /obj/item/weapon/reagent_containers/food/snacks) || istype(reagent_source, /obj/item/weapon/reagent_containers/food/pill)) + visi_msg="[user] composts [reagent_source], spreading it through [target]" + else + if(istype(reagent_source, /obj/item/weapon/reagent_containers/syringe/)) + var/obj/item/weapon/reagent_containers/syringe/syr = reagent_source + visi_msg="[user] injects [target] with [syr]" + if(syr.reagents.total_volume <= syr.amount_per_transfer_from_this) + syr.mode = 0 + else if(istype(reagent_source, /obj/item/weapon/reagent_containers/spray/)) + visi_msg="[user] sprays [target] with [reagent_source]" + playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) + irrigate = 1 + else if(reagent_source.amount_per_transfer_from_this) // Droppers, cans, beakers, what have you. + visi_msg="[user] uses [reagent_source] on [target]" + irrigate = 1 + // Beakers, bottles, buckets, etc. Can't use is_open_container though. + if(istype(reagent_source, /obj/item/weapon/reagent_containers/glass/)) + playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + + if(irrigate && reagent_source.amount_per_transfer_from_this > 30 && reagent_source.reagents.total_volume >= 30 && using_irrigation) + trays = FindConnected() + if (trays.len > 1) + visi_msg += ", setting off the irrigation system" + + if(visi_msg) + visible_message("[visi_msg].") + + var/split = round(reagent_source.amount_per_transfer_from_this/trays.len) + + for(var/obj/machinery/hydroponics/H in trays) + //cause I don't want to feel like im juggling 15 tamagotchis and I can get to my real work of ripping flooring apart in hopes of validating my life choices of becoming a space-gardener + + var/datum/reagents/S = new /datum/reagents() //This is a strange way, but I don't know of a better one so I can't fix it at the moment... + S.my_atom = H + + reagent_source.reagents.trans_to(S,split) + if(istype(reagent_source, /obj/item/weapon/reagent_containers/food/snacks) || istype(reagent_source, /obj/item/weapon/reagent_containers/food/pill)) + qdel(reagent_source) + + H.applyChemicals(S, user) + + S.clear_reagents() + qdel(S) + H.update_icon() + if(reagent_source) // If the source wasn't composted and destroyed + reagent_source.update_icon() + return 1 + + else if(istype(O, /obj/item/seeds) && !istype(O, /obj/item/seeds/sample)) + if(!myseed) + if(istype(O, /obj/item/seeds/kudzu)) + investigate_log("had Kudzu planted in it by [user.ckey]([user]) at ([x],[y],[z])","kudzu") + user.unEquip(O) + to_chat(user, "You plant [O].") + dead = 0 + myseed = O + age = 1 + plant_health = myseed.endurance + plant_hud_set_health() + plant_hud_set_status() + lastcycle = world.time + O.forceMove(src) + update_icon() + else + to_chat(user, "[src] already has seeds in it!") + + else if(istype(O, /obj/item/device/plant_analyzer)) + if(myseed) + to_chat(user, "*** [myseed.plantname] ***") //Carn: now reports the plants growing, not the seeds. + to_chat(user, "- Plant Age: [age]") + var/list/text_string = myseed.get_analyzer_text() + if(text_string) + to_chat(user, text_string) + else + to_chat(user, "No plant found.") + to_chat(user, "- Weed level: [weedlevel] / 10") + to_chat(user, "- Pest level: [pestlevel] / 10") + to_chat(user, "- Toxicity level: [toxic] / 100") + to_chat(user, "- Water level: [waterlevel] / [maxwater]") + to_chat(user, "- Nutrition level: [nutrilevel] / [maxnutri]") + to_chat(user, "") + + else if(istype(O, /obj/item/weapon/cultivator)) + if(weedlevel > 0) + user.visible_message("[user] uproots the weeds.", "You remove the weeds from [src].") + adjustWeeds(-10) + update_icon() + else + to_chat(user, "This plot is completely devoid of weeds! It doesn't need uprooting.") + + else if(istype(O, /obj/item/weapon/storage/bag/plants)) + attack_hand(user) + var/obj/item/weapon/storage/bag/plants/S = O + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in locate(user.x,user.y,user.z)) + if(!S.can_be_inserted(G)) + return + S.handle_item_insertion(G, 1) + + else if(iswrench(O) && wrenchable) + if(using_irrigation) + to_chat(user, "Disconnect the hoses first!") + return + + if(!anchored && !isinspace()) + user.visible_message("[user] begins to wrench [src] into place.", "You begin to wrench [src] in place...") + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + if (do_after(user, 20, target = src)) + if(anchored) + return + anchored = 1 + user.visible_message("[user] wrenches [src] into place.", \ + "You wrench [src] in place.") + else if(anchored) + user.visible_message("[user] begins to unwrench [src].", \ + "You begin to unwrench [src]...") + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + if (do_after(user, 20, target = src)) + if(!anchored) + return + anchored = 0 + user.visible_message("[user] unwrenches [src].", \ + "You unwrench [src].") + + else if(iswirecutter(O) && wrenchable) + using_irrigation = !using_irrigation + playsound(src, 'sound/items/Wirecutter.ogg', 50, 1) + user.visible_message("[user] [using_irrigation ? "" : "dis"]connects [src]'s irrigation hoses.", \ + "You [using_irrigation ? "" : "dis"]connect [src]'s irrigation hoses.") + for(var/obj/machinery/hydroponics/h in range(1,src)) + h.update_icon() + + else if(istype(O, /obj/item/weapon/shovel/spade)) + if(!myseed && !weedlevel) + to_chat(user, "[src] doesn't have any plants or weeds!") + return + user.visible_message("[user] starts digging out [src]'s plants...", "You start digging out [src]'s plants...") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + if(!do_after(user, 50, target = src) || (!myseed && !weedlevel)) + return + user.visible_message("[user] digs out the plants in [src]!", "You dig out all of [src]'s plants!") + playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) + if(myseed) //Could be that they're just using it as a de-weeder + age = 0 + plant_health = 0 + if(harvest) + harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it + qdel(myseed) + myseed = null + plant_hud_set_health() + plant_hud_set_status() + adjustWeeds(-10) //Has a side effect of cleaning up those nasty weeds + update_icon() + + else + return ..() + +/obj/machinery/hydroponics/attack_hand(mob/user) + if(issilicon(user)) //How does AI know what plant is? + return + if(harvest) + myseed.harvest(user) + else if(dead) + dead = 0 + to_chat(user, "You remove the dead plant from [src].") + qdel(myseed) + myseed = null + update_icon() + plant_hud_set_status() + plant_hud_set_health() + else + examine(user) + +/obj/machinery/hydroponics/proc/update_tray(mob/user = usr) + harvest = 0 + lastproduce = age + if(istype(myseed,/obj/item/seeds/replicapod)) + to_chat(user, "You harvest from the [myseed.plantname].") + else if(myseed.getYield() <= 0) + to_chat(user, "You fail to harvest anything useful!") + else + to_chat(user, "You harvest [myseed.getYield()] items from the [myseed.plantname].") + if(!myseed.get_gene(/datum/plant_gene/trait/repeated_harvest)) + qdel(myseed) + myseed = null + dead = 0 + plant_hud_set_status() + plant_hud_set_health() + update_icon() + +/// Tray Setters - The following procs adjust the tray or plants variables, and make sure that the stat doesn't go out of bounds./// +/obj/machinery/hydroponics/proc/adjustNutri(adjustamt) + nutrilevel = Clamp(nutrilevel + adjustamt, 0, maxnutri) + plant_hud_set_nutrient() + +/obj/machinery/hydroponics/proc/adjustWater(adjustamt) + waterlevel = Clamp(waterlevel + adjustamt, 0, maxwater) + plant_hud_set_water() + if(adjustamt>0) + adjustToxic(-round(adjustamt/4))//Toxicity dilutation code. The more water you put in, the lesser the toxin concentration. + +/obj/machinery/hydroponics/proc/adjustHealth(adjustamt) + if(myseed && !dead) + plant_health = Clamp(plant_health + adjustamt, 0, myseed.endurance) + plant_hud_set_health() + +/obj/machinery/hydroponics/proc/adjustToxic(adjustamt) + toxic = Clamp(toxic + adjustamt, 0, 100) + plant_hud_set_toxin() + +/obj/machinery/hydroponics/proc/adjustPests(adjustamt) + pestlevel = Clamp(pestlevel + adjustamt, 0, 10) + plant_hud_set_pest() + +/obj/machinery/hydroponics/proc/adjustWeeds(adjustamt) + weedlevel = Clamp(weedlevel + adjustamt, 0, 10) + plant_hud_set_weed() + +/obj/machinery/hydroponics/proc/spawnplant() // why would you put strange reagent in a hydro tray you monster I bet you also feed them blood + var/list/livingplants = list(/mob/living/simple_animal/hostile/tree, /mob/living/simple_animal/hostile/killertomato) + var/chosen = pick(livingplants) + var/mob/living/simple_animal/hostile/C = new chosen + C.faction = list("plants") + +///Diona Nymph Related Procs/// +/obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) //So nymphs can climb over top of trays. + if(air_group || (height==0)) + return 1 + + if(istype(mover) && mover.checkpass(PASSTABLE)) + return 1 + else + return 0 + +/obj/machinery/hydroponics/attack_animal(mob/living/user) + if(istype(user, /mob/living/simple_animal/diona)) + if(weedlevel > 0) + user.nutrition += weedlevel * 15 + adjustWeeds(-10) + update_icon() + visible_message("[user] begins rooting through [src], ripping out weeds and eating them noisily.","You begin rooting through [src], ripping out weeds and eating them noisily.") + else if(nutrilevel < 10) + user.nutrition -= ((10 - nutrilevel) * 5) + adjustNutri(10) + update_icon() + visible_message("[user] secretes a trickle of green liquid from its tail, refilling [src]'s nutrient tray.","You secrete a trickle of green liquid from your tail, refilling [src]'s nutrient tray.") + else + ..() + +/////////////////////////////////////////////////////////////////////////////// +/obj/machinery/hydroponics/soil //Not actually hydroponics at all! Honk! + name = "soil" + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "soil" + density = 0 + use_power = 0 + wrenchable = 0 + +/obj/machinery/hydroponics/soil/update_icon_hoses() + return // Has no hoses + +/obj/machinery/hydroponics/soil/update_icon_lights() + return // Has no lights + +/obj/machinery/hydroponics/soil/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/weapon/shovel) && !istype(O, /obj/item/weapon/shovel/spade)) //Doesn't include spades because of uprooting plants + to_chat(user, "You clear up [src]!") + qdel(src) + else + ..() \ No newline at end of file diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm new file mode 100644 index 00000000000..ecf38424764 --- /dev/null +++ b/code/modules/hydroponics/plant_genes.dm @@ -0,0 +1,408 @@ +/datum/plant_gene + var/name + +/datum/plant_gene/proc/get_name() // Used for manipulator display and gene disk name. + return name + +/datum/plant_gene/proc/can_add(obj/item/seeds/S) + return !istype(S, /obj/item/seeds/sample) // Samples can't accept new genes + +/datum/plant_gene/proc/Copy() + return new type + + + + +// Core plant genes store 5 main variables: lifespan, endurance, production, yield, potency +/datum/plant_gene/core + var/value + +/datum/plant_gene/core/get_name() + return "[name] [value]" + +/datum/plant_gene/core/proc/apply_stat(obj/item/seeds/S) + return + +/datum/plant_gene/core/New(var/i = null) + ..() + if(!isnull(i)) + value = i + +/datum/plant_gene/core/Copy() + var/datum/plant_gene/core/C = ..() + C.value = value + return C + +/datum/plant_gene/core/can_add(obj/item/seeds/S) + if(!..()) + return FALSE + return S.get_gene(type) + +/datum/plant_gene/core/lifespan + name = "Lifespan" + value = 25 + +/datum/plant_gene/core/lifespan/apply_stat(obj/item/seeds/S) + S.lifespan = value + + +/datum/plant_gene/core/endurance + name = "Endurance" + value = 15 + +/datum/plant_gene/core/endurance/apply_stat(obj/item/seeds/S) + S.endurance = value + + +/datum/plant_gene/core/production + name = "Production Speed" + value = 6 + +/datum/plant_gene/core/production/apply_stat(obj/item/seeds/S) + S.production = value + + +/datum/plant_gene/core/yield + name = "Yield" + value = 3 + +/datum/plant_gene/core/yield/apply_stat(obj/item/seeds/S) + S.yield = value + + +/datum/plant_gene/core/potency + name = "Potency" + value = 10 + +/datum/plant_gene/core/potency/apply_stat(obj/item/seeds/S) + S.potency = value + + +/datum/plant_gene/core/weed_rate + name = "Weed Growth Rate" + value = 1 + +/datum/plant_gene/core/weed_rate/apply_stat(obj/item/seeds/S) + S.weed_rate = value + + +/datum/plant_gene/core/weed_chance + name = "Weed Vulnerability" + value = 5 + +/datum/plant_gene/core/weed_chance/apply_stat(obj/item/seeds/S) + S.weed_chance = value + + +// Reagent genes store reagent ID and reagent ratio. Amount of reagent in the plant = 1 + (potency * rate) +/datum/plant_gene/reagent + name = "Nutriment" + var/reagent_id = "nutriment" + var/rate = 0.04 + +/datum/plant_gene/reagent/get_name() + return "[name] production [rate*100]%" + +/datum/plant_gene/reagent/proc/set_reagent(reag_id) + reagent_id = reag_id + name = "UNKNOWN" + + var/datum/reagent/R = chemical_reagents_list[reag_id] + if(R && R.id == reagent_id) + name = R.name + +/datum/plant_gene/reagent/New(reag_id = null, reag_rate = 0) + ..() + if(reag_id && reag_rate) + set_reagent(reag_id) + rate = reag_rate + +/datum/plant_gene/reagent/Copy() + var/datum/plant_gene/reagent/G = ..() + G.name = name + G.reagent_id = reagent_id + G.rate = rate + return G + +/datum/plant_gene/reagent/can_add(obj/item/seeds/S) + if(!..()) + return FALSE + for(var/datum/plant_gene/reagent/R in S.genes) + if(R.reagent_id == reagent_id) + return FALSE + return TRUE + + +// Various traits affecting the product. Each must be somehow useful. +/datum/plant_gene/trait + var/rate = 0.05 + var/examine_line = "" + var/list/origin_tech = null + var/trait_id // must be set and equal for any two traits of the same type + +/datum/plant_gene/trait/Copy() + var/datum/plant_gene/trait/G = ..() + G.rate = rate + return G + +/datum/plant_gene/trait/can_add(obj/item/seeds/S) + if(!..()) + return FALSE + + for(var/datum/plant_gene/trait/R in S.genes) + if(trait_id && R.trait_id == trait_id) + return FALSE + if(type == R.type) + return FALSE + return TRUE + +/datum/plant_gene/trait/proc/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc) + if(!origin_tech) // This ugly code segment adds RnD tech levels to resulting plants. + return + + if(G.origin_tech) + var/list/tech = params2list(G.origin_tech) + for(var/t in origin_tech) + if(t in tech) + tech[t] = max(text2num(tech[t]), origin_tech[t]) + else + tech[t] = origin_tech[t] + G.origin_tech = list2params(tech) + else + G.origin_tech = list2params(origin_tech) + +/datum/plant_gene/trait/proc/on_consume(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) + return + +/datum/plant_gene/trait/proc/on_cross(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + return + +/datum/plant_gene/trait/proc/on_slip(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) + return + +/datum/plant_gene/trait/proc/on_squash(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + return + +/datum/plant_gene/trait/proc/on_attackby(obj/item/weapon/reagent_containers/food/snacks/grown/G, obj/item/I, mob/user) + return + +/datum/plant_gene/trait/proc/on_throw_impact(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + return + +/datum/plant_gene/trait/squash + // Allows the plant to be squashed when thrown or slipped on, leaving a colored mess and trash type item behind. + // Also splashes everything in target turf with reagents and applies other trait effects (teleporting, etc) to the target by on_squash. + // For code, see grown.dm + name = "Liquid Contents" + examine_line = "It has a lot of liquid contents inside." + origin_tech = list("biotech" = 5) + +/datum/plant_gene/trait/slip + // Makes plant slippery, unless it has a grown-type trash. Then the trash gets slippery. + // Applies other trait effects (teleporting, etc) to the target by on_slip. + name = "Slippery Skin" + rate = 0.1 + examine_line = "It has a very slippery skin." + +/datum/plant_gene/trait/slip/on_cross(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + if(iscarbon(target)) + var/obj/item/seeds/seed = G.seed + var/mob/living/carbon/M = target + + var/stun_len = seed.potency * rate * 0.8 + if(istype(G) && ispath(G.trash, /obj/item/weapon/grown)) + return + + if(!istype(G, /obj/item/weapon/grown/bananapeel) && (!G.reagents || !G.reagents.has_reagent("lube"))) + stun_len /= 3 + + var/stun = min(stun_len, 7) + var/weaken = min(stun_len, 7) + + if(M.slip("[G]", stun, weaken)) + for(var/datum/plant_gene/trait/T in seed.genes) + T.on_slip(G, M) + +/datum/plant_gene/trait/cell_charge + // Cell recharging trait. Charges all mob's power cells to (potency*rate)% mark when eaten. + // Generates sparks on squash. + // Small (potency*rate*5) chance to shock squish or slip target for (potency*rate*5) damage. + // Multiplies max charge by (rate*1000) when used in potato power cells. + name = "Electrical Activity" + rate = 0.2 + origin_tech = list("powerstorage" = 5) + +/datum/plant_gene/trait/cell_charge/on_slip(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) + var/power = G.seed.potency*rate + if(prob(power)) + C.electrocute_act(round(power), G, 1, 1) + +/datum/plant_gene/trait/cell_charge/on_squash(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + if(iscarbon(target)) + var/mob/living/carbon/C = target + var/power = G.seed.potency*rate + if(prob(power)) + C.electrocute_act(round(power), G, 1, 1) + +/datum/plant_gene/trait/cell_charge/on_consume(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) + if(!G.reagents.total_volume) + var/batteries_recharged = 0 + for(var/obj/item/weapon/stock_parts/cell/C in target.GetAllContents()) + var/newcharge = min(G.seed.potency*0.01*C.maxcharge, C.maxcharge) + if(C.charge < newcharge) + C.charge = newcharge + if(isobj(C.loc)) + var/obj/O = C.loc + O.update_icon() //update power meters and such + C.update_icon() + batteries_recharged = 1 + if(batteries_recharged) + to_chat(target, "Your batteries are recharged!") + + + +/datum/plant_gene/trait/glow + // Makes plant glow. Makes plant in tray glow too. + // Adds potency*rate luminosity to products. + name = "Bioluminescence" + rate = 0.1 + examine_line = "It emits a soft glow." + trait_id = "glow" + +/datum/plant_gene/trait/glow/proc/get_lum(obj/item/seeds/S) + return round(S.potency*rate) + +/datum/plant_gene/trait/glow/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc) + ..() + G.set_light(get_lum(G.seed)) + +/datum/plant_gene/trait/glow/berry + name = "Strong Bioluminescence" + rate = 0.2 + + +/datum/plant_gene/trait/teleport + // Makes plant teleport people when squashed or slipped on. + // Teleport radius is calculated as max(round(potency*rate), 1) + name = "Bluespace Activity" + rate = 0.1 + origin_tech = list("bluespace" = 5) + +/datum/plant_gene/trait/teleport/on_squash(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + if(isliving(target)) + var/teleport_radius = max(round(G.seed.potency / 10), 1) + var/turf/T = get_turf(target) + new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect... + do_teleport(target, T, teleport_radius) + +/datum/plant_gene/trait/teleport/on_slip(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) + var/teleport_radius = max(round(G.seed.potency / 10), 1) + var/turf/T = get_turf(C) + to_chat(C, "You slip through spacetime!") + do_teleport(C, T, teleport_radius) + if(prob(50)) + do_teleport(G, T, teleport_radius) + else + new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect... + qdel(G) + + +/datum/plant_gene/trait/noreact + // Makes plant reagents not react until squashed. + name = "Separated Chemicals" + +/datum/plant_gene/trait/noreact/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc) + ..() + G.reagents.set_reacting(FALSE) + +/datum/plant_gene/trait/noreact/on_squash(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + if(G && G.reagents) + G.reagents.set_reacting(TRUE) + G.reagents.handle_reactions() + + +/datum/plant_gene/trait/maxchem + // 2x to max reagents volume. + name = "Densified Chemicals" + rate = 2 + +/datum/plant_gene/trait/maxchem/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc) + ..() + G.reagents.maximum_volume *= rate + +/datum/plant_gene/trait/repeated_harvest + name = "Perennial Growth" + +/datum/plant_gene/trait/repeated_harvest/can_add(obj/item/seeds/S) + if(!..()) + return FALSE + if(istype(S, /obj/item/seeds/replicapod)) + return FALSE + return TRUE + +/datum/plant_gene/trait/battery + name = "Capacitive Cell Production" + +/datum/plant_gene/trait/battery/on_attackby(obj/item/weapon/reagent_containers/food/snacks/grown/G, obj/item/I, mob/user) + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = I + if(C.use(5)) + to_chat(user, "You add some cable to [G] and slide it inside the battery encasing.") + var/obj/item/weapon/stock_parts/cell/potato/pocell = new /obj/item/weapon/stock_parts/cell/potato(user.loc) + pocell.icon_state = G.icon_state + pocell.maxcharge = G.seed.potency * 20 + + // The secret of potato supercells! + var/datum/plant_gene/trait/cell_charge/CG = G.seed.get_gene(/datum/plant_gene/trait/cell_charge) + if(CG) // 10x charge for deafult cell charge gene - 20 000 with 100 potency. + pocell.maxcharge *= CG.rate*1000 + pocell.charge = pocell.maxcharge + pocell.name = "[G] battery" + pocell.desc = "A rechargable plant based power cell. This one has a power rating of [pocell.maxcharge], and you should not swallow it." + + if(G.reagents.has_reagent("plasma", 2)) + pocell.rigged = 1 + + qdel(G) + else + to_chat(user, "You need five lengths of cable to make a [G] battery!") + + +/datum/plant_gene/trait/stinging + name = "Hypodermic Prickles" + +/datum/plant_gene/trait/stinging/on_throw_impact(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + if(isliving(target) && G.reagents && G.reagents.total_volume) + var/mob/living/L = target + if(L.reagents && L.can_inject(null, 0)) + var/injecting_amount = max(1, G.seed.potency*0.2) // Minimum of 1, max of 20 + var/fraction = min(injecting_amount/G.reagents.total_volume, 1) + G.reagents.reaction(L, INGEST, fraction) + G.reagents.trans_to(L, injecting_amount) + to_chat(target, "You are pricked by [G]!") + +/datum/plant_gene/trait/smoke + name = "gaseous decomposition" + +/datum/plant_gene/trait/smoke/on_squash(obj/item/weapon/reagent_containers/food/snacks/grown/G, atom/target) + var/datum/effect/system/chem_smoke_spread/S = new + var/splat_location = get_turf(target) + var/smoke_amount = round(sqrt(G.seed.potency * 0.1), 1) + S.attach(splat_location) + S.set_up(G.reagents, 2, 0, splat_location) + S.start(smoke_amount) + if(G && G.reagents) + G.reagents.clear_reagents() + +/datum/plant_gene/trait/plant_type // Parent type + name = "you shouldn't see this" + trait_id = "plant_type" + +/datum/plant_gene/trait/plant_type/weed_hardy + name = "Weed Adaptation" + +/datum/plant_gene/trait/plant_type/fungal_metabolism + name = "Fungal Vitality" + +/datum/plant_gene/trait/plant_type/alien_properties + name ="?????" diff --git a/code/modules/hydroponics/sample.dm b/code/modules/hydroponics/sample.dm new file mode 100644 index 00000000000..4478671b2fb --- /dev/null +++ b/code/modules/hydroponics/sample.dm @@ -0,0 +1,44 @@ +var/list/chem_t1_reagents = list( + "hydrogen", "oxygen", "silicon", + "phosphorus", "sulfur", "carbon", + "nitrogen", "water" +) + +var/list/chem_t2_reagents = list( + "lithium", "copper", "mercury", + "sodium", "iodine", "bromine" +) // "sugar", "sacid" removed because they are already in roundstart plants + +var/list/chem_t3_reagents = list( + "ethanol", "chlorine", "potassium", + "aluminium", "radium", "fluorine", + "iron", "welding_fuel", "silver", + "stable_plasma" +) + +var/list/chem_t4_reagents = list( + "oil", "ash", "acetone", + "saltpetre", "ammonia", "diethylamine" +) + +/obj/item/seeds/sample + name = "plant sample" + icon_state = "sample-empty" + potency = -1 + yield = -1 + var/sample_color = "#FFFFFF" + +/obj/item/seeds/sample/New() + ..() + if(sample_color) + var/image/I = image(icon, icon_state = "sample-filling") + I.color = sample_color + overlays += I + +/obj/item/seeds/sample/get_analyzer_text() + return " The DNA of this sample is damaged beyond recovery, it can't support life on it's own.\n*---------*" + +/obj/item/seeds/sample/alienweed + name = "alien weed sample" + icon_state = "alienweed" + sample_color = null \ No newline at end of file diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm deleted file mode 100644 index 4343bc75686..00000000000 --- a/code/modules/hydroponics/seed.dm +++ /dev/null @@ -1,839 +0,0 @@ -/datum/plantgene - var/genetype // Label used when applying trait. - var/list/values // Values to copy into the target seed datum. - -/datum/seed - //Tracking. - var/uid // Unique identifier. - var/name // Index for global list. - var/seed_name // Plant name for seed packet. - var/seed_noun = "seeds" // Descriptor for packet. - var/display_name // Prettier name. - var/base_name // Unchanging name for use with modified versions - var/roundstart // If set, seed will not display variety number. - var/mysterious // Only used for the random seed packets. - var/can_self_harvest = 0 // Mostly used for living mobs. - var/growth_stages = 0 // Number of stages the plant passes through before it is mature. - var/list/traits = list() // Initialized in New() - var/list/mutants // Possible predefined mutant varieties, if any. - var/list/chems // Chemicals that plant produces in products/injects into victim. - var/list/consume_gasses // The plant will absorb these gasses during its life. - var/list/exude_gasses // The plant will exude these gasses during its life. - var/kitchen_tag // Used by the reagent grinder. - var/trash_type // Garbage item produced when eaten. - var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal. - var/preset_product - var/final_form = 1 - var/last_diverge_type = -1 // Used to check if we need to change our name prefix when we are mutated/modified/enhanced - var/modular_icon = 0 // Dictates if the product uses a modular sprite. 0 = preset, 1 = modular - var/preset_icon = "undef" // Name of the iconstate in icon/obj/harvest.dmi to use for preset sprite - // Make sure to set this to the correct icon if not using a modular sprite - -/datum/seed/New() - base_name = seed_name - set_trait(TRAIT_IMMUTABLE, 0) // If set, plant will never mutate. If -1, plant is highly mutable. - set_trait(TRAIT_HARVEST_REPEAT, 0) // If 1, this plant will fruit repeatedly. - set_trait(TRAIT_PRODUCES_POWER, 0) // Can be used to make a battery. - set_trait(TRAIT_JUICY, 0) // When thrown, causes a splatter decal. - set_trait(TRAIT_EXPLOSIVE, 0) // When thrown, acts as a grenade. - set_trait(TRAIT_CARNIVOROUS, 0) // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine). - set_trait(TRAIT_PARASITE, 0) // 0 = no, 1 = gain health from weed level. - set_trait(TRAIT_STINGS, 0) // Can cause damage/inject reagents when thrown or handled. - set_trait(TRAIT_YIELD, 0) // Amount of product. - set_trait(TRAIT_SPREAD, 0) // 0 limits plant to tray, 1 = creepers, 2 = vines. - set_trait(TRAIT_MATURATION, 0) // Time taken before the plant is mature. - set_trait(TRAIT_PRODUCTION, 0) // Time before harvesting can be undertaken again. - set_trait(TRAIT_TELEPORTING, 0) // Uses the bluespace tomato effect. - set_trait(TRAIT_BATTERY_RECHARGE, 0) // Used for glowcaps; recharges batteries on a user. - set_trait(TRAIT_BIOLUM, 0) // Plant is bioluminescent. - set_trait(TRAIT_ALTER_TEMP, 0) // If set, the plant will periodically alter local temp by this amount. - set_trait(TRAIT_PRODUCT_ICON, 0) // Icon to use for fruit coming from this plant. - set_trait(TRAIT_PLANT_ICON, 0) // Icon to use for the plant growing in the tray. - set_trait(TRAIT_PRODUCT_COLOUR, 0) // Colour to apply to product icon. - set_trait(TRAIT_BIOLUM_COLOUR, 0) // The colour of the plant's radiance. - set_trait(TRAIT_RARITY, 0) // How rare the plant is. Used for giving points to cargo when shipping off to Centcom. - set_trait(TRAIT_POTENCY, 1) // General purpose plant strength value. - set_trait(TRAIT_REQUIRES_NUTRIENTS, 1) // The plant can starve. - set_trait(TRAIT_REQUIRES_WATER, 1) // The plant can become dehydrated. - set_trait(TRAIT_WATER_CONSUMPTION, 3) // Plant drinks this much per tick. - set_trait(TRAIT_LIGHT_TOLERANCE, 5) // Departure from ideal that is survivable. - set_trait(TRAIT_TOXINS_TOLERANCE, 5) // Resistance to poison. - set_trait(TRAIT_PEST_TOLERANCE, 5) // Threshold for pests to impact health. - set_trait(TRAIT_WEED_TOLERANCE, 5) // Threshold for weeds to impact health. - set_trait(TRAIT_IDEAL_LIGHT, 8) // Preferred light level in luminosity. - set_trait(TRAIT_HEAT_TOLERANCE, 20) // Departure from ideal that is survivable. - set_trait(TRAIT_LOWKPA_TOLERANCE, 25) // Low pressure capacity. - set_trait(TRAIT_ENDURANCE, 100) // Maximum plant HP when growing. - set_trait(TRAIT_HIGHKPA_TOLERANCE, 200) // High pressure capacity. - set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin. - set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick. - set_trait(TRAIT_PLANT_COLOUR, "#46B543") // Colour of the plant icon. - - spawn(5) - sleep(-1) - update_growth_stages() - -/datum/seed/proc/get_trait(var/trait) - return traits["[trait]"] - -/datum/seed/proc/set_trait(var/trait,var/nval,var/ubound,var/lbound, var/degrade) - if(!isnull(degrade)) nval *= degrade - if(!isnull(ubound)) nval = min(nval,ubound) - if(!isnull(lbound)) nval = max(nval,lbound) - traits["[trait]"] = nval - -/datum/seed/proc/create_spores(var/turf/T, var/obj/item/thrown) - if(!T) - return - if(!istype(T)) - T = get_turf(T) - if(!T) - return - - var/datum/reagents/R = new/datum/reagents(100) - R.my_atom = thrown - if(chems.len) - for(var/rid in chems) - var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3)) - R.add_reagent(rid,injecting) - - var/datum/effect/system/chem_smoke_spread/S = new() - S.attach(T) - S.set_up(R, round(get_trait(TRAIT_POTENCY)/4), 0, T) - S.start() - -// Does brute damage to a target. -/datum/seed/proc/do_thorns(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb) - - if(!get_trait(TRAIT_CARNIVOROUS)) - return - - if(!istype(target)) - if(istype(target, /mob/living/simple_animal/mouse) || istype(target, /mob/living/simple_animal/lizard)) - new /obj/effect/decal/cleanable/blood/splatter(get_turf(target)) - qdel(target) - return - - - if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin") - var/obj/item/organ/external/affecting = target.get_organ(target_limb) - var/damage = 0 - - if(get_trait(TRAIT_CARNIVOROUS)) - if(get_trait(TRAIT_CARNIVOROUS) == 2) - if(affecting) - to_chat(target, "\The [fruit]'s thorns pierce your [affecting.name] greedily!") - else - to_chat(target, "\The [fruit]'s thorns pierce your flesh greedily!") - damage = get_trait(TRAIT_POTENCY)/2 - else - if(affecting) - to_chat(target, "\The [fruit]'s thorns dig deeply into your [affecting.name]!") - else - to_chat(target, "\The [fruit]'s thorns dig deeply into your flesh!") - damage = get_trait(TRAIT_POTENCY)/5 - else - return - - if(affecting) - affecting.take_damage(damage, 0) - affecting.add_autopsy_data("Thorns",damage) - else - target.adjustBruteLoss(damage) - target.UpdateDamageIcon() - target.updatehealth() - -// Adds reagents to a target. -/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb) - if(!get_trait(TRAIT_STINGS)) - return - if(!istype(target)) - return - if(!target_limb) //if we weren't given a target_limb, pick a random one to try stinging - target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin") - if(chems && chems.len) - - if(!target.can_inject(target, 0, target_limb)) //if a syringe can't get through, neither can the sting - return - - var/protection_needed - switch(target_limb) - if("head") - protection_needed = HEAD | HEADCOVERSMOUTH | HEADCOVERSEYES - if("chest") - protection_needed = UPPER_TORSO - if("groin") - protection_needed = LOWER_TORSO - if("l_arm","r_arm") - protection_needed = ARMS - if("l_hand","r_hand") - protection_needed = HANDS - if("l_leg","r_leg") - protection_needed = LEGS - if("l_foot","r_foot") - protection_needed = FEET - - for(var/obj/item/clothing/clothes in target) - - if(target.l_hand == clothes|| target.r_hand == clothes) - continue - protection_needed &= ~(clothes.body_parts_covered) - if((clothes.slot_flags & SLOT_HEAD) || (clothes.slot_flags & SLOT_MASK)) - if(clothes.flags & HEADCOVERSEYES) - protection_needed &= ~(HEADCOVERSEYES) - if(clothes.flags & HEADCOVERSMOUTH) - protection_needed &= ~(HEADCOVERSMOUTH) - if(!protection_needed) //already got the needed protection, save some time and skip the rest of the loop - break - - if(!protection_needed) //properly protected, good job! - return - - to_chat(target, "You are stung by \the [fruit]!") - for(var/rid in chems) - var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/5)) - target.reagents.add_reagent(rid,injecting) - -//Splatter a turf. -/datum/seed/proc/splatter(var/turf/T,var/obj/item/thrown) - if(splat_type) - var/obj/effect/plant/splat = new splat_type(T, src) - if(!istype(splat)) // Plants handle their own stuff. - splat.name = "[thrown.name] [pick("smear","smudge","splatter")]" - var/clr - if(get_trait(TRAIT_BIOLUM)) - if(get_trait(TRAIT_BIOLUM_COLOUR)) - clr = get_trait(TRAIT_BIOLUM_COLOUR) - splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr) - if(get_trait(TRAIT_PRODUCT_COLOUR)) - splat.color = get_trait(TRAIT_PRODUCT_COLOUR) - - if(chems) - for(var/mob/living/M in T.contents) - if(!M.reagents) - continue - for(var/chem in chems) - var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3)) - M.reagents.add_reagent(chem,injecting) - -//Applies an effect to a target atom. -/datum/seed/proc/thrown_at(var/obj/item/thrown,var/atom/target, var/force_explode) - - var/splatted - var/turf/origin_turf = get_turf(target) - - if(force_explode || get_trait(TRAIT_EXPLOSIVE)) - - create_spores(origin_turf, thrown) - - var/flood_dist = min(10,max(1,get_trait(TRAIT_POTENCY)/15)) - var/list/open_turfs = list() - var/list/closed_turfs = list() - var/list/valid_turfs = list() - open_turfs |= origin_turf - - // Flood fill to get affected turfs. - while(open_turfs.len) - var/turf/T = pick(open_turfs) - open_turfs -= T - closed_turfs |= T - valid_turfs |= T - - for(var/dir in alldirs) - var/turf/neighbor = get_step(T,dir) - if(!neighbor || (neighbor in closed_turfs) || (neighbor in open_turfs)) - continue - if(neighbor.density || get_dist(neighbor,origin_turf) > flood_dist || istype(neighbor,/turf/space)) - closed_turfs |= neighbor - continue - // Check for windows. - var/no_los - var/turf/last_turf = origin_turf - for(var/turf/target_turf in getline(origin_turf,neighbor)) - if(!last_turf.Enter(thrown,target_turf) || target_turf.density) - no_los = 1 - break - last_turf = target_turf - if(!no_los && !origin_turf.Enter(thrown, neighbor)) - no_los = 1 - if(no_los) - closed_turfs |= neighbor - continue - open_turfs |= neighbor - - for(var/turf/T in valid_turfs) - for(var/mob/living/M in T.contents) - apply_special_effect(M) - splatter(T,thrown) - origin_turf.visible_message("The [thrown.name] explodes!") - qdel(thrown) - return - - if(istype(target,/mob/living)) - splatted = apply_special_effect(target,thrown) - else if(istype(target,/turf)) - splatted = 1 - for(var/mob/living/M in target.contents) - apply_special_effect(M) - - if(get_trait(TRAIT_JUICY) && splatted) - splatter(origin_turf,thrown) - origin_turf.visible_message("The [thrown.name] splatters against [target]!") - qdel(thrown) - -/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/obj/item/weapon/tank/holding, var/check_only) - - var/health_change = 0 - - if(!environment) //Someone called this without passing an environment. Punish their plant. - return -100 - - // Process it. - var/pressure - if(holding) //Check if we are running from an internal source (portable tank) - //Use the tank's distribution pressure or it's internal pressure (whichever is lower) for pressure checks - pressure = min(environment.return_pressure(), holding.distribute_pressure) - else //Not using an internal source - pressure = environment.return_pressure() - if(pressure < get_trait(TRAIT_LOWKPA_TOLERANCE)|| pressure > get_trait(TRAIT_HIGHKPA_TOLERANCE)) - health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER - - if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) > get_trait(TRAIT_HEAT_TOLERANCE)) - health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER - - // Handle gas consumption. - if(consume_gasses && consume_gasses.len) - var/missing_gas = 0 - for(var/gas in consume_gasses) - if(environment && environment.vars[gas] && environment.vars[gas] >= consume_gasses[gas]) - if(!check_only) - environment = adjust_gas(environment, gas,-consume_gasses[gas]) - else - missing_gas++ - - if(missing_gas > 0) - health_change += missing_gas * HYDRO_SPEED_MULTIPLIER - - // Handle gas production. - if(exude_gasses && exude_gasses.len && !check_only) - for(var/gas in exude_gasses) - environment = adjust_gas(environment, gas, max(1,round((exude_gasses[gas]*(get_trait(TRAIT_POTENCY)/5))/exude_gasses.len))) - - //Handle heat adjustment - if(get_trait(TRAIT_ALTER_TEMP)) - environment.temperature += get_trait(TRAIT_ALTER_TEMP) - if(environment.temperature < 0) //Make sure we didn't drop below absolute zero - environment.temperature = 0 //Set temperature back to zero if we did - - // Handle light requirements. - if(!light_supplied) - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in current_turf - if(L) - light_supplied = L.get_clamped_lum()*10 - else - light_supplied = 5 - - if(light_supplied) - if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE)) - health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER - - return health_change - -//Screw it, making a new proc for this for the sake of readability or something. --FalseIncarnate -/datum/seed/proc/adjust_gas(var/datum/gas_mixture/environment, var/gas, var/amount = 0) - if(!environment || !gas) //no gas_mixture or gas defined to adjust - return - - var/transfer_moles = environment.total_moles() - var/datum/gas_mixture/temp_holding - if(transfer_moles <= 0) //Check if the transfer_moles is an unacceptable value for the remove proc - //The environment is empty (or somehow has negative moles), create a new gas_mixture for temp_holding - temp_holding = new /datum/gas_mixture() - temp_holding.temperature = T20C - else - //The environment is acceptable, transfer it's contents into temp_holding - temp_holding = environment.remove(transfer_moles) - - if(!temp_holding) return //Just in case temp_holding has somehow avoided being set - - switch(gas) - if("oxygen") - temp_holding.oxygen += amount - if("nitrogen") - temp_holding.nitrogen += amount - if("carbon_dioxide") - temp_holding.carbon_dioxide += amount - if("toxins") - temp_holding.toxins += amount - - return environment.merge(temp_holding) - -/datum/seed/proc/apply_special_effect(var/mob/living/target,var/obj/item/thrown) - - var/impact = 1 - do_sting(target,thrown) - do_thorns(target,thrown) - - // Bluespace tomato code copied over from grown.dm. - if(get_trait(TRAIT_TELEPORTING)) - if(!is_teleport_allowed(target.z)) - return 1 - - //Plant potency determines radius of teleport. - var/outer_teleport_radius = get_trait(TRAIT_POTENCY)/5 - var/inner_teleport_radius = get_trait(TRAIT_POTENCY)/15 - - var/list/turfs = list() - if(inner_teleport_radius > 0) - for(var/turf/T in orange(target,outer_teleport_radius)) - if(get_dist(target,T) >= inner_teleport_radius) - turfs |= T - - if(turfs.len) - // Moves the mob, causes sparks. - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, get_turf(target)) - s.start() - var/turf/picked = get_turf(pick(turfs)) // Just in case... - new/obj/effect/decal/cleanable/molten_item(get_turf(target)) // Leave a pile of goo behind for dramatic effect... - target.loc = picked // And teleport them to the chosen location. - - impact = 1 - - return impact - -//Creates a random seed. MAKE SURE THE LINE HAS DIVERGED BEFORE THIS IS CALLED. -/datum/seed/proc/randomize() - - roundstart = 0 - // TODO: Better name generator - seed_name = "cultivar #[uid]" - display_name = "strange plants" // TODO: name generator. - base_name = seed_name - mysterious = 1 - seed_noun = pick("spores","nodes","cuttings","seeds") - modular_icon = 1 - - set_trait(TRAIT_POTENCY,rand(5,30),200,0) - set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.plant_product_sprites)) - set_trait(TRAIT_PLANT_ICON,pick(plant_controller.plant_sprites)) - set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]") - set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]") - update_growth_stages() - - if(prob(20)) - set_trait(TRAIT_HARVEST_REPEAT,1) - - if(prob(15)) - if(prob(15)) - set_trait(TRAIT_JUICY,2) - else - set_trait(TRAIT_JUICY,1) - - if(prob(5)) - set_trait(TRAIT_STINGS,1) - - if(prob(5)) - set_trait(TRAIT_PRODUCES_POWER,1) - - if(prob(1)) - set_trait(TRAIT_EXPLOSIVE,1) - else if(prob(1)) - set_trait(TRAIT_TELEPORTING,1) - - if(prob(5)) - consume_gasses = list() - var/gas = pick("oxygen","nitrogen","toxins","carbon_dioxide") - consume_gasses[gas] = rand(3,9) - - if(prob(5)) - exude_gasses = list() - var/gas = pick("oxygen","nitrogen","toxins","carbon_dioxide") - exude_gasses[gas] = rand(3,9) - - chems = list() - if(prob(80)) - var/nutrient_type = rand(1,7) - switch(nutrient_type) - if(1) - chems["plantmatter"] = list(rand(1,10),rand(10,20)) - if(2) - chems["nutriment"] = list(rand(1,10),rand(10,20)) - if(3) - chems["protein"] = list(rand(1,10),rand(10,20)) - if(4) - chems["plantmatter"] = list(rand(1,5),rand(10,20)) - chems["nutriment"] = list(rand(1,5),rand(10,20)) - if(5) - chems["plantmatter"] = list(rand(1,5),rand(10,20)) - chems["protein"] = list(rand(1,5),rand(10,20)) - if(6) - chems["protein"] = list(rand(1,5),rand(10,20)) - chems["nutriment"] = list(rand(1,5),rand(10,20)) - if(7) - chems["plantmatter"] = list(rand(1,3),rand(10,20)) - chems["nutriment"] = list(rand(1,4),rand(10,20)) - chems["protein"] = list(rand(1,3),rand(10,20)) - - var/additional_chems = rand(0,5) - - if(additional_chems) - for(var/x=1;x<=additional_chems;x++) - var/new_chem = get_random_chemical(1) - if(chems.Find(new_chem)) - chems[new_chem] = list(rand(2,20),rand(5,15)) //DOUBLE UP - else - chems[new_chem] = list(rand(1,10),rand(10,20)) - - if(prob(90)) - set_trait(TRAIT_REQUIRES_NUTRIENTS,1) - set_trait(TRAIT_NUTRIENT_CONSUMPTION,rand(25)/25) - else - set_trait(TRAIT_REQUIRES_NUTRIENTS,0) - - if(prob(90)) - set_trait(TRAIT_REQUIRES_WATER,1) - set_trait(TRAIT_WATER_CONSUMPTION,rand(10)) - else - set_trait(TRAIT_REQUIRES_WATER,0) - - set_trait(TRAIT_IDEAL_HEAT, rand(100,400)) - set_trait(TRAIT_HEAT_TOLERANCE, rand(10,30)) - set_trait(TRAIT_IDEAL_LIGHT, rand(2,10)) - set_trait(TRAIT_LIGHT_TOLERANCE, rand(2,7)) - set_trait(TRAIT_TOXINS_TOLERANCE, rand(2,7)) - set_trait(TRAIT_PEST_TOLERANCE, rand(2,7)) - set_trait(TRAIT_WEED_TOLERANCE, rand(2,7)) - set_trait(TRAIT_LOWKPA_TOLERANCE, rand(10,50)) - set_trait(TRAIT_HIGHKPA_TOLERANCE,rand(100,300)) - - if(prob(5)) - set_trait(TRAIT_ALTER_TEMP,rand(-5,5)) - - if(prob(1)) - set_trait(TRAIT_IMMUTABLE,-1) - - var/carnivore_prob = rand(100) - if(carnivore_prob < 5) - set_trait(TRAIT_CARNIVOROUS,2) - else if(carnivore_prob < 10) - set_trait(TRAIT_CARNIVOROUS,1) - - if(prob(10)) - set_trait(TRAIT_PARASITE,1) - - var/vine_prob = rand(100) - if(vine_prob < 5) - set_trait(TRAIT_SPREAD,2) - else if(vine_prob < 10) - set_trait(TRAIT_SPREAD,1) - - if(prob(5)) - set_trait(TRAIT_BIOLUM,1) - set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]") - - set_trait(TRAIT_ENDURANCE,rand(60,100)) - set_trait(TRAIT_YIELD,rand(3,15)) - set_trait(TRAIT_MATURATION,rand(5,15)) - set_trait(TRAIT_PRODUCTION,get_trait(TRAIT_MATURATION)+rand(2,5)) - -//Returns a key corresponding to an entry in the global seed list. -/datum/seed/proc/get_mutant_variant() - if(!mutants || !mutants.len || get_trait(TRAIT_IMMUTABLE) > 0) return 0 - return pick(mutants) - -//Mutates the plant overall (randomly). -/datum/seed/proc/mutate(var/degree,var/turf/source_turf) - - if(!degree || get_trait(TRAIT_IMMUTABLE) > 0) return - - source_turf.visible_message("\The [display_name] quivers!") - - //This looks like shit, but it's a lot easier to read/change this way. - var/total_mutations = rand(1,1+degree) - for(var/i = 0;i\The [display_name] withers rapidly!") - if(1) - set_trait(TRAIT_NUTRIENT_CONSUMPTION,get_trait(TRAIT_NUTRIENT_CONSUMPTION)+rand(-(degree*0.1),(degree*0.1)),5,0) - set_trait(TRAIT_WATER_CONSUMPTION, get_trait(TRAIT_WATER_CONSUMPTION) +rand(-degree,degree),50,0) - set_trait(TRAIT_JUICY, !get_trait(TRAIT_JUICY)) - set_trait(TRAIT_STINGS, !get_trait(TRAIT_STINGS)) - if(2) - set_trait(TRAIT_IDEAL_HEAT, get_trait(TRAIT_IDEAL_HEAT) + (rand(-5,5)*degree),800,70) - set_trait(TRAIT_HEAT_TOLERANCE, get_trait(TRAIT_HEAT_TOLERANCE) + (rand(-5,5)*degree),800,70) - set_trait(TRAIT_LOWKPA_TOLERANCE, get_trait(TRAIT_LOWKPA_TOLERANCE)+ (rand(-5,5)*degree),80,0) - set_trait(TRAIT_HIGHKPA_TOLERANCE, get_trait(TRAIT_HIGHKPA_TOLERANCE)+(rand(-5,5)*degree),500,110) - set_trait(TRAIT_EXPLOSIVE,1) - if(3) - set_trait(TRAIT_IDEAL_LIGHT, get_trait(TRAIT_IDEAL_LIGHT)+(rand(-1,1)*degree),30,0) - set_trait(TRAIT_LIGHT_TOLERANCE, get_trait(TRAIT_LIGHT_TOLERANCE)+(rand(-2,2)*degree),10,0) - if(4) - set_trait(TRAIT_TOXINS_TOLERANCE, get_trait(TRAIT_TOXINS_TOLERANCE)+(rand(-2,2)*degree),10,0) - if(5) - set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) - if(prob(degree*5)) - set_trait(TRAIT_CARNIVOROUS, get_trait(TRAIT_CARNIVOROUS)+rand(-degree,degree),2, 0) - if(get_trait(TRAIT_CARNIVOROUS)) - source_turf.visible_message("\The [display_name] shudders hungrily.") - if(6) - set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) - if(prob(degree*5)) - set_trait(TRAIT_PARASITE,!get_trait(TRAIT_PARASITE)) - if(7) - if(get_trait(TRAIT_YIELD) != -1) - set_trait(TRAIT_YIELD, get_trait(TRAIT_YIELD)+(rand(-2,2)*degree),10,0) - if(8) - set_trait(TRAIT_ENDURANCE, get_trait(TRAIT_ENDURANCE)+(rand(-5,5)*degree),100,10) - set_trait(TRAIT_PRODUCTION, get_trait(TRAIT_PRODUCTION)+(rand(-1,1)*degree),10, 1) - set_trait(TRAIT_POTENCY, get_trait(TRAIT_POTENCY)+(rand(-20,20)*degree),200, 0) - if(prob(degree*5)) - set_trait(TRAIT_SPREAD, get_trait(TRAIT_SPREAD)+rand(-1,1),2, 0) - source_turf.visible_message("\The [display_name] spasms visibly, shifting in the tray.") - if(9) - set_trait(TRAIT_MATURATION, get_trait(TRAIT_MATURATION)+(rand(-1,1)*degree),30, 0) - if(prob(degree*5)) - set_trait(TRAIT_HARVEST_REPEAT, !get_trait(TRAIT_HARVEST_REPEAT)) - if(10) - if(prob(degree*2)) - set_trait(TRAIT_BIOLUM, !get_trait(TRAIT_BIOLUM)) - if(get_trait(TRAIT_BIOLUM)) - source_turf.visible_message("\The [display_name] begins to glow!") - if(prob(degree*2)) - set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]") - source_turf.visible_message("\The [display_name]'s glow changes colour!") - else - source_turf.visible_message("\The [display_name]'s glow dims...") - if(11) - set_trait(TRAIT_TELEPORTING,1) - - return - -//Mutates a specific trait/set of traits. -/datum/seed/proc/apply_gene(var/datum/plantgene/gene) - - if(!gene || !gene.values || get_trait(TRAIT_IMMUTABLE) > 0) return - - // Splicing products has some detrimental effects on yield and lifespan. - // We handle this before we do the rest of the looping, as normal traits don't really include lists. - switch(gene.genetype) - if(GENE_BIOCHEMISTRY) - for(var/trait in list(TRAIT_YIELD, TRAIT_ENDURANCE)) - if(get_trait(trait) > 0) set_trait(trait,get_trait(trait),null,1,0.85) - - if(!chems) chems = list() - - var/list/gene_value = gene.values["[TRAIT_CHEMS]"] - for(var/rid in gene_value) - - var/list/gene_chem = gene_value[rid] - - if(!chems[rid]) - chems[rid] = gene_chem.Copy() - continue - - // Normally a length 2 list - but sometimes, it's length 1 - poisonberries, etc. - // This means the reagent does not scale with potency. - // Index 1 is the base value, index 2 is the potency per u of reagent - var/list/rgnt_list = chems[rid] - rgnt_list.len = max(gene_chem.len, rgnt_list.len) - - for(var/i=1;i<=gene_chem.len;i++) - - if(isnull(gene_chem[i])) gene_chem[i] = 0 - - if(rgnt_list[i]) - rgnt_list[i] = max(1,round((gene_chem[i] + rgnt_list[i])/2)) - else - rgnt_list[i] = gene_chem[i] - - var/list/new_gasses = gene.values["[TRAIT_EXUDE_GASSES]"] - if(islist(new_gasses)) - if(!exude_gasses) exude_gasses = list() - exude_gasses |= new_gasses - for(var/gas in exude_gasses) - exude_gasses[gas] = max(1,round(exude_gasses[gas]*0.8)) - - gene.values["[TRAIT_EXUDE_GASSES]"] = null - gene.values["[TRAIT_CHEMS]"] = null - - if(GENE_DIET) - var/list/new_gasses = gene.values["[TRAIT_CONSUME_GASSES]"] - consume_gasses |= new_gasses - gene.values["[TRAIT_CONSUME_GASSES]"] = null - if(GENE_METABOLISM) - preset_product = gene.values["alt_product"] - gene.values["alt_product"] = null - - for(var/trait in gene.values) - set_trait(trait,gene.values["[trait]"]) - - update_growth_stages() - -//Returns a list of the desired trait values. -/datum/seed/proc/get_gene(var/genetype) - - if(!genetype) return 0 - - var/list/traits_to_copy - var/datum/plantgene/P = new() - P.genetype = genetype - P.values = list() - - switch(genetype) - if(GENE_BIOCHEMISTRY) - P.values["[TRAIT_CHEMS]"] = chems - P.values["[TRAIT_EXUDE_GASSES]"] = exude_gasses - traits_to_copy = list(TRAIT_POTENCY) - if(GENE_OUTPUT) - traits_to_copy = list(TRAIT_PRODUCES_POWER,TRAIT_BIOLUM,TRAIT_BATTERY_RECHARGE) - if(GENE_ATMOSPHERE) - traits_to_copy = list(TRAIT_HEAT_TOLERANCE,TRAIT_LOWKPA_TOLERANCE,TRAIT_HIGHKPA_TOLERANCE) - if(GENE_HARDINESS) - traits_to_copy = list(TRAIT_TOXINS_TOLERANCE,TRAIT_PEST_TOLERANCE,TRAIT_WEED_TOLERANCE,TRAIT_ENDURANCE) - if(GENE_METABOLISM) - P.values["alt_product"] = preset_product - traits_to_copy = list(TRAIT_REQUIRES_NUTRIENTS,TRAIT_REQUIRES_WATER,TRAIT_ALTER_TEMP) - if(GENE_VIGOUR) - traits_to_copy = list(TRAIT_PRODUCTION,TRAIT_MATURATION,TRAIT_YIELD,TRAIT_SPREAD) - if(GENE_DIET) - P.values["[TRAIT_CONSUME_GASSES]"] = consume_gasses - traits_to_copy = list(TRAIT_CARNIVOROUS,TRAIT_PARASITE,TRAIT_NUTRIENT_CONSUMPTION,TRAIT_WATER_CONSUMPTION) - if(GENE_ENVIRONMENT) - traits_to_copy = list(TRAIT_IDEAL_HEAT,TRAIT_IDEAL_LIGHT,TRAIT_LIGHT_TOLERANCE) - if(GENE_PIGMENT) - traits_to_copy = list(TRAIT_PLANT_COLOUR,TRAIT_PRODUCT_COLOUR,TRAIT_BIOLUM_COLOUR) - if(GENE_STRUCTURE) - traits_to_copy = list(TRAIT_PLANT_ICON,TRAIT_PRODUCT_ICON,TRAIT_HARVEST_REPEAT) - if(GENE_FRUIT) - traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_JUICY) - if(GENE_SPECIAL) - traits_to_copy = list(TRAIT_TELEPORTING) - - for(var/trait in traits_to_copy) - P.values["[trait]"] = get_trait(trait) - return (P ? P : 0) - -//Place the plant products at the feet of the user. -/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount) - - if(!user) - return - - if(!force_amount && get_trait(TRAIT_YIELD) == 0 && !harvest_sample) - if(istype(user)) - to_chat(user, "You fail to harvest anything useful.") - else - if(istype(user)) - to_chat(user, "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name].") - - //This may be a new line. Update the global if it is. - if(name == "new line" || !(name in plant_controller.seeds)) - uid = plant_controller.seeds.len + 1 - name = "[uid]" - plant_controller.seeds[name] = src - - if(harvest_sample) - var/obj/item/seeds/seeds = new(get_turf(user)) - seeds.seed_type = name - seeds.update_seed() - return - - var/total_yield = 0 - if(!isnull(force_amount)) - total_yield = force_amount - else - if(get_trait(TRAIT_YIELD) > -1) - if(isnull(yield_mod) || yield_mod < 1) - yield_mod = 0 - total_yield = get_trait(TRAIT_YIELD) - else - total_yield = get_trait(TRAIT_YIELD) + rand(yield_mod) - total_yield = max(1,total_yield) - - currently_querying = list() - for(var/i = 0;iThe pod disgorges [product]!") - handle_living_product(product) - -// When the seed in this machine mutates/is modified, the tray seed value -// is set to a new datum copied from the original. This datum won't actually -// be put into the global datum list until the product is harvested, though. -/datum/seed/proc/diverge(var/modified = 0) - - if(get_trait(TRAIT_IMMUTABLE) > 0) return - - //Set up some basic information. - var/datum/seed/new_seed = new - new_seed.name = "new line" - new_seed.uid = 0 - new_seed.roundstart = 0 - new_seed.can_self_harvest = can_self_harvest - new_seed.kitchen_tag = kitchen_tag - new_seed.trash_type = trash_type - new_seed.preset_product = preset_product - new_seed.final_form = final_form - //Copy over everything else. - if(mutants) new_seed.mutants = mutants.Copy() - if(chems) new_seed.chems = chems.Copy() - if(consume_gasses) new_seed.consume_gasses = consume_gasses.Copy() - if(exude_gasses) new_seed.exude_gasses = exude_gasses.Copy() - new_seed.modular_icon = modular_icon - new_seed.preset_icon = preset_icon - - new_seed.base_name = base_name - new_seed.update_name_prefixes(modified) - - new_seed.seed_noun = seed_noun - new_seed.traits = traits.Copy() - new_seed.update_growth_stages() - return new_seed - -/datum/seed/proc/update_growth_stages() - if(get_trait(TRAIT_PLANT_ICON)) - growth_stages = plant_controller.plant_sprites[get_trait(TRAIT_PLANT_ICON)] - else - growth_stages = 0 - -/datum/seed/proc/update_name_prefixes(var/modified = 0) - if(last_diverge_type == modified) - //We already match the new prefix, so we're not going to bother - return - //Since we don't match, set the last_diverge type to the modified value, then handle the new prefix - last_diverge_type = modified - switch(modified) - if(0) //Mutant (default) - seed_name = "mutant [base_name]" - display_name = "mutant [base_name]" - if(1) //Modified - seed_name = "modified [base_name]" - display_name = "modified [base_name]" - if(2) //Enhanced - seed_name = "enhanced [base_name]" - display_name = "enhanced [base_name]" diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm deleted file mode 100644 index 7e56c57a45f..00000000000 --- a/code/modules/hydroponics/seed_controller.dm +++ /dev/null @@ -1,153 +0,0 @@ -// Attempts to offload processing for the spreading plants from the MC. -// Processes vines/spreading plants. - -#define PLANTS_PER_TICK 500 // Cap on number of plant segments processed. -#define PLANT_TICK_TIME 75 // Number of ticks between the plant processor cycling. - -// Debug for testing seed genes (less useful now that the obfuscation is gone, but still might be useful for the future. -/client/proc/show_plant_genes() - set category = "Debug" - set name = "Show Plant Genes" - set desc = "Prints the round's plant gene tags." - - if(!holder) return - - if(!plant_controller || !plant_controller.gene_tag_list) - to_chat(usr, "Gene tags not set.") - return - - for(var/gene_tag in plant_controller.gene_tag_list) - to_chat(usr, "[gene_tag]") - -var/global/datum/controller/plants/plant_controller // Set in New(). - -/datum/controller/plants - - var/plants_per_tick = PLANTS_PER_TICK - var/plant_tick_time = PLANT_TICK_TIME - var/list/product_descs = list() // Stores generated fruit descs. - var/list/plant_queue = list() // All queued plants. - var/list/seeds = list() // All seed data stored here. - var/list/gene_tag_list = list() // List of gene tags for xenobotany fun - var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds. - var/list/plant_sprites = list() // List of all harvested product sprites. - var/list/plant_product_sprites = list() // List of all growth sprites plus number of growth stages. - //var/processing = 0 // Off/on. - -/datum/controller/plants/New() - if(plant_controller && plant_controller != src) - log_debug("Rebuilding plant controller.") - qdel(plant_controller) - plant_controller = src - setup() - process() - -/datum/controller/plants/Destroy() - ..() - return QDEL_HINT_HARDDEL_NOW - -// Predefined/roundstart varieties use a string key to make it -// easier to grab the new variety when mutating. Post-roundstart -// and mutant varieties use their uid converted to a string instead. -// Looks like shit but it's sort of necessary. -/datum/controller/plants/proc/setup() - - // Build the icon lists. - for(var/icostate in icon_states('icons/obj/hydroponics_growing.dmi')) - var/split = findtext(icostate,"-") - if(!split) - // invalid icon_state - continue - - var/ikey = copytext(icostate,(split+1)) - if(ikey == "dead") - // don't count dead icons - continue - ikey = text2num(ikey) - var/base = copytext(icostate,1,split) - - if(!(plant_sprites[base]) || (plant_sprites[base]= max_seeds) + break + ++loaded + add_seed(G) + if (loaded) + to_chat(user, "You put the seeds from \the [O.name] into [src].") + else + to_chat(user, "There are no seeds in \the [O.name].") + return + + else if(seedify(O,-1, src, user)) + to_chat(user, "You extract some seeds.") + return + else if (istype(O,/obj/item/seeds)) + if(add_seed(O)) + to_chat(user, "You add [O] to [name].") + updateUsrDialog() + return + else if(user.a_intent != I_HARM) + to_chat(user, "You can't extract any seeds from \the [O.name]!") + else + return ..() + +/datum/seed_pile + var/name = "" + var/lifespan = 0 //Saved stats + var/endurance = 0 + var/maturation = 0 + var/production = 0 + var/yield = 0 + var/potency = 0 + var/amount = 0 + +/datum/seed_pile/New(var/name, var/life, var/endur, var/matur, var/prod, var/yie, var/poten, var/am = 1) + src.name = name + src.lifespan = life + src.endurance = endur + src.maturation = matur + src.production = prod + src.yield = yie + src.potency = poten + src.amount = am + +/obj/machinery/seed_extractor/attack_hand(mob/user) + user.set_machine(src) + interact(user) + +/obj/machinery/seed_extractor/interact(mob/user) + if (stat) + return 0 + + var/dat = "Stored seeds:
" + + if (contents.len == 0) + dat += "No seeds" + else + dat += "" + for (var/datum/seed_pile/O in piles) + dat += "" + dat += "" + dat += "
NameLifespanEnduranceMaturationProductionYieldPotencyStock
[O.name][O.lifespan][O.endurance][O.maturation][O.production][O.yield][O.potency]" + dat += "Vend ([O.amount] left)
" + var/datum/browser/popup = new(user, "seed_ext", name, 700, 400) + popup.set_content(dat) + popup.open() + return + +/obj/machinery/seed_extractor/Topic(var/href, var/list/href_list) + if(..()) + return + usr.set_machine(src) + + href_list["li"] = text2num(href_list["li"]) + href_list["en"] = text2num(href_list["en"]) + href_list["ma"] = text2num(href_list["ma"]) + href_list["pr"] = text2num(href_list["pr"]) + href_list["yi"] = text2num(href_list["yi"]) + href_list["pot"] = text2num(href_list["pot"]) + + for (var/datum/seed_pile/N in piles)//Find the pile we need to reduce... + if (href_list["name"] == N.name && href_list["li"] == N.lifespan && href_list["en"] == N.endurance && href_list["ma"] == N.maturation && href_list["pr"] == N.production && href_list["yi"] == N.yield && href_list["pot"] == N.potency) + if(N.amount <= 0) + return + N.amount = max(N.amount - 1, 0) + if (N.amount <= 0) + piles -= N + qdel(N) + break + + for (var/obj/T in contents)//Now we find the seed we need to vend + var/obj/item/seeds/O = T + if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) + O.forceMove(loc) + break + + updateUsrDialog() + return + +/obj/machinery/seed_extractor/proc/add_seed(obj/item/seeds/O) + if(contents.len >= 999) + to_chat(usr, "\The [src] is full.") + return 0 + + if(istype(O.loc,/mob)) + var/mob/M = O.loc + if(!M.drop_item()) + return 0 + else if(istype(O.loc,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = O.loc + S.remove_from_storage(O,src) + + O.forceMove(src) + . = 1 + for (var/datum/seed_pile/N in piles) + if (O.plantname == N.name && O.lifespan == N.lifespan && O.endurance == N.endurance && O.maturation == N.maturation && O.production == N.production && O.yield == N.yield && O.potency == N.potency) + ++N.amount + return + + piles += new /datum/seed_pile(O.plantname, O.lifespan, O.endurance, O.maturation, O.production, O.yield, O.potency) + return diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm deleted file mode 100644 index 7e21e12370e..00000000000 --- a/code/modules/hydroponics/seed_machines.dm +++ /dev/null @@ -1,377 +0,0 @@ -/obj/item/weapon/disk/botany - name = "flora data disk" - desc = "A small disk used for carrying data on plant genetics." - icon = 'icons/obj/hydroponics_machines.dmi' - icon_state = "disk" - w_class = 1 - - var/list/genes = list() - var/genesource = "unknown" - -/obj/item/weapon/disk/botany/New() - ..() - pixel_x = rand(-5,5) - pixel_y = rand(-5,5) - -/obj/item/weapon/disk/botany/attack_self(var/mob/user as mob) - if(genes.len) - var/choice = alert(user, "Are you sure you want to wipe the disk?", "Xenobotany Data", "No", "Yes") - if(src && user && genes && choice && choice == "Yes" && user.Adjacent(get_turf(src))) - to_chat(user, "You wipe the disk data.") - name = initial(name) - desc = initial(name) - genes = list() - genesource = "unknown" - -/obj/item/weapon/storage/box/botanydisk - name = "flora disk box" - desc = "A box of flora data disks, apparently." - -/obj/item/weapon/storage/box/botanydisk/New() - ..() - for(var/i = 0;i<7;i++) - new /obj/item/weapon/disk/botany(src) - -/obj/machinery/botany - icon = 'icons/obj/hydroponics_machines.dmi' - icon_state = "hydrotray3" - density = 1 - anchored = 1 - use_power = 1 - - var/obj/item/seeds/seed // Currently loaded seed packet. - var/obj/item/weapon/disk/botany/loaded_disk //Currently loaded data disk. - - var/open = 0 - var/active = 0 - var/action_time = 5 - var/last_action = 0 - var/eject_disk = 0 - var/failed_task = 0 - var/disk_needs_genes = 0 - -/obj/machinery/botany/process() - - ..() - if(!active) return - - if(world.time > last_action + action_time) - finished_task() - -/obj/machinery/botany/attack_ai(mob/user as mob) - return attack_hand(user) - -/obj/machinery/botany/attack_hand(mob/user as mob) - ui_interact(user) - -/obj/machinery/botany/proc/finished_task() - active = 0 - if(failed_task) - failed_task = 0 - visible_message("[bicon(src)] [src] pings unhappily, flashing a red warning light.") - else - visible_message("[bicon(src)] [src] pings happily.") - - if(eject_disk) - eject_disk = 0 - if(loaded_disk) - loaded_disk.loc = get_turf(src) - visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") - loaded_disk = null - -/obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/seeds)) - if(seed) - to_chat(user, "There is already a seed loaded.") - return - var/obj/item/seeds/S =W - if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0) - to_chat(user, "That seed is not compatible with our genetics technology.") - else - user.drop_item(W) - W.loc = src - seed = W - to_chat(user, "You load [W] into [src].") - return - - if(istype(W,/obj/item/weapon/screwdriver)) - open = !open - to_chat(user, "You [open ? "open" : "close"] the maintenance panel.") - return - - if(open) - if(istype(W, /obj/item/weapon/crowbar)) - dismantle() - return - - if(istype(W,/obj/item/weapon/disk/botany)) - if(loaded_disk) - to_chat(user, "There is already a data disk loaded.") - return - else - var/obj/item/weapon/disk/botany/B = W - - if(B.genes && B.genes.len) - if(!disk_needs_genes) - to_chat(user, "That disk already has gene data loaded.") - return - else - if(disk_needs_genes) - to_chat(user, "That disk does not have any gene data loaded.") - return - - user.drop_item(W) - W.loc = src - loaded_disk = W - to_chat(user, "You load [W] into [src].") - - return - ..() - -// Allows for a trait to be extracted from a seed packet, destroying that seed. -/obj/machinery/botany/extractor - name = "lysis-isolation centrifuge" - icon_state = "traitcopier" - - var/datum/seed/genetics // Currently scanned seed genetic structure. - var/degradation = 0 // Increments with each scan, stops allowing gene mods after a certain point. - - var/degrade_lower = 20 - var/degrade_upper = 60 - -/obj/machinery/botany/extractor/New() - ..() - - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/botany_extractor(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/scanning_module(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/botany/extractor/RefreshParts() - var/tier = 1 - for(var/obj/item/weapon/stock_parts/scanning_module/S in component_parts) - tier = S.rating - degrade_lower = 25 - (tier * 5) //Tier 1: 20, Tier 4: 5 - degrade_upper = 70 - (tier * 10) //Tier 1: 60, Tier 4: 30 - -/obj/machinery/botany/extractor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!user) - return - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "botany_isolator.tmpl", "Lysis-isolation Centrifuge UI", 470, 450) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/botany/extractor/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) - var/data[0] - - var/list/geneMasks[0] - for(var/gene_tag in plant_controller.gene_tag_list) - geneMasks.Add(gene_tag) - data["geneMasks"] = geneMasks - - data["activity"] = active - data["degradation"] = degradation - - if(loaded_disk) - data["disk"] = 1 - else - data["disk"] = 0 - - if(seed) - data["loaded"] = "[seed.name]" - else - data["loaded"] = 0 - - if(genetics) - data["hasGenetics"] = 1 - data["sourceName"] = genetics.display_name - if(!genetics.roundstart) - data["sourceName"] += " (variety #[genetics.uid])" - else - data["hasGenetics"] = 0 - data["sourceName"] = 0 - - return data - -/obj/machinery/botany/Topic(href, href_list) - - if(..()) - return 1 - - if(href_list["eject_packet"]) - if(!seed) return - seed.loc = get_turf(src) - - if(seed.seed.name == "new line" || isnull(plant_controller.seeds[seed.seed.name])) - seed.seed.uid = plant_controller.seeds.len + 1 - seed.seed.name = "[seed.seed.uid]" - plant_controller.seeds[seed.seed.name] = seed.seed - - seed.update_seed() - visible_message("[bicon(src)] [src] beeps and spits out [seed].") - - seed = null - - if(href_list["eject_disk"]) - if(!loaded_disk) return - loaded_disk.loc = get_turf(src) - visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") - loaded_disk = null - - usr.set_machine(src) - src.add_fingerprint(usr) - -/obj/machinery/botany/extractor/Topic(href, href_list) - - if(..()) - return 1 - - usr.set_machine(src) - src.add_fingerprint(usr) - - if(href_list["scan_genome"]) - - if(!seed) return - - last_action = world.time - active = 1 - - if(seed && seed.seed) - genetics = seed.seed - degradation = 0 - - qdel(seed) - seed = null - - if(href_list["get_gene"]) - - if(!genetics || !loaded_disk) return - - last_action = world.time - active = 1 - - var/datum/plantgene/P = genetics.get_gene(href_list["get_gene"]) - if(!P) return - loaded_disk.genes += P - - loaded_disk.genesource = "[genetics.display_name]" - if(!genetics.roundstart) - loaded_disk.genesource += " (variety #[genetics.uid])" - - loaded_disk.name += " ([href_list["get_gene"]], #[genetics.uid])" - loaded_disk.desc += " The label reads \'[href_list["get_gene"]] gene, sampled from [genetics.display_name]\'." - eject_disk = 1 - - degradation += rand(degrade_lower, degrade_upper) - if(degradation >= 100) - failed_task = 1 - genetics = null - degradation = 0 - - if(href_list["clear_buffer"]) - if(!genetics) return - genetics = null - degradation = 0 - - src.updateUsrDialog() - return - -// Fires an extracted trait into another packet of seeds with a chance -// of destroying it based on the size/complexity of the plasmid. -/obj/machinery/botany/editor - name = "bioballistic delivery system" - icon_state = "traitgun" - disk_needs_genes = 1 - - var/degrade_lower = 5 - var/degrade_upper = 10 - -/obj/machinery/botany/editor/New() - ..() - - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/botany_editor(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - RefreshParts() - -/obj/machinery/botany/editor/RefreshParts() - var/tier = 1 - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - tier = M.rating - degrade_lower = 6 - tier //Tier 1: 5, Tier 4: 1 - degrade_upper = 11 - tier //Tier 1: 10, Tier 4: 6 - -/obj/machinery/botany/editor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(!user) - return - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "botany_editor.tmpl", "Bioballistic Delivery UI", 470, 450) - ui.open() - ui.set_auto_update(1) - -/obj/machinery/botany/editor/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) - var/data[0] - - data["activity"] = active - - if(seed) - data["degradation"] = seed.modified - else - data["degradation"] = 0 - - if(loaded_disk && loaded_disk.genes.len) - data["disk"] = 1 - data["sourceName"] = loaded_disk.genesource - data["locus"] = "" - - for(var/datum/plantgene/P in loaded_disk.genes) - if(data["locus"] != "") data["locus"] += ", " - data["locus"] += "[plant_controller.gene_tag_list[P.genetype]]" - - else - data["disk"] = 0 - data["sourceName"] = 0 - data["locus"] = 0 - - if(seed) - data["loaded"] = "[seed.name]" - else - data["loaded"] = 0 - - return data - -/obj/machinery/botany/editor/Topic(href, href_list) - - if(..()) - return 1 - - if(href_list["apply_gene"]) - if(!loaded_disk || !seed) return - - last_action = world.time - active = 1 - - if(!isnull(plant_controller.seeds[seed.seed.name])) - seed.seed = seed.seed.diverge(1) - seed.seed_type = seed.seed.name - seed.update_seed() - - if(prob(seed.modified)) - failed_task = 1 - seed.modified = 101 - - for(var/datum/plantgene/gene in loaded_disk.genes) - seed.seed.apply_gene(gene) - seed.modified += rand(degrade_lower, degrade_upper) - - usr.set_machine(src) - src.add_fingerprint(usr) diff --git a/code/modules/hydroponics/seed_mobs.dm b/code/modules/hydroponics/seed_mobs.dm deleted file mode 100644 index 57579a3a797..00000000000 --- a/code/modules/hydroponics/seed_mobs.dm +++ /dev/null @@ -1,5 +0,0 @@ -/datum/seed - var/list/currently_querying // Used to avoid asking the same ghost repeatedly. - -// The following procs are used to grab players for mobs produced by a seed (mostly for dionaea). -/datum/seed/proc/handle_living_product(var/mob/living/host) \ No newline at end of file diff --git a/code/modules/hydroponics/seed_packets.dm b/code/modules/hydroponics/seed_packets.dm deleted file mode 100644 index 244b9fef8f3..00000000000 --- a/code/modules/hydroponics/seed_packets.dm +++ /dev/null @@ -1,315 +0,0 @@ -var/global/list/plant_seed_sprites = list() - -//Seed packet object/procs. -/obj/item/seeds - name = "packet of seeds" - icon = 'icons/obj/seeds.dmi' - icon_state = "blank" - w_class = 2 - burn_state = FLAMMABLE - var/seed_type - var/datum/seed/seed - var/modified = 0 - -/obj/item/seeds/New() - while(!plant_controller) - sleep(30) - update_seed() - ..() - -//Grabs the appropriate seed datum from the global list. -/obj/item/seeds/proc/update_seed() - if(!seed && seed_type && !isnull(plant_controller.seeds) && plant_controller.seeds[seed_type]) - seed = plant_controller.seeds[seed_type] - update_appearance() - -//Updates strings and icon appropriately based on seed datum. -/obj/item/seeds/proc/update_appearance() - if(!seed) return - - // Update icon. - overlays.Cut() - var/is_seeds = ((seed.seed_noun in list("seeds","pits","nodes")) ? 1 : 0) - var/image/seed_mask - var/seed_base_key = "base-[is_seeds ? seed.get_trait(TRAIT_PLANT_COLOUR) : "spores"]" - if(plant_seed_sprites[seed_base_key]) - seed_mask = plant_seed_sprites[seed_base_key] - else - seed_mask = image('icons/obj/seeds.dmi',"[is_seeds ? "seed" : "spore"]-mask") - if(is_seeds) // Spore glass bits aren't coloured. - seed_mask.color = seed.get_trait(TRAIT_PLANT_COLOUR) - plant_seed_sprites[seed_base_key] = seed_mask - - var/image/seed_overlay - var/seed_overlay_key = "[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]" - if(plant_seed_sprites[seed_overlay_key]) - seed_overlay = plant_seed_sprites[seed_overlay_key] - else - seed_overlay = image('icons/obj/seeds.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]") - seed_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) - plant_seed_sprites[seed_overlay_key] = seed_overlay - - overlays |= seed_mask - overlays |= seed_overlay - - if(is_seeds) - src.name = "packet of [seed.seed_name] [seed.seed_noun]" - src.desc = "It has a picture of [seed.display_name] on the front." - else - src.name = "sample of [seed.seed_name] [seed.seed_noun]" - src.desc = "It's labelled as coming from [seed.display_name]." - -/obj/item/seeds/examine(mob/user) - ..(user) - if(seed && !seed.roundstart) - to_chat(user, "It's tagged as variety #[seed.uid].") - -/obj/item/seeds/cutting - name = "cuttings" - desc = "Some plant cuttings." - -/obj/item/seeds/cutting/update_appearance() - ..() - src.name = "packet of [seed.seed_name] cuttings" - -/obj/item/seeds/random - seed_type = null - -/obj/item/seeds/random/New() - seed = plant_controller.create_random_seed() - seed_type = seed.name - update_seed() - -/obj/item/seeds/replicapod - seed_type = "diona" - -/obj/item/seeds/chiliseed - seed_type = "chili" - -/obj/item/seeds/plastiseed - seed_type = "plastic" - -/obj/item/seeds/grapeseed - seed_type = "grapes" - -/obj/item/seeds/greengrapeseed - seed_type = "greengrapes" - -/obj/item/seeds/peanutseed - seed_type = "peanut" - -/obj/item/seeds/cabbageseed - seed_type = "cabbage" - -/obj/item/seeds/comfreyseed - seed_type = "comfrey" - -/obj/item/seeds/aloeseed - seed_type = "aloe" - -/obj/item/seeds/berryseed - seed_type = "berries" - -/obj/item/seeds/glowberryseed - seed_type = "glowberries" - -/obj/item/seeds/bananaseed - seed_type = "banana" - -/obj/item/seeds/eggplantseed - seed_type = "eggplant" - -/obj/item/seeds/bloodtomatoseed - seed_type = "bloodtomato" - -/obj/item/seeds/tomatoseed - seed_type = "tomato" - -/obj/item/seeds/killertomatoseed - seed_type = "killertomato" - -/obj/item/seeds/bluetomatoseed - seed_type = "bluetomato" - -/obj/item/seeds/bluespacetomatoseed - seed_type = "bluespacetomato" - -/obj/item/seeds/cornseed - seed_type = "corn" - -/obj/item/seeds/poppyseed - seed_type = "poppies" - -/obj/item/seeds/potatoseed - seed_type = "potato" - -/obj/item/seeds/icepepperseed - seed_type = "icechili" - -/obj/item/seeds/soyaseed - seed_type = "soybean" - -/obj/item/seeds/wheatseed - seed_type = "wheat" - -/obj/item/seeds/riceseed - seed_type = "rice" - -/obj/item/seeds/carrotseed - seed_type = "carrot" - -/obj/item/seeds/reishimycelium - seed_type = "reishi" - -/obj/item/seeds/amanitamycelium - seed_type = "amanita" - -/obj/item/seeds/angelmycelium - seed_type = "destroyingangel" - -/obj/item/seeds/libertymycelium - seed_type = "libertycap" - -/obj/item/seeds/chantermycelium - seed_type = "mushrooms" - -/obj/item/seeds/towermycelium - seed_type = "towercap" - -/obj/item/seeds/glowshroom - seed_type = "glowshroom" - -/obj/item/seeds/glowcap - seed_type = "glowcap" - -/obj/item/seeds/plumpmycelium - seed_type = "plumphelmet" - -/obj/item/seeds/walkingmushroommycelium - seed_type = "walkingmushroom" - -/obj/item/seeds/nettleseed - seed_type = "nettle" - -/obj/item/seeds/deathnettleseed - seed_type = "deathnettle" - -/obj/item/seeds/weeds - seed_type = "weeds" - -/obj/item/seeds/harebell - seed_type = "harebells" - -/obj/item/seeds/sunflowerseed - seed_type = "sunflowers" - -/obj/item/seeds/brownmold - seed_type = "mold" - -/obj/item/seeds/appleseed - seed_type = "apple" - -/obj/item/seeds/poisonedappleseed - seed_type = "poisonapple" - -/obj/item/seeds/goldappleseed - seed_type = "goldapple" - -/obj/item/seeds/ambrosiavulgarisseed - seed_type = "ambrosia" - -/obj/item/seeds/ambrosiadeusseed - seed_type = "ambrosiadeus" - -/obj/item/seeds/ambrosiavulgarisseed/cruciatus - seed_type = "ambrosia" - -/obj/item/seeds/whitebeetseed - seed_type = "whitebeet" - -/obj/item/seeds/sugarcaneseed - seed_type = "sugarcane" - -/obj/item/seeds/watermelonseed - seed_type = "watermelon" - -/obj/item/seeds/pumpkinseed - seed_type = "pumpkin" - -/obj/item/seeds/limeseed - seed_type = "lime" - -/obj/item/seeds/lemonseed - seed_type = "lemon" - -/obj/item/seeds/orangeseed - seed_type = "orange" - -/obj/item/seeds/poisonberryseed - seed_type = "poisonberries" - -/obj/item/seeds/deathberryseed - seed_type = "deathberries" - -/obj/item/seeds/grassseed - seed_type = "grass" - -/obj/item/seeds/cocoapodseed - seed_type = "cocoa" - -/obj/item/seeds/cherryseed - seed_type = "cherry" - -/obj/item/seeds/tobaccoseed - seed_type = "tobacco" - -/obj/item/seeds/kudzuseed - seed_type = "kudzu" - -/obj/item/seeds/jurlmah - seed_type = "jurlmah" - -/obj/item/seeds/amauri - seed_type = "amauri" - -/obj/item/seeds/gelthi - seed_type = "gelthi" - -/obj/item/seeds/vale - seed_type = "vale" - -/obj/item/seeds/surik - seed_type = "surik" - -/obj/item/seeds/telriis - seed_type = "telriis" - -/obj/item/seeds/thaadra - seed_type = "thaadra" - -/obj/item/seeds/clown - seed_type = "clown" - -/obj/item/seeds/test - seed_type = "test" - -/obj/item/seeds/test2 - seed_type = "test2" - -/obj/item/seeds/stobaccoseed - seed_type = "stobacco" - -/obj/item/seeds/teaasperaseed - seed_type = "teaaspera" - -/obj/item/seeds/teaastraseed - seed_type = "teaastra" - -/obj/item/seeds/coffeeaseed - seed_type = "coffeea" - -/obj/item/seeds/coffeerseed - seed_type = "coffeer" - -/obj/item/seeds/cash - seed_type = "cashtree" \ No newline at end of file diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm deleted file mode 100644 index 8c2924db35e..00000000000 --- a/code/modules/hydroponics/seed_storage.dm +++ /dev/null @@ -1,245 +0,0 @@ -/datum/seed_pile - var/name - var/amount - var/datum/seed/seed_type // Keeps track of what our seed is - var/list/obj/item/seeds/seeds = list() // Tracks actual objects contained in the pile - var/ID - -/datum/seed_pile/New(var/obj/item/seeds/O, var/ID) - name = O.name - amount = 1 - seed_type = O.seed - seeds += O - src.ID = ID - -/datum/seed_pile/proc/matches(var/obj/item/seeds/O) - if(O.seed == seed_type) - return 1 - return 0 - -/obj/machinery/seed_storage - name = "Seed storage" - desc = "It stores, sorts, and dispenses seeds." - icon = 'icons/obj/vending.dmi' - icon_state = "seeds" - density = 1 - anchored = 1 - use_power = 1 - idle_power_usage = 100 - - var/initialized = 0 // Map-placed ones break if seeds are loaded right at the start of the round, so we do it on the first interaction - var/list/datum/seed_pile/piles = list() - var/list/starting_seeds = list() - var/list/scanner = list() // What properties we can view - -/obj/machinery/seed_storage/random // This is mostly for testing, but I guess admins could spawn it - name = "Random seed storage" - scanner = list("stats", "produce", "soil", "temperature", "light") - starting_seeds = list(/obj/item/seeds/random = 50) - -/obj/machinery/seed_storage/garden - name = "Garden seed storage" - scanner = list("stats") - starting_seeds = list(/obj/item/seeds/appleseed = 3, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/limeseed = 3, /obj/item/seeds/aloeseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/comfreyseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) - -/obj/machinery/seed_storage/xenobotany - name = "Xenobotany seed storage" - scanner = list("stats", "produce", "soil", "temperature", "light") - starting_seeds = list(/obj/item/seeds/ambrosiavulgarisseed = 3, /obj/item/seeds/appleseed = 3, /obj/item/seeds/amanitamycelium = 2, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/libertymycelium = 2, /obj/item/seeds/limeseed = 3, /obj/item/seeds/aloeseed = 2, /obj/item/seeds/nettleseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plastiseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/comfreyseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) - -/obj/machinery/seed_storage/attack_hand(mob/user as mob) - user.set_machine(src) - interact(user) - -/obj/machinery/seed_storage/interact(mob/user as mob) - if(..()) - return - - if(!initialized) - for(var/typepath in starting_seeds) - var/amount = starting_seeds[typepath] - if(isnull(amount)) amount = 1 - - for(var/i = 1 to amount) - var/O = new typepath - add(O) - initialized = 1 - - var/dat = "

Seed storage contents

" - if(piles.len == 0) - dat += "No seeds" - else - dat += "" - dat += "" - if("stats" in scanner) - dat += "" - if("temperature" in scanner) - dat += "" - if("light" in scanner) - dat += "" - if("soil" in scanner) - dat += "" - dat += "" - for(var/datum/seed_pile/S in piles) - var/datum/seed/seed = S.seed_type - if(!seed) - continue - dat += "" - dat += "" - dat += "" - if("stats" in scanner) - dat += "" - if(seed.get_trait(TRAIT_HARVEST_REPEAT)) - dat += "" - else - dat += "" - if("temperature" in scanner) - dat += "" - if("light" in scanner) - dat += "" - if("soil" in scanner) - if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) - if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) - dat += "" - else if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS) > 0.2) - dat += "" - else - dat += "" - else - dat += "" - if(seed.get_trait(TRAIT_REQUIRES_WATER)) - if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) - dat += "" - else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) - dat += "" - else - dat += "" - else - dat += "" - - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
NameVarietyEYMPrPtHarvestTempLightNutriWaterNotesAmount
[seed.seed_name]#[seed.uid][seed.get_trait(TRAIT_ENDURANCE)][seed.get_trait(TRAIT_YIELD)][seed.get_trait(TRAIT_MATURATION)][seed.get_trait(TRAIT_PRODUCTION)][seed.get_trait(TRAIT_POTENCY)]MultipleSingle[seed.get_trait(TRAIT_IDEAL_HEAT)] K[seed.get_trait(TRAIT_IDEAL_LIGHT)] LLowHighNormNoLowHighNormNo" - switch(seed.get_trait(TRAIT_CARNIVOROUS)) - if(1) - dat += "CARN " - if(2) - dat += "CARN " - switch(seed.get_trait(TRAIT_SPREAD)) - if(1) - dat += "VINE " - if(2) - dat += "VINE " - if("pressure" in scanner) - if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) - dat += "LP " - if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) - dat += "HP " - if("temperature" in scanner) - if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) - dat += "TEMRES " - else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) - dat += "TEMSEN " - if("light" in scanner) - if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) - dat += "LIGRES " - else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) - dat += "LIGSEN " - if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) - dat += "TOXSEN " - else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) - dat += "TOXRES " - if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) - dat += "PESTSEN " - else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) - dat += "PESTRES " - if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) - dat += "WEEDSEN " - else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) - dat += "WEEDRES " - if(seed.get_trait(TRAIT_PARASITE)) - dat += "PAR " - if("temperature" in scanner) - if(seed.get_trait(TRAIT_ALTER_TEMP) > 0) - dat += "TEMP+ " - if(seed.get_trait(TRAIT_ALTER_TEMP) < 0) - dat += "TEMP- " - if(seed.get_trait(TRAIT_BIOLUM)) - dat += "LUM " - dat += "[S.amount]Vend Purge
" - - user << browse(dat, "window=seedstorage") - onclose(user, "seedstorage") - -/obj/machinery/seed_storage/Topic(var/href, var/list/href_list) - if(..()) - return - var/task = href_list["task"] - var/ID = text2num(href_list["id"]) - - for(var/datum/seed_pile/N in piles) - if(N.ID == ID) - if(task == "vend") - var/obj/O = pick(N.seeds) - if(O) - --N.amount - N.seeds -= O - if(N.amount <= 0 || N.seeds.len <= 0) - piles -= N - qdel(N) - O.loc = src.loc - else - piles -= N - qdel(N) - else if(task == "purge") - for(var/obj/O in N.seeds) - qdel(O) - piles -= N - qdel(N) - break - updateUsrDialog() - -/obj/machinery/seed_storage/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/seeds)) - add(O) - user.visible_message("[user] puts \the [O.name] into \the [src].", "You put \the [O] into \the [src].") - return - else if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/P = O - var/loaded = 0 - for(var/obj/item/seeds/G in P.contents) - ++loaded - add(G) - if(loaded) - user.visible_message("[user] puts the seeds from \the [O.name] into \the [src].", "You put the seeds from \the [O.name] into \the [src].") - else - to_chat(user, "There are no seeds in \the [O.name].") - return - else if(istype(O, /obj/item/weapon/wrench)) - playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) - anchored = !anchored - to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].") - -/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O as obj) - if(istype(O.loc, /mob)) - var/mob/user = O.loc - user.drop_item(O) - else if(istype(O.loc,/obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = O.loc - S.remove_from_storage(O, src) - - O.loc = src - var/newID = 0 - - for(var/datum/seed_pile/N in piles) - if(N.matches(O)) - ++N.amount - N.seeds += (O) - return - else if(N.ID >= newID) - newID = N.ID + 1 - - piles += new /datum/seed_pile(O, newID) - return diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm new file mode 100644 index 00000000000..d35621e4c59 --- /dev/null +++ b/code/modules/hydroponics/seeds.dm @@ -0,0 +1,386 @@ +// ******************************************************** +// Here's all the seeds (plants) that can be used in hydro +// ******************************************************** + +/obj/item/seeds + icon = 'icons/obj/hydroponics/seeds.dmi' + icon_state = "seed" // Unknown plant seed - these shouldn't exist in-game. + w_class = 1 + burn_state = FLAMMABLE + var/plantname = "Plants" // Name of plant when planted. + var/product // A type path. The thing that is created when the plant is harvested. + var/species = "" // Used to update icons. Should match the name in the sprites unless all icon_* are overriden. + + var/growing_icon = 'icons/obj/hydroponics/growing.dmi' //the file that stores the sprites of the growing plant from this seed. + var/icon_grow // Used to override grow icon (default is "[species]-grow"). You can use one grow icon for multiple closely related plants with it. + var/icon_dead // Used to override dead icon (default is "[species]-dead"). You can use one dead icon for multiple closely related plants with it. + var/icon_harvest // Used to override harvest icon (default is "[species]-harvest"). If null, plant will use [icon_grow][growthstages]. + + var/lifespan = 25 // How long before the plant begins to take damage from age. + var/endurance = 15 // Amount of health the plant has. + var/maturation = 6 // Used to determine which sprite to switch to when growing. + var/production = 6 // Changes the amount of time needed for a plant to become harvestable. + var/yield = 3 // Amount of growns created per harvest. If is -1, the plant/shroom/weed is never meant to be harvested. + var/potency = 10 // The 'power' of a plant. Generally effects the amount of reagent in a plant, also used in other ways. + var/growthstages = 6 // Amount of growth sprites the plant has. + var/rarity = 0 // How rare the plant is. Used for giving points to cargo when shipping off to Centcom. + var/list/mutatelist = list() // The type of plants that this plant can mutate into. + var/list/genes = list() // Plant genes are stored here, see plant_genes.dm for more info. + var/list/reagents_add = list() + // A list of reagents to add to product. + // Format: "reagent_id" = potency multiplier + // Stronger reagents must always come first to avoid being displaced by weaker ones. + // Total amount of any reagent in plant is calculated by formula: 1 + round(potency * multiplier) + + var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth + var/weed_chance = 5 //Percentage chance per tray update to grow weeds + +/obj/item/seeds/New(loc, nogenes = 0) + ..() + pixel_x = rand(-8, 8) + pixel_y = rand(-8, 8) + + if(!icon_grow) + icon_grow = "[species]-grow" + + if(!icon_dead) + icon_dead = "[species]-dead" + + if(!icon_harvest && !get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism) && yield != -1) + icon_harvest = "[species]-harvest" + + if(!nogenes) // not used on Copy() + genes += new /datum/plant_gene/core/lifespan(lifespan) + genes += new /datum/plant_gene/core/endurance(endurance) + genes += new /datum/plant_gene/core/weed_rate(weed_rate) + genes += new /datum/plant_gene/core/weed_chance(weed_chance) + if(yield != -1) + genes += new /datum/plant_gene/core/yield(yield) + genes += new /datum/plant_gene/core/production(production) + if(potency != -1) + genes += new /datum/plant_gene/core/potency(potency) + + for(var/p in genes) + if(ispath(p)) + genes -= p + genes += new p + + for(var/reag_id in reagents_add) + genes += new /datum/plant_gene/reagent(reag_id, reagents_add[reag_id]) + +/obj/item/seeds/proc/Copy() + var/obj/item/seeds/S = new type(null, 1) + // Copy all the stats + S.lifespan = lifespan + S.endurance = endurance + S.maturation = maturation + S.production = production + S.yield = yield + S.potency = potency + S.weed_rate = weed_rate + S.weed_chance = weed_chance + S.genes = list() + for(var/g in genes) + var/datum/plant_gene/G = g + S.genes += G.Copy() + S.reagents_add = reagents_add.Copy() // Faster than grabbing the list from genes. + return S + +/obj/item/seeds/proc/get_gene(typepath) + return (locate(typepath) in genes) + +/obj/item/seeds/proc/reagents_from_genes() + reagents_add = list() + for(var/datum/plant_gene/reagent/R in genes) + reagents_add[R.reagent_id] = R.rate + +/obj/item/seeds/proc/mutate(lifemut = 2, endmut = 5, productmut = 1, yieldmut = 2, potmut = 25, wrmut = 2, wcmut = 5, traitmut = 0) + adjust_lifespan(rand(-lifemut,lifemut)) + adjust_endurance(rand(-endmut,endmut)) + adjust_production(rand(-productmut,productmut)) + adjust_yield(rand(-yieldmut,yieldmut)) + adjust_potency(rand(-potmut,potmut)) + adjust_weed_rate(rand(-wrmut, wrmut)) + adjust_weed_chance(rand(-wcmut, wcmut)) + if(prob(traitmut)) + add_random_traits(1, 1) + + + +/obj/item/seeds/bullet_act(obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables. + if(istype(Proj, /obj/item/projectile/energy/florayield)) + var/rating = 1 + if(istype(loc, /obj/machinery/hydroponics)) + var/obj/machinery/hydroponics/H = loc + rating = H.rating + + if(yield == 0)//Oh god don't divide by zero you'll doom us all. + adjust_yield(1 * rating) + else if(prob(1/(yield * yield) * 100))//This formula gives you diminishing returns based on yield. 100% with 1 yield, decreasing to 25%, 11%, 6, 4, 2... + adjust_yield(1 * rating) + else + return ..() + + +// Harvest procs +/obj/item/seeds/proc/getYield() + var/return_yield = yield + + var/obj/machinery/hydroponics/parent = loc + if(istype(loc, /obj/machinery/hydroponics)) + if(parent.yieldmod == 0) + return_yield = min(return_yield, 1)//1 if above zero, 0 otherwise + else + return_yield *= (parent.yieldmod) + + return return_yield + + +/obj/item/seeds/proc/harvest(mob/user = usr) + var/obj/machinery/hydroponics/parent = loc //for ease of access + var/t_amount = 0 + var/list/result = list() + var/output_loc = parent.Adjacent(user) ? user.loc : parent.loc //needed for TK + var/product_name + while(t_amount < getYield()) + var/obj/item/weapon/reagent_containers/food/snacks/grown/t_prod = new product(output_loc, src) + result.Add(t_prod) // User gets a consumable + if(!t_prod) + return + t_amount++ + product_name = t_prod.name + if(getYield() >= 1) + feedback_add_details("food_harvested","[product_name]|[getYield()]") + parent.update_tray() + + return result + + +/obj/item/seeds/proc/prepare_result(var/obj/item/weapon/reagent_containers/food/snacks/grown/T) + if(T.reagents) + for(var/reagent_id in reagents_add) + if(reagent_id == "blood") // Hack to make blood in plants always O- + T.reagents.add_reagent(reagent_id, 1 + round(potency * reagents_add[reagent_id], 1), list("blood_type"="O-")) + continue + + T.reagents.add_reagent(reagent_id, 1 + round(potency * reagents_add[reagent_id]), 1) + return 1 + + +/// Setters procs /// +/obj/item/seeds/proc/adjust_yield(adjustamt) + if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable + yield = Clamp(yield + adjustamt, 0, 10) + + if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) + yield = 1 // Mushrooms always have a minimum yield of 1. + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/yield) + if(C) + C.value = yield + +/obj/item/seeds/proc/adjust_lifespan(adjustamt) + lifespan = Clamp(lifespan + adjustamt, 10, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) + if(C) + C.value = lifespan + +/obj/item/seeds/proc/adjust_endurance(adjustamt) + endurance = Clamp(endurance + adjustamt, 10, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) + if(C) + C.value = endurance + +/obj/item/seeds/proc/adjust_production(adjustamt) + if(yield != -1) + production = Clamp(production + adjustamt, 1, 10) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) + if(C) + C.value = production + +/obj/item/seeds/proc/adjust_potency(adjustamt) + if(potency != -1) + potency = Clamp(potency + adjustamt, 0, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) + if(C) + C.value = potency + +/obj/item/seeds/proc/adjust_weed_rate(adjustamt) + weed_rate = Clamp(weed_rate + adjustamt, 0, 10) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) + if(C) + C.value = weed_rate + +/obj/item/seeds/proc/adjust_weed_chance(adjustamt) + weed_chance = Clamp(weed_chance + adjustamt, 0, 67) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) + if(C) + C.value = weed_chance + +//Directly setting stats + +/obj/item/seeds/proc/set_yield(adjustamt) + if(yield != -1) // Unharvestable shouldn't suddenly turn harvestable + yield = Clamp(adjustamt, 0, 10) + + if(yield <= 0 && get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) + yield = 1 // Mushrooms always have a minimum yield of 1. + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/yield) + if(C) + C.value = yield + +/obj/item/seeds/proc/set_lifespan(adjustamt) + lifespan = Clamp(adjustamt, 10, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/lifespan) + if(C) + C.value = lifespan + +/obj/item/seeds/proc/set_endurance(adjustamt) + endurance = Clamp(adjustamt, 10, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/endurance) + if(C) + C.value = endurance + +/obj/item/seeds/proc/set_production(adjustamt) + if(yield != -1) + production = Clamp(adjustamt, 1, 10) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/production) + if(C) + C.value = production + +/obj/item/seeds/proc/set_potency(adjustamt) + if(potency != -1) + potency = Clamp(adjustamt, 0, 100) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/potency) + if(C) + C.value = potency + +/obj/item/seeds/proc/set_weed_rate(adjustamt) + weed_rate = Clamp(adjustamt, 0, 10) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_rate) + if(C) + C.value = weed_rate + +/obj/item/seeds/proc/set_weed_chance(adjustamt) + weed_chance = Clamp(adjustamt, 0, 67) + var/datum/plant_gene/core/C = get_gene(/datum/plant_gene/core/weed_chance) + if(C) + C.value = weed_chance + + +/obj/item/seeds/proc/get_analyzer_text() //in case seeds have something special to tell to the analyzer + var/text = "" + if(!get_gene(/datum/plant_gene/trait/plant_type/weed_hardy) && !get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism) && !get_gene(/datum/plant_gene/trait/plant_type/alien_properties)) + text += "- Plant type: Normal plant\n" + if(get_gene(/datum/plant_gene/trait/plant_type/weed_hardy)) + text += "- Plant type: Weed. Can grow in nutrient-poor soil.\n" + if(get_gene(/datum/plant_gene/trait/plant_type/fungal_metabolism)) + text += "- Plant type: Mushroom. Can grow in dry soil.\n" + if(get_gene(/datum/plant_gene/trait/plant_type/alien_properties)) + text += "- Plant type: UNKNOWN \n" + if(potency != -1) + text += "- Potency: [potency]\n" + if(yield != -1) + text += "- Yield: [yield]\n" + text += "- Maturation speed: [maturation]\n" + if(yield != -1) + text += "- Production speed: [production]\n" + text += "- Endurance: [endurance]\n" + text += "- Lifespan: [lifespan]\n" + text += "- Weed Growth Rate: [weed_rate]\n" + text += "- Weed Vulnerability: [weed_chance]\n" + if(rarity) + text += "- Species Discovery Value: [rarity]\n" + var/all_traits = "" + for(var/datum/plant_gene/trait/traits in genes) + if(istype(traits, /datum/plant_gene/trait/plant_type)) + continue + all_traits += " [traits.get_name()]" + text += "- Plant Traits:[all_traits]\n" + + text += "*---------*" + + return text + +/obj/item/seeds/proc/on_chem_reaction(datum/reagents/S) //in case seeds have some special interaction with special chems + return + +/obj/item/seeds/attackby(obj/item/O, mob/user, params) + if (istype(O, /obj/item/device/plant_analyzer)) + to_chat(user, "*---------*\n This is \a [src].") + var/text = get_analyzer_text() + if(text) + to_chat(user, "[text]") + + return + ..() // Fallthrough to item/attackby() so that bags can pick seeds up + + + + + + + +// Checks plants for broken tray icons. Use Advanced Proc Call to activate. +// Maybe some day it would be used as unit test. +/proc/check_plants_growth_stages_icons() + var/list/states = icon_states('icons/obj/hydroponics/growing.dmi') + states |= icon_states('icons/obj/hydroponics/growing_fruits.dmi') + states |= icon_states('icons/obj/hydroponics/growing_flowers.dmi') + states |= icon_states('icons/obj/hydroponics/growing_mushrooms.dmi') + states |= icon_states('icons/obj/hydroponics/growing_vegetables.dmi') + var/list/paths = typesof(/obj/item/seeds) - /obj/item/seeds - typesof(/obj/item/seeds/sample) + + for(var/seedpath in paths) + var/obj/item/seeds/seed = new seedpath + + for(var/i in 1 to seed.growthstages) + if("[seed.icon_grow][i]" in states) + continue + log_runtime("[seed.name] ([seed.type]) lacks the [seed.icon_grow][i] icon!", src) + + if(!(seed.icon_dead in states)) + log_runtime("[seed.name] ([seed.type]) lacks the [seed.icon_dead] icon!", src) + + if(seed.icon_harvest) // mushrooms have no grown sprites, same for items with no product + if(!(seed.icon_harvest in states)) + log_runtime("[seed.name] ([seed.type]) lacks the [seed.icon_harvest] icon!", src) + +/obj/item/seeds/proc/randomize_stats() + set_lifespan(rand(25, 60)) + set_endurance(rand(15, 35)) + set_production(rand(2, 10)) + set_yield(rand(1, 10)) + set_potency(rand(10, 35)) + set_weed_rate(rand(1, 10)) + set_weed_chance(rand(5, 100)) + maturation = rand(6, 12) + +/obj/item/seeds/proc/add_random_reagents(lower = 0, upper = 2) + var/amount_random_reagents = rand(lower, upper) + for(var/i in 1 to amount_random_reagents) + var/random_amount = rand(4, 15) * 0.01 // this must be multiplied by 0.01, otherwise, it will not properly associate + var/datum/plant_gene/reagent/R = new(get_random_reagent_id(), random_amount) + if(R.can_add(src)) + genes += R + else + qdel(R) + reagents_from_genes() + +/obj/item/seeds/proc/add_random_traits(lower = 0, upper = 2) + var/amount_random_traits = rand(lower, upper) + for(var/i in 1 to amount_random_traits) + var/random_trait = pick((subtypesof(/datum/plant_gene/trait)-typesof(/datum/plant_gene/trait/plant_type))) + var/datum/plant_gene/trait/T = new random_trait + if(T.can_add(src)) + genes += T + else + qdel(T) + +/obj/item/seeds/proc/add_random_plant_type(normal_plant_chance = 75) + if(prob(normal_plant_chance)) + var/random_plant_type = pick(subtypesof(/datum/plant_gene/trait/plant_type)) + var/datum/plant_gene/trait/plant_type/P = new random_plant_type + if(P.can_add(src)) + genes += P + else + qdel(P) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm deleted file mode 100644 index 21dc0dad4af..00000000000 --- a/code/modules/hydroponics/spreading/spreading.dm +++ /dev/null @@ -1,277 +0,0 @@ -#define DEFAULT_SEED "glowshroom" -#define VINE_GROWTH_STAGES 5 - -/proc/spacevine_infestation(var/potency_min=70, var/potency_max=100, var/maturation_min=5, var/maturation_max=15) - spawn() //to stop the secrets panel hanging - var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas - for(var/areapath in typesof(/area/hallway)) - var/area/A = locate(areapath) - for(var/turf/simulated/floor/F in A.contents) - if(turf_clear(F)) - turfs += F - - if(turfs.len) //Pick a turf to spawn at if we can - var/turf/simulated/floor/T = pick(turfs) - var/datum/seed/seed = plant_controller.create_random_seed(1) - seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines. - seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects. - seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max)) - - //make vine zero start off fully matured - var/obj/effect/plant/vine = new(T,seed) - vine.health = vine.max_health - vine.mature_time = 0 - vine.process() - - message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])") - -/obj/effect/dead_plant - anchored = 1 - opacity = 0 - density = 0 - color = DEAD_PLANT_COLOUR - -/obj/effect/dead_plant/attack_hand() - qdel(src) - -/obj/effect/dead_plant/attackby() - ..() - for(var/obj/effect/plant/neighbor in range(1)) - neighbor.update_neighbors() - qdel(src) - -/obj/effect/plant - name = "plant" - anchored = 1 - opacity = 0 - density = 0 - icon = 'icons/obj/hydroponics_growing.dmi' - icon_state = "bush4-1" - layer = 3 - pass_flags = PASSTABLE - - var/health = 10 - var/max_health = 100 - var/growth_threshold = 0 - var/growth_type = 0 - var/max_growth = 0 - - var/list/neighbors = list() - var/obj/effect/plant/parent - var/datum/seed/seed - var/floor = 0 - var/spread_chance = 40 - var/spread_distance = 3 - var/evolve_chance = 2 - var/mature_time - var/last_tick = 0 - var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant - - var/movable = 0 - -/obj/effect/plant/Destroy() - if(buckled_mob) - unbuckle_mob() - if(plant_controller) - plant_controller.remove_plant(src) - for(var/obj/effect/plant/neighbor in range(1,src)) - plant_controller.add_plant(neighbor) - return ..() - -/obj/effect/plant/single - spread_chance = 0 - -/obj/effect/plant/New(var/newloc, var/datum/seed/newseed, var/obj/effect/plant/newparent) - ..() - - if(!newparent) - parent = src - else - parent = newparent - - if(!plant_controller) - sleep(250) // ugly hack, should mean roundstart plants are fine. - if(!plant_controller) - to_chat(world, "Plant controller does not exist and [src] requires it. Aborting.") - qdel(src) - return - - if(!istype(newseed)) - newseed = plant_controller.seeds[DEFAULT_SEED] - seed = newseed - if(!seed) - qdel(src) - return - - name = seed.display_name - max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2) - if(seed.get_trait(TRAIT_SPREAD)==2) - max_growth = VINE_GROWTH_STAGES - growth_threshold = max_health/VINE_GROWTH_STAGES - icon = 'icons/obj/hydroponics_vines.dmi' - growth_type = 2 // Vines by default. - if(seed.get_trait(TRAIT_CARNIVOROUS) == 2) - growth_type = 1 // WOOOORMS. - else if(!(seed.seed_noun in list("seeds","pits"))) - if(seed.seed_noun == "nodes") - growth_type = 3 // Biomass - else - growth_type = 4 // Mold - else - max_growth = seed.growth_stages - growth_threshold = max_health/seed.growth_stages - - if(max_growth > 2 && prob(50)) - max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky. - - mature_time = world.time + seed.get_trait(TRAIT_MATURATION) + 15 //prevent vines from maturing until at least a few seconds after they've been created. - spread_chance = seed.get_trait(TRAIT_POTENCY) - if(growth_type == 0) //These don't spread far at all (glowshroom, glowberries, brown mold) - spread_distance = round(spread_chance*0.1) - else if(growth_type == 2 || growth_type == 3) //Vines and biomass can go further than worms and mold - spread_distance = round(spread_chance*0.6) - else //Worms and mold go a moderate distance - spread_distance = round(spread_chance*0.3) - update_icon() - - spawn(1) // Plants will sometimes be spawned in the turf adjacent to the one they need to end up in, for the sake of correct dir/etc being set. - set_dir(calc_dir()) - update_icon() - plant_controller.add_plant(src) - // Some plants eat through plating. - if(!isnull(seed.chems["facid"])) - var/turf/T = get_turf(src) - T.ex_act(prob(80) ? 3 : 2) - -/obj/effect/plant/update_icon() - //TODO: should really be caching this. - refresh_icon() - if(growth_type == 0 && !floor) - src.transform = null - var/matrix/M = matrix() - // should make the plant flush against the wall it's meant to be growing from. - M.Translate(0,-(rand(12,14))) - switch(dir) - if(WEST) - M.Turn(90) - if(NORTH) - M.Turn(180) - if(EAST) - M.Turn(270) - src.transform = M - var/icon_colour = seed.get_trait(TRAIT_PLANT_COLOUR) - if(icon_colour) - color = icon_colour - // Apply colour and light from seed datum. - if(seed.get_trait(TRAIT_BIOLUM)) - var/clr - if(seed.get_trait(TRAIT_BIOLUM_COLOUR)) - clr = seed.get_trait(TRAIT_BIOLUM_COLOUR) - set_light(1+round(seed.get_trait(TRAIT_POTENCY)/20), l_color = clr) - return - else - set_light(0) - -/obj/effect/plant/proc/refresh_icon() - var/growth = min(max_growth,round(health/growth_threshold)) - var/at_fringe = get_dist(src,parent) - if(spread_distance > 5) - if(at_fringe >= (spread_distance-3)) - max_growth-- - if(at_fringe >= (spread_distance-2)) - max_growth-- - max_growth = max(1,max_growth) - if(growth_type > 0) - switch(growth_type) - if(1) - icon_state = "worms" - if(2) - icon_state = "vines-[growth]" - if(3) - icon_state = "mass-[growth]" - if(4) - icon_state = "mold-[growth]" - else - icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]" - - if(growth>2 && growth == max_growth) - layer = 5 - if(seed.get_trait(TRAIT_SPREAD) == 2) - opacity = 1 - if(!isnull(seed.chems["woodpulp"])) - density = 1 - else - layer = 3 - density = 0 - -/obj/effect/plant/proc/calc_dir(turf/location = loc) - set background = 1 - var/direction = 16 - - for(var/wallDir in cardinal) - var/turf/newTurf = get_step(location,wallDir) - if(newTurf.density) - direction |= wallDir - - for(var/obj/effect/plant/shroom in location) - if(shroom == src) - continue - if(shroom.floor) //special - direction &= ~16 - else - direction &= ~shroom.dir - - var/list/dirList = list() - - for(var/i=1,i<=16,i <<= 1) - if(direction & i) - dirList += i - - if(dirList.len) - var/newDir = pick(dirList) - if(newDir == 16) - floor = 1 - newDir = 1 - return newDir - - floor = 1 - return 1 - -/obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user) - - plant_controller.add_plant(src) - - if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel)) - if(!seed) - to_chat(user, "There is nothing to take a sample from.") - return - seed.harvest(user,0,1) - health -= (rand(3,5)*10) - else - ..() - if(W.force) - health -= W.force - check_health() - -/obj/effect/plant/ex_act(severity) - switch(severity) - if(1.0) - die_off() - return - if(2.0) - if(prob(50)) - die_off() - return - if(3.0) - if(prob(5)) - die_off() - return - else - return - -/obj/effect/plant/proc/check_health() - if(health <= 0) - die_off() - -/obj/effect/plant/proc/is_mature() - return (health >= (max_health/3) && world.time > mature_time) \ No newline at end of file diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm deleted file mode 100644 index b86c3966aa8..00000000000 --- a/code/modules/hydroponics/spreading/spreading_growth.dm +++ /dev/null @@ -1,109 +0,0 @@ -#define NEIGHBOR_REFRESH_TIME 100 - -/obj/effect/plant/proc/get_cardinal_neighbors() - var/list/cardinal_neighbors = list() - for(var/check_dir in cardinal) - var/turf/simulated/T = get_step(get_turf(src), check_dir) - if(istype(T)) - cardinal_neighbors |= T - return cardinal_neighbors - -/obj/effect/plant/proc/update_neighbors() - // Update our list of valid neighboring turfs. - neighbors = list() - for(var/turf/simulated/floor in get_cardinal_neighbors()) - if(get_dist(parent, floor) > spread_distance) - continue - if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) ) - continue - if(floor.density) - if(!isnull(seed.chems["pacid"])) - spawn(rand(5,25)) floor.ex_act(3) - continue - if(!Adjacent(floor) || !floor.Enter(src)) - continue - neighbors |= floor - // Update all of our friends. - var/turf/T = get_turf(src) - for(var/obj/effect/plant/neighbor in range(1,src)) - neighbor.neighbors -= T - -/obj/effect/plant/process() - - // Something is very wrong, kill ourselves. - if(!seed) - die_off() - return 0 - - /* MOVED INTO code\game\objects\effects\effect_system.dm - for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) - if(smoke.reagents.has_reagent("plantbgone")) - die_off() - return - */ - - // Handle life. - var/turf/simulated/T = get_turf(src) - if(istype(T)) - health -= seed.handle_environment(T,T.return_air(),null,null,1) - if(health < max_health) - health += rand(3,5) - refresh_icon() - if(health > max_health) - health = max_health - else if(health == max_health && !plant) - plant = new(T,seed) - plant.dir = src.dir - plant.transform = src.transform - plant.age = seed.get_trait(TRAIT_MATURATION)-1 - plant.update_icon() - if(growth_type==0) //Vines do not become invisible. - invisibility = INVISIBILITY_MAXIMUM - else - plant.layer = layer + 0.1 - - if(buckled_mob) - seed.do_sting(buckled_mob,src) - if(seed.get_trait(TRAIT_CARNIVOROUS)) - seed.do_thorns(buckled_mob,src) - - if(world.time >= last_tick+NEIGHBOR_REFRESH_TIME) - last_tick = world.time - update_neighbors() - - if(is_mature() && neighbors.len && prob(spread_chance)) - //spread to 1-3 adjacent turfs depending on yield trait. - var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3) - - for(var/i in 1 to max_spread) - if(prob(spread_chance)) - sleep(rand(3,5)) - if(!neighbors.len) - break - var/turf/target_turf = pick(neighbors) - var/obj/effect/plant/child = new(get_turf(src),seed,parent) - spawn(1) // This should do a little bit of animation. - child.loc = target_turf - child.update_icon() - // Update neighboring squares. - for(var/obj/effect/plant/neighbor in range(1,target_turf)) - neighbor.neighbors -= target_turf - - // We shouldn't have spawned if the controller doesn't exist. - check_health() - if(neighbors.len || health != max_health) - plant_controller.add_plant(src) - -/obj/effect/plant/proc/die_off() - // Kill off our plant. - if(plant) plant.die() - // This turf is clear now, let our buddies know. - for(var/turf/simulated/check_turf in get_cardinal_neighbors()) - if(!istype(check_turf)) - continue - for(var/obj/effect/plant/neighbor in check_turf.contents) - neighbor.neighbors |= check_turf - plant_controller.add_plant(neighbor) - spawn(1) if(src) qdel(src) - -#undef NEIGHBOR_REFRESH_TIME \ No newline at end of file diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm deleted file mode 100644 index 8145cb13ad4..00000000000 --- a/code/modules/hydroponics/spreading/spreading_response.dm +++ /dev/null @@ -1,57 +0,0 @@ -/obj/effect/plant/HasProximity(var/atom/movable/AM) - - if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2) - return - - var/mob/living/M = AM - if(!istype(M)) - return - - if(!buckled_mob && !M.buckled && !M.anchored && ((M.mob_size <= MOB_SIZE_SMALL) || prob(round(seed.get_trait(TRAIT_POTENCY)/6)))) - //wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation), - //so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines. - spawn(1) - entangle(M) - -/obj/effect/plant/attack_hand(mob/user as mob) - // Todo, cause damage. - user_unbuckle_mob(user, user) - -/obj/effect/plant/Crossed(var/mob/living/victim) - if(!is_mature()) - return - if(!istype(victim)) - return - var/target_limb = pick("r_foot","l_foot","r_leg","l_leg") - if(ishuman(victim)) - var/mob/living/carbon/human/H = victim - if(H.shoes && prob(50)) //shoes will reduce chances of being stuck/stung by plants, but not always avoid it - return - seed.do_thorns(victim,src,target_limb) - seed.do_sting(victim,src,target_limb) - - -/obj/effect/plant/proc/entangle(var/mob/living/victim) - - if(buckled_mob) - return - - if(victim.buckled) - return - - //grabbing people - if(!victim.anchored && Adjacent(victim) && victim.loc != get_turf(src)) - var/can_grab = 1 - if(istype(victim, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = victim - if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) - can_grab = 0 - if(can_grab) - src.visible_message("Tendrils lash out from \the [src] and drag \the [victim] in!") - victim.loc = src.loc - - //entangling people - if(victim.loc == src.loc) - to_chat(victim, "Tendrils [pick("wind", "tangle", "tighten")] around you!") - can_buckle = 1 - buckle_mob(victim) \ No newline at end of file diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm deleted file mode 100644 index 72bf80c58de..00000000000 --- a/code/modules/hydroponics/trays/tray.dm +++ /dev/null @@ -1,771 +0,0 @@ -/obj/machinery/portable_atmospherics/hydroponics - name = "hydroponics tray" - icon = 'icons/obj/hydroponics_machines.dmi' - icon_state = "hydrotray3" - density = 1 - anchored = 1 - flags = OPENCONTAINER - volume = 100 - - hud_possible = list (PLANT_NUTRIENT_HUD, PLANT_WATER_HUD, PLANT_STATUS_HUD, PLANT_HEALTH_HUD, PLANT_TOXIN_HUD, PLANT_PEST_HUD, PLANT_WEED_HUD) - - var/mechanical = 1 // Set to 0 to stop it from drawing the alert lights. - var/base_name = "tray" - - // Plant maintenance vars. - var/waterlevel = 100 // Water level (max 100) - var/maxwater = 100 - var/nutrilevel = 10 // Nutrient level (max 10) - var/maxnutri = 10 - var/pestlevel = 0 // Pests (max 10) - var/weedlevel = 0 // Weeds (max 10) - - // Tray state vars. - var/dead = 0 // Is it dead? - var/harvest = 0 // Is it ready to harvest? - var/age = 0 // Current plant age - var/sampled = 0 // Have we taken a sample? - - // Harvest/mutation mods. - var/yield_mod = 0 // Modifier to yield - var/mutation_mod = 0 // Modifier to mutation chance - var/toxins = 0 // Toxicity in the tray? - var/tray_light = 1 // Supplied lighting. - - // Mechanical concerns. - var/health = 0 // Plant health. - var/lastproduce = 0 // Last time tray was harvested - var/current_cycle = 0 // Used for tracking number of cycles for aging - var/lastcycle = 0 // Cycle timing/tracking var. - var/cycledelay = 150 // Delay per cycle. - var/closed_system // If set, the tray will attempt to take atmos from a pipe. - var/force_update // Set this to bypass the cycle time check. - var/obj/temp_chem_holder // Something to hold reagents during process_reagents() - var/labelled - - // Seed details/line data. - var/datum/seed/seed = null // The currently planted seed - - // Construction - var/unwrenchable = 1 - - var/last_plant_ikey //This is for debugging reference, and is otherwise useless. --FalseIncarnate - - var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpolinate one plant - -/* -* process() can be found in \code\modules\hydroponics\tray\tray_process.dm -* reagent handling can be found in \code\modules\hydroponics\tray\tray_reagents.dm -* icon handling can be found in \code\modules\hydroponics\tray\tray_update_icons.dm -*/ - -/obj/machinery/portable_atmospherics/hydroponics/AltClick() - if(mechanical && !usr.stat && !usr.lying && Adjacent(usr)) - close_lid(usr) - return - return ..() - -/obj/machinery/portable_atmospherics/hydroponics/proc/attack_generic(var/mob/user) - if(istype(user,/mob/living/simple_animal/diona)) - var/mob/living/simple_animal/diona/nymph = user - - if(nymph.stat == DEAD || nymph.paralysis || nymph.weakened || nymph.stunned || nymph.restrained()) - return - - if(weedlevel > 0) - nymph.reagents.add_reagent("nutriment", weedlevel) - weedlevel = 0 - plant_hud_set_weed() - nymph.visible_message("[nymph] begins rooting through [src], ripping out weeds and eating them noisily.","You begin rooting through [src], ripping out weeds and eating them noisily.") - else if(nymph.nutrition > 100 && nutrilevel < 10) - nymph.nutrition -= ((10-nutrilevel)*5) - nutrilevel = 10 - plant_hud_set_nutrient() - nymph.visible_message("[nymph] secretes a trickle of green liquid, refilling [src].","You secrete a trickle of green liquid, refilling [src].") - else - nymph.visible_message("[nymph] rolls around in [src] for a bit.","You roll around in [src] for a bit.") - return - -/obj/machinery/portable_atmospherics/hydroponics/New() - ..() - - var/datum/atom_hud/data/hydroponic/hydro_hud = huds[DATA_HUD_HYDROPONIC] - prepare_huds() - hydro_hud.add_to_hud(src) - plant_hud_set_nutrient() - plant_hud_set_water() - plant_hud_set_status() - plant_hud_set_health() - plant_hud_set_toxin() - plant_hud_set_pest() - plant_hud_set_weed() - - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/hydroponics(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - RefreshParts() - - temp_chem_holder = new() - temp_chem_holder.create_reagents(10) - - create_reagents(200) - connect() - update_icon() - if(closed_system) - flags &= ~OPENCONTAINER - - -/obj/machinery/portable_atmospherics/hydroponics/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/hydroponics(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(src) - component_parts += new /obj/item/weapon/stock_parts/console_screen(src) - RefreshParts() - -/obj/machinery/portable_atmospherics/hydroponics/RefreshParts() - var/tmp_capacity = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) - tmp_capacity += M.rating - maxwater = tmp_capacity * 50 // Up to 300 - maxnutri = tmp_capacity * 5 // Up to 30 - //waterlevel = maxwater - //nutrilevel = 3 - plant_hud_set_nutrient() - plant_hud_set_water() - -/obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj) - - //Don't act on seeds like dionaea that shouldn't change. - if(seed && seed.get_trait(TRAIT_IMMUTABLE) > 0) - return - - //--FalseIncarnate - //Override for somatoray projectiles, updated to work with new mutation rework - if(istype(Proj ,/obj/item/projectile/energy/floramut)) - mutate("F1") - return - else if(istype(Proj ,/obj/item/projectile/energy/florayield)) - mutate("F2") - return - //--FalseIncarnate - - ..() - -/obj/machinery/portable_atmospherics/hydroponics/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - -/obj/machinery/portable_atmospherics/hydroponics/proc/check_health() - if(seed && !dead && health <= 0) - die() - check_level_sanity() - update_icon() - plant_hud_set_status() - plant_hud_set_health() - -/obj/machinery/portable_atmospherics/hydroponics/proc/die() - dead = 1 - harvest = 0 - weedlevel += 1 * HYDRO_SPEED_MULTIPLIER - pestlevel = 0 - plant_hud_set_status() - plant_hud_set_health() - plant_hud_set_weed() - plant_hud_set_pest() - -//Harvests the product of a plant. -/obj/machinery/portable_atmospherics/hydroponics/proc/harvest(var/mob/user) - - //Harvest the product of the plant, - if(!seed || !harvest) - return - - if(closed_system) - if(user) - to_chat(user, "You can't harvest from the plant while the lid is shut.") - return - - if(user) - seed.harvest(user,yield_mod) - else - seed.harvest(get_turf(src),yield_mod) - //Increases harvest count for round-end score - //Currently per-plant (not per-item) harvested - // --FalseIncarnate - score_stuffharvested++ - - // Reset values. - harvest = 0 - lastproduce = age - - if(!seed.get_trait(TRAIT_HARVEST_REPEAT)) - yield_mod = 0 - seed = null - dead = 0 - age = 0 - lastproduce = 0 - sampled = 0 - mutation_mod = 0 - - check_health() - return - -//Clears out a dead plant. -/obj/machinery/portable_atmospherics/hydroponics/proc/remove_dead(var/mob/user) - if(!user || !dead) return - - if(closed_system) - to_chat(user, "You can't remove the dead plant while the lid is shut.") - return - - seed = null - dead = 0 - - sampled = 0 - age = 0 - lastproduce = 0 - yield_mod = 0 - mutation_mod = 0 - - to_chat(user, "You remove the dead plant.") - check_health() - return - -// If a weed growth is sufficient, this proc is called. -/obj/machinery/portable_atmospherics/hydroponics/proc/weed_invasion() - - //Remove the seed if something is already planted. - if(seed) seed = null - seed = plant_controller.seeds[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))] - if(!seed) return //Weed does not exist, someone fucked up. - - dead = 0 - age = 0 - health = seed.get_trait(TRAIT_ENDURANCE) - lastcycle = world.time - harvest = 0 - lastproduce = 0 - weedlevel = 0 - pestlevel = 0 - sampled = 0 - update_icon() - plant_hud_set_weed() - plant_hud_set_status() - plant_hud_set_health() - visible_message("[src] has been overtaken by [seed.display_name].") - - return - -/obj/machinery/portable_atmospherics/hydroponics/proc/mutate(var/severity) - - // No seed, no mutations. - if(!seed) - return - - /* - --FalseIncarnate - New mutation system, now uses "Mutation Tiers" to adjust the chances of mutations - Tier 1 has a low chance of causing a stat mutation - Tier 2 has a higher chance of causing a stat mutation - Tier 3 has a low chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species - Tier 4 has a higher chance of causing a species shift (if possible), and will ALWAYS cause a stat mutation if it does not shift species - Tier 4 also has a low chance to cause a SECOND stat mutation when it does not shift species - All mutation chances are increased by the mutation_mod value. Mutation_mod is not transferred into seeds/harvests, and is reset when the plant dies - */ - - switch(severity) - //Reagent Tiers - if(1) //Tier 1 - if(prob(20+mutation_mod)) //Low chance of stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - if(2) //Tier 2 - if(prob(60+mutation_mod)) //Higher chance of stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - if(3) //Tier 3 - if(prob(20+mutation_mod)) //Low chance of species shift mutation - if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species - mutate_species() - else //No mutant species, mutate stats instead - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - else //Failed to shift, mutate stats instead - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - if(4) //Tier 4 - if(prob(60+mutation_mod)) //Higher chance of species shift mutation - if(seed.mutants. && seed.mutants.len) //Check if current seed/plant has mutant species - mutate_species() - else //No mutant species, mutate stats instead - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - if(prob(20+mutation_mod)) //Low chance for second stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - else //Failed to shift, mutate stats instead - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - if(prob(20+mutation_mod)) //Low chance for second stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - //Floral Somatoray Tiers - if("F1") //Random Stat Tier - if(prob(80+mutation_mod)) //EVEN Higher chance of stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - seed.mutate(1,get_turf(src)) - return - if("F2") //Yield Tier - if(prob(40+mutation_mod)) //Medium chance of Yield stat mutation - if(!isnull(plant_controller.seeds[seed.name])) - seed = seed.diverge() - else - seed.update_name_prefixes() - if(seed.get_trait(TRAIT_IMMUTABLE) <= 0 && seed.get_trait(TRAIT_YIELD) != -1) //Check if the plant can be mutated and has a yield to mutate - seed.set_trait(TRAIT_YIELD, (seed.get_trait(TRAIT_YIELD) + rand(-2, 2))) //Randomly adjust yield - if(seed.get_trait(TRAIT_YIELD) < 0) //If yield would drop below 0 after adjustment, set to 0 to allow further attempts - seed.set_trait(TRAIT_YIELD, 0) - return - - /* code references - // We need to make sure we're not modifying one of the global seed datums. - // If it's not in the global list, then no products of the line have been - // harvested yet and it's safe to assume it's restricted to this tray. - if(!isnull(seed_types[seed.name])) - seed = seed.diverge() - seed.mutate(severity,get_turf(src)) - */ - - //--FalseIncarnate - -/obj/machinery/portable_atmospherics/hydroponics/verb/remove_label() - set name = "Remove Label" - set category = "Object" - set src in view(1) - - if(usr.incapacitated()) - return - - if(labelled) - to_chat(usr, "You remove the label.") - labelled = null - update_icon() - else - to_chat(usr, "There is no label to remove.") - return - -/obj/machinery/portable_atmospherics/hydroponics/verb/setlight() - set name = "Set Light" - set category = "Object" - set src in view(1) - - if(usr.incapacitated()) - return - - var/new_light = input("Specify a light level.") as null|anything in list(0,1,2,3,4,5,6,7,8,9,10) - if(new_light) - tray_light = new_light - to_chat(usr, "You set the tray to a light level of [tray_light] lumens.") - -/obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity() - //Make sure various values are sane. - if(seed) - health = max(0,min(seed.get_trait(TRAIT_ENDURANCE),health)) - else - health = 0 - dead = 0 - - nutrilevel = max(0,min(nutrilevel,maxnutri)) - waterlevel = max(0,min(waterlevel,maxwater)) - pestlevel = max(0,min(pestlevel,10)) - weedlevel = max(0,min(weedlevel,10)) - toxins = max(0,min(toxins,10)) - yield_mod = min(100, yield_mod) - - plant_hud_set_nutrient() - plant_hud_set_water() - plant_hud_set_status() - plant_hud_set_health() - plant_hud_set_toxin() - plant_hud_set_pest() - plant_hud_set_weed() - -/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species() - - var/previous_plant = seed.display_name - var/newseed = seed.get_mutant_variant() - if(newseed in plant_controller.seeds) - seed = plant_controller.seeds[newseed] - else - return - - dead = 0 - //mutate(1) - age = 0 - health = seed.get_trait(TRAIT_ENDURANCE) - lastcycle = world.time - lastproduce = 0 - harvest = 0 - weedlevel = 0 - - plant_hud_set_health() - plant_hud_set_weed() - - update_icon() - visible_message("\red The \blue [previous_plant] \red has suddenly mutated into \blue [seed.display_name]!") - - return - - -/obj/machinery/portable_atmospherics/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(exchange_parts(user, O)) - return - - if(istype(O, /obj/item/weapon/crowbar)) - if(anchored==2) - to_chat(user, "Unscrew the hoses first!") - return - default_deconstruction_crowbar(O, 1) - - //--FalseIncarnate - //Check if held item is an open container - if(O.is_open_container()) - //Check if container is of the "glass" subtype (includes buckets, beakers, vials) - if(istype(O, /obj/item/weapon/reagent_containers/glass)) - var/obj/item/weapon/reagent_containers/glass/C = O - //Check if container is empty - if(!C.reagents.total_volume) - to_chat(user, "\red [C] is empty.") - return - //Container not empty, transfer contents to tray - var/trans = C.reagents.trans_to(src, C.amount_per_transfer_from_this) - to_chat(user, "\blue You transfer [trans] units of the solution to [src].") - - check_level_sanity() - process_reagents() - update_icon() - - //Check if container is one of the plantsprays (defined in tray_reagents.dm) - else if(istype(O, /obj/item/weapon/plantspray)) - var/obj/item/weapon/plantspray/P = O - user.drop_item(O) - toxins += P.toxicity - pestlevel -= P.pest_kill_str - weedlevel -= P.weed_kill_str - to_chat(user, "You spray [src] with [O].") - playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) - qdel(O) - - check_level_sanity() - update_icon() - - //Check if spray is weedkiller (defined in tray_reagents.dm, un-obtainable currently) - else if(istype(O, /obj/item/weedkiller)) - var/obj/item/weedkiller/W = O - user.drop_item(O) - toxins += W.toxicity - weedlevel -= W.weed_kill_str - to_chat(user, "You spray [src] with [O].") - playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) - qdel(O) - - check_level_sanity() - update_icon() - - //Check if container is any spray container - else if(istype(O, /obj/item/weapon/reagent_containers/spray)) - var/obj/item/weapon/reagent_containers/spray/S = O - //Check if there is a plant in the tray - if(seed) - if(!S.reagents.total_volume) - to_chat(user, "\red [S] is empty.") - return - //Container not empty, transfer contents to tray - S.reagents.trans_to(src, S.amount_per_transfer_from_this) - visible_message("\red \The [src] has been sprayed with \the [O][(user ? " by [user]." : ".")]") - playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) - check_level_sanity() - update_icon() - else - to_chat(user, "There's nothing in [src] to spray!") - - else if(istype(O, /obj/item/weapon/screwdriver) && unwrenchable) //THIS NEED TO BE DONE DIFFERENTLY, SOMEONE REFACTOR THE TRAY CODE ALREADY - if(anchored) - if(anchored == 2) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - anchored = 1 - to_chat(user, "You unscrew the [src]'s hoses.") - panel_open = 0 - - else if(anchored == 1) - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - anchored = 2 - to_chat(user, "You screw in the [src]'s hoses.") - panel_open = 1 - - for(var/obj/machinery/portable_atmospherics/hydroponics/h in range(1,src)) - spawn() - h.update_icon() - - if(istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/weapon/scalpel)) - - if(!seed) - to_chat(user, "There is nothing to take a sample from in \the [src].") - return - - if(sampled) - to_chat(user, "You have already sampled from this plant.") - return - - if(dead) - to_chat(user, "The plant is dead.") - return - - // Create a sample. - seed.harvest(user,yield_mod,1) - health -= (rand(3,5)*10) - - if(prob(30)) - sampled = 1 - - // Bookkeeping. - check_health() - force_update = 1 - process() - - return - - else if(istype(O, /obj/item/weapon/reagent_containers/syringe)) - - var/obj/item/weapon/reagent_containers/syringe/S = O - - if(S.mode == 1) - if(seed) - return ..() - else - to_chat(user, "There's no plant to inject.") - return 1 - else - if(seed) - //Leaving this in in case we want to extract from plants later. - to_chat(user, "You can't get any extract out of this plant.") - else - to_chat(user, "There's nothing to draw something from.") - return 1 - - else if(istype(O, /obj/item/seeds)) - - if(!seed) - - var/obj/item/seeds/S = O - user.drop_item(O) - - if(!S.seed) - to_chat(user, "The packet seems to be empty. You throw it away.") - qdel(O) - return - - to_chat(user, "You plant the [S.seed.seed_name] [S.seed.seed_noun].") - seed = S.seed //Grab the seed datum. - dead = 0 - age = 1 - lastproduce = 0 - //Snowflakey, maybe move this to the seed datum - health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE)) - lastcycle = world.time - - qdel(O) - - check_health() - - else - to_chat(user, "\The [src] already has seeds in it!") - - else if(istype(O, /obj/item/weapon/minihoe)) // The minihoe - - if(weedlevel > 0) - user.visible_message("[user] starts uprooting the weeds.", "You remove the weeds from the [src].") - weedlevel = 0 - update_icon() - plant_hud_set_weed() - else - to_chat(user, "This plot is completely devoid of weeds. It doesn't need uprooting.") - - else if(istype(O, /obj/item/weapon/storage/bag/plants)) - - attack_hand(user) - - var/obj/item/weapon/storage/bag/plants/S = O - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in locate(user.x,user.y,user.z)) - if(!S.can_be_inserted(G)) - return - S.handle_item_insertion(G, 1) - - else if(mechanical && istype(O, /obj/item/weapon/wrench)) - - //If there's a connector here, the portable_atmospherics setup can handle it. - if(locate(/obj/machinery/atmospherics/unary/portables_connector) in loc) - return ..() - - playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) - anchored = !anchored - to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].") - - else if((istype(O, /obj/item/weapon/tank) && !( src.destroyed ))) - if(src.holding) - to_chat(user, "\blue There is alreadu a tank loaded into the [src].") - return - var/obj/item/weapon/tank/T = O - user.drop_item() - T.loc = src - src.holding = T - update_icon() - return - else if(O && O.force && seed) - user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") - if(!dead) - health -= O.force - check_health() - return - -/obj/machinery/portable_atmospherics/hydroponics/attack_tk(mob/user as mob) - if(dead) - remove_dead(user) - else if(harvest) - harvest(user) - -/obj/machinery/portable_atmospherics/hydroponics/attack_hand(mob/user as mob) - - if(istype(usr,/mob/living/silicon)) - return - - if(harvest) - harvest(user) - else if(dead) - remove_dead(user) - -/obj/machinery/portable_atmospherics/hydroponics/examine(mob/user) - ..(user) - - if(!seed) - to_chat(user, "[src] is empty.") - return - - to_chat(user, "[seed.display_name] are growing here.") - - if(!Adjacent(user)) - return - - to_chat(user, "Water: [round(waterlevel,0.1)]/[maxwater]") - to_chat(user, "Nutrient: [round(nutrilevel,0.1)]/[maxnutri]") - - if(weedlevel >= 5) - to_chat(user, "\The [src] is infested with weeds!") - if(pestlevel >= 5) - to_chat(user, "\The [src] is infested with tiny worms!") - - if(dead) - to_chat(user, "The plant is dead.") - else if(health <= (seed.get_trait(TRAIT_ENDURANCE)/ 2)) - to_chat(user, "The plant looks unhealthy.") - - if(mechanical) - var/turf/T = loc - var/datum/gas_mixture/environment - - if(closed_system && (connected_port || holding)) - environment = air_contents - - if(!environment) - if(istype(T)) - environment = T.return_air() - - if(!environment) //We're in a crate or nullspace, bail out. - return - - var/light_string - if(closed_system && mechanical) - light_string = "that the internal lights are set to [tray_light] lumens" - else - var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T - var/light_available - if(L) - light_available = L.get_clamped_lum()*10 - else - light_available = 5 - light_string = "a light level of [light_available] lumens" - - to_chat(user, "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K.") - -/obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb() - set name = "Toggle Tray Lid" - set category = "Object" - set src in view(1) - close_lid(usr) - -/obj/machinery/portable_atmospherics/hydroponics/proc/close_lid(var/mob/living/user) - if(!user || user.stat || user.restrained()) - return - - closed_system = !closed_system - to_chat(user, "You [closed_system ? "close" : "open"] the tray's lid.") - update_icon() - -/obj/machinery/portable_atmospherics/hydroponics/verb/eject_tank_verb() - set name = "Eject Internal Tank" - set category = "Object" - set src in view(1) - eject_tank(usr) - -/obj/machinery/portable_atmospherics/hydroponics/proc/eject_tank(var/mob/living/user) - if(!user || user.stat || user.restrained()) - return - - if(!holding) - to_chat(usr, "\red There is no tank loaded into [src] to eject.") - - if(istype(holding, /obj/item/weapon/tank)) - to_chat(usr, "\blue You eject [holding.name] from [src].") - holding.loc = loc - holding = null diff --git a/code/modules/hydroponics/trays/tray_apiary.dm b/code/modules/hydroponics/trays/tray_apiary.dm deleted file mode 100644 index 95d3a05e4bd..00000000000 --- a/code/modules/hydroponics/trays/tray_apiary.dm +++ /dev/null @@ -1,240 +0,0 @@ -//http://www.youtube.com/watch?v=-1GadTfGFvU -//i could have done these as just an ordinary plant, but fuck it - there would have been too much snowflake code - -/obj/machinery/apiary - name = "apiary tray" - icon = 'icons/obj/hydroponics_machines.dmi' - icon_state = "hydrotray3" - density = 1 - anchored = 1 - var/nutrilevel = 0 - var/yieldmod = 1 - var/mut = 1 - var/toxic = 0 - var/dead = 0 - var/health = -1 - var/maxhealth = 100 - var/lastcycle = 0 - var/cycledelay = 100 - var/harvestable_honey = 0 - var/beezeez = 0 - var/swarming = 0 - - var/bees_in_hive = 0 - var/list/owned_bee_swarms = list() - var/hydrotray_type = /obj/machinery/portable_atmospherics/hydroponics - -//overwrite this after it's created if the apiary needs a custom machinery sprite -/obj/machinery/apiary/New() - ..() - overlays += image('icons/obj/apiary_bees_etc.dmi', icon_state="apiary") - -/obj/machinery/apiary/bullet_act(var/obj/item/projectile/Proj) //Works with the Somatoray to modify plant variables. - if(istype(Proj ,/obj/item/projectile/energy/floramut)) - mut++ - else if(istype(Proj ,/obj/item/projectile/energy/florayield)) - if(!yieldmod) - yieldmod += 1 -// to_chat(world, "Yield increased by 1, from 0, to a total of [myseed.yield]") - else if(prob(1/(yieldmod * yieldmod) *100))//This formula gives you diminishing returns based on yield. 100% with 1 yield, decreasing to 25%, 11%, 6, 4, 2... - yieldmod += 1 -// to_chat(world, "Yield increased by 1, to a total of [myseed.yield]") - else - ..() - return - -/obj/machinery/apiary/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/queen_bee)) - if(health > 0) - to_chat(user, "\red There is already a queen in there.") - else - health = 10 - nutrilevel += 10 - user.drop_item() - qdel(O) - to_chat(user, "\blue You carefully insert the queen into [src], she gets busy making a hive.") - bees_in_hive = 0 - else if(istype(O, /obj/item/beezeez)) - beezeez += 100 - nutrilevel += 10 - user.drop_item() - if(health > 0) - to_chat(user, "\blue You insert [O] into [src]. A relaxed humming appears to pick up.") - else - to_chat(user, "\blue You insert [O] into [src]. Now it just needs some bees.") - qdel(O) - else if(istype(O, /obj/item/weapon/minihoe)) - if(health > 0) - to_chat(user, "You begin to dislodge the apiary from the tray, the bees don't like that.") - angry_swarm(user) - else - to_chat(user, "\blue You begin to dislodge the dead apiary from the tray.") - if(do_after(user, 50, target = src)) - new hydrotray_type(src.loc) - new /obj/item/apiary(src.loc) - to_chat(user, "\red You dislodge the apiary from the tray.") - qdel(src) - else if(istype(O, /obj/item/weapon/bee_net)) - var/obj/item/weapon/bee_net/N = O - if(N.caught_bees > 0) - to_chat(user, "\blue You empty the bees into the apiary.") - bees_in_hive += N.caught_bees - N.caught_bees = 0 - else - to_chat(user, "\blue There are no more bees in the net.") - else if(istype(O, /obj/item/weapon/reagent_containers/glass)) - var/obj/item/weapon/reagent_containers/glass/G = O - if(harvestable_honey > 0) - if(health > 0) - to_chat(user, "\red You begin to harvest the honey. The bees don't seem to like it.") - angry_swarm(user) - else - to_chat(user, "\blue You begin to harvest the honey.") - if(do_after(user,50, target = src)) - G.reagents.add_reagent("honey",harvestable_honey) - harvestable_honey = 0 - to_chat(user, "\blue You successfully harvest the honey.") - else - to_chat(user, "\blue There is no honey left to harvest.") - else - angry_swarm(user) - ..() - -/obj/machinery/apiary/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover) && mover.checkpass(PASSTABLE)) - return 1 - else - return 0 - -/obj/machinery/apiary/process() - - if(swarming > 0) - swarming -= 1 - if(swarming <= 0) - for(var/mob/living/simple_animal/bee/B in src.loc) - bees_in_hive += B.strength - qdel(B) - else if(bees_in_hive < 10) - for(var/mob/living/simple_animal/bee/B in src.loc) - bees_in_hive += B.strength - qdel(B) - - if(world.time > (lastcycle + cycledelay)) - lastcycle = world.time - if(health < 0) - return - - //magical bee formula - if(beezeez > 0) - beezeez -= 1 - - nutrilevel += 2 - health += 1 - toxic = max(0, toxic - 1) - - //handle nutrients - nutrilevel -= bees_in_hive / 10 + owned_bee_swarms.len / 5 - if(nutrilevel > 0) - bees_in_hive += 1 * yieldmod - if(health < maxhealth) - health++ - else - //nutrilevel is less than 1, so we're effectively subtracting here - health += max(nutrilevel - 1, round(-health / 2)) - bees_in_hive += max(nutrilevel - 1, round(-bees_in_hive / 2)) - if(owned_bee_swarms.len) - var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms) - B.target_turf = get_turf(src) - - //clear out some toxins - if(toxic > 0) - toxic -= 1 - health -= 1 - - if(health <= 0) - return - - //make a bit of honey - if(harvestable_honey < 50) - harvestable_honey += 0.5 - - //make some new bees - if(bees_in_hive >= 10 && prob(bees_in_hive * 10)) - var/mob/living/simple_animal/bee/B = new(get_turf(src), src) - owned_bee_swarms.Add(B) - B.mut = mut - B.toxic = toxic - bees_in_hive -= 1 - - //find some plants, harvest - for(var/obj/machinery/portable_atmospherics/hydroponics/H in view(7, src)) - if(H.seed && !H.dead && prob(owned_bee_swarms.len * 10)) - src.nutrilevel++ - H.nutrilevel++ - if(mut < H.mutation_mod - 1) - mut = H.mutation_mod - 1 - else if(mut > H.mutation_mod - 1) - H.mutation_mod = mut - - //flowers give us pollen (nutrients) -/* - All plants should be giving nutrients to the hive. - if(H.myseed.type == /obj/item/seeds/harebell || H.myseed.type == /obj/item/seeds/sunflowerseed) - src.nutrilevel++ - H.nutrilevel++ -*/ - //have a few beneficial effects on nearby plants - if(prob(10)) - H.lastcycle -= 5 - if(prob(10)) - H.seed.set_trait(TRAIT_ENDURANCE,max(H.seed.get_trait(TRAIT_ENDURANCE)*1.5,H.seed.get_trait(TRAIT_ENDURANCE)+1)) - if(H.toxins && prob(10)) - H.toxins = min(0, H.toxins - 1) - toxic++ - -/obj/machinery/apiary/proc/die() - if(owned_bee_swarms.len) - var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms) - B.target_turf = get_turf(src) - B.strength -= 1 - if(B.strength <= 0) - qdel(B) - else if(B.strength <= 5) - B.icon_state = "bees[B.strength]" - bees_in_hive = 0 - health = 0 - -/obj/machinery/apiary/proc/angry_swarm(var/mob/M) - for(var/mob/living/simple_animal/bee/B in owned_bee_swarms) - B.feral = 25 - B.target_mob = M - - swarming = 25 - - while(bees_in_hive > 0) - var/spawn_strength = bees_in_hive - if(bees_in_hive >= 5) - spawn_strength = 6 - - var/mob/living/simple_animal/bee/B = new(get_turf(src), src) - B.target_mob = M - B.strength = spawn_strength - B.feral = 25 - B.mut = mut - B.toxic = toxic - bees_in_hive -= spawn_strength - -/obj/machinery/apiary/verb/harvest_honeycomb() - set src in oview(1) - set name = "Harvest honeycomb" - set category = "Object" - - while(health > 15) - health -= 15 - var/obj/item/weapon/reagent_containers/food/snacks/honeycomb/H = new(src.loc) - if(toxic > 0) - H.reagents.add_reagent("toxin", toxic) - - to_chat(usr, "\blue You harvest the honeycomb from the hive. There is a wild buzzing!") - angry_swarm(usr) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm deleted file mode 100644 index 03568731dc5..00000000000 --- a/code/modules/hydroponics/trays/tray_process.dm +++ /dev/null @@ -1,142 +0,0 @@ -/obj/machinery/portable_atmospherics/hydroponics/process() - - /* MOVED INTO code\game\objects\effects\effect_system.dm - // Handle nearby smoke if any. - for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) - if(smoke.reagents.total_volume) - smoke.reagents.copy_to(src, 5) - */ - - //Do this even if we're not ready for a plant cycle. - process_reagents() - - // Update values every cycle rather than every process() tick. - if(force_update) - force_update = 0 - else if(world.time < (lastcycle + cycledelay)) - return - lastcycle = world.time - - // Weeds like water and nutrients, there's a chance the weed population will increase. - // Bonus chance if the tray is unoccupied. - if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 6 : 3)) - weedlevel += 1 * HYDRO_SPEED_MULTIPLIER - plant_hud_set_weed() - - // There's a chance for a weed explosion to happen if the weeds take over. - // Plants that are themselves weeds (weed_tolerance > 10) are unaffected. - if(weedlevel >= 10 && prob(10)) - if(!seed || weedlevel >= seed.get_trait(TRAIT_WEED_TOLERANCE)) - weed_invasion() - - // If there is no seed data (and hence nothing planted), - // or the plant is dead, process nothing further. - if(!seed || dead) - if(mechanical) update_icon() //Harvesting would fail to set alert icons properly. - return - - // Advance plant age. - current_cycle++ - if(current_cycle == 3) - age += 1 * HYDRO_SPEED_MULTIPLIER - current_cycle = 0 - - //Highly mutable plants have a chance of mutating every tick. - if(seed.get_trait(TRAIT_IMMUTABLE) == -1) - var/mut_prob = rand(1,100) - if(mut_prob <= 5) mutate(mut_prob == 1 ? 2 : 1) - - // Maintain tray nutrient and water levels. - if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0 && nutrilevel > 0 && prob(25)) - nutrilevel -= max(0,seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER) - plant_hud_set_nutrient() - if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 0 && waterlevel > 0 && prob(25)) - waterlevel -= max(0,seed.get_trait(TRAIT_WATER_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER) - plant_hud_set_water() - - // Make sure the plant is not starving or thirsty. Adequate - // water and nutrients will cause a plant to become healthier. - var/healthmod = rand(1,3) * HYDRO_SPEED_MULTIPLIER - if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS) && prob(35)) - health += (nutrilevel < 2 ? -healthmod : healthmod) - if(seed.get_trait(TRAIT_REQUIRES_WATER) && prob(35)) - health += (waterlevel < 10 ? -healthmod : healthmod) - - // Check that pressure, heat and light are all within bounds. - // First, handle an open system or an unconnected closed system. - var/turf/T = loc - var/datum/gas_mixture/environment - // If we're closed, take from our internal sources. - if(closed_system && (connected_port || holding)) - if(holding) - air_contents = holding.air_contents - environment = air_contents - // If atmos input is not there, grab from turf. - if(!environment && istype(T)) environment = T.return_air() - if(!environment) return - - // Seed datum handles gasses, light and pressure. - if(mechanical && closed_system) - health -= seed.handle_environment(T,environment,tray_light, holding) - else - health -= seed.handle_environment(T,environment) - - T.air_update_turf() - - // If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses - if(closed_system && connected_port) - connected_port.parent.update = 1 - - // Toxin levels beyond the plant's tolerance cause damage, but - // toxins are sucked up each tick and slowly reduce over time. - if(toxins > 0) - var/toxin_uptake = max(1,round(toxins/10)) - if(toxins > seed.get_trait(TRAIT_TOXINS_TOLERANCE)) - health -= toxin_uptake - toxins -= toxin_uptake - plant_hud_set_toxin() - - // Check for pests and weeds. - // Some carnivorous plants happily eat pests. - if(pestlevel > 0) - if(seed.get_trait(TRAIT_CARNIVOROUS)) - health += HYDRO_SPEED_MULTIPLIER - pestlevel -= HYDRO_SPEED_MULTIPLIER - else if(pestlevel >= seed.get_trait(TRAIT_PEST_TOLERANCE)) - health -= HYDRO_SPEED_MULTIPLIER - plant_hud_set_pest() - - // Some plants thrive and live off of weeds. - if(weedlevel > 0) - if(seed.get_trait(TRAIT_PARASITE)) - health += HYDRO_SPEED_MULTIPLIER - weedlevel -= HYDRO_SPEED_MULTIPLIER - else if(weedlevel >= seed.get_trait(TRAIT_WEED_TOLERANCE)) - health -= HYDRO_SPEED_MULTIPLIER - plant_hud_set_weed() - - // Handle life and death. - // If the plant gets too old, begin killing it each cycle - var/lifespan = 5 * seed.get_trait(TRAIT_MATURATION) - if(age > lifespan) - health -= rand(5,10) * HYDRO_SPEED_MULTIPLIER - - // When the plant dies, weeds thrive and pests die off. - check_health() - - // If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again. - if((age > seed.get_trait(TRAIT_MATURATION)) && \ - ((age - lastproduce) > seed.get_trait(TRAIT_PRODUCTION)) && \ - (!harvest && !dead)) - harvest = 1 - lastproduce = age - - if(prob(5)) // On each tick, there's a chance the pest population will increase - pestlevel += 0.5 * HYDRO_SPEED_MULTIPLIER - - // Some seeds will self-harvest if you don't keep a lid on them. - if(seed && seed.can_self_harvest && harvest && !closed_system && prob(5)) - harvest() - - check_health() - return diff --git a/code/modules/hydroponics/trays/tray_reagents.dm b/code/modules/hydroponics/trays/tray_reagents.dm deleted file mode 100644 index e4f68e6d106..00000000000 --- a/code/modules/hydroponics/trays/tray_reagents.dm +++ /dev/null @@ -1,217 +0,0 @@ - -//Process reagents being put into the tray. -/obj/machinery/portable_atmospherics/hydroponics/proc/process_reagents() - - if(!reagents) return - - if(reagents.total_volume <= 0) - return - - for(var/datum/reagent/R in reagents.reagent_list) - - var/reagent_total = reagents.get_reagent_amount(R.id) - - //These are here because they have checks that would clutter up the switch statement cases, and thus get handled after the switch(readability) - var/water_value = 0 - var/health_value = 0 - var/production_stat_value = 0 - var/potency_stat_value = 0 - - - switch(R.id) - /* EXAMPLE: - * - * if("example") - * //Nutrients - * nutrilevel += reagent_total * - * - * //Water - * water_value = - * - * //Toxins - * toxins += reagent_total * - * - * //Weeds and Pests - * weedlevel += reagent_total * - * pestlevel += reagent_total * - * - * //Mutagens - * handle_mutagens(reagent_total, , ) - * - * //Modifiers - * yield_mod += reagent_total * - * mutation_mod += reagent_total * - * - * //Health - * health_value = - * - * //Production Stat - * production_stat_value = - * - * //Potency Stat - * potency_stat_value = - * - */ - - if("adminordrazine") - nutrilevel += reagent_total * 1 - water_value = 1 - weedlevel += reagent_total * -5 - pestlevel += reagent_total * -5 - yield_mod += reagent_total * 1 - mutation_mod += reagent_total * 1 - health_value = 1 - if("ammonia") - nutrilevel += reagent_total * 1 - health_value = 0.5 - if("atrazine") - toxins += reagent_total * 3 - weedlevel += reagent_total * -8 - mutation_mod += reagent_total * 0.2 - health_value = -2 - if("beer") - nutrilevel += reagent_total * 0.25 - water_value = 0.7 - health_value = -0.05 - if("charcoal") - toxins += reagent_total * -2 - if("chlorine") - water_value = -0.5 - toxins += reagent_total * 1.5 - weedlevel += reagent_total * -3 - health_value = -1 - if("cryoxadone") - toxins += reagent_total * -3 - if(seed && !dead) - health += reagent_total * 3 - if("diethylamine") - nutrilevel += reagent_total * 2 - pestlevel += reagent_total * -2 - health_value = 1 - if("eznutrient") - nutrilevel += reagent_total * 1 - if("facid") - toxins += reagent_total * 3 - weedlevel += reagent_total * -4 - health_value = -2 - if("fishwater") - nutrilevel += reagent_total * 0.75 - water_value = 1 - if("fluorine") - water_value = -0.5 - toxins = reagent_total * 2.5 - weedlevel += reagent_total * -4 - health_value = -2 - if("holywater") - water_value = 1 - health_value = 0.1 - if("left4zed") - nutrilevel += reagent_total * 1 - mutation_mod += reagent_total * 0.2 - if("milk") - nutrilevel += reagent_total * 0.1 - water_value = 0.9 - if("mutagen") - handle_mutagens(reagent_total, 1, 5) - if("nutriment") - nutrilevel += reagent_total * 1 - yield_mod += reagent_total * 0.15 - health_value = 0.25 - if("phosphorus") - nutrilevel += reagent_total * 0.1 - water_value = -0.5 - weedlevel += reagent_total * -2 - health_value = -0.75 - if("plantmatter") - nutrilevel += reagent_total * 1.25 - yield_mod += reagent_total * 0.15 - health_value = 0.25 - if("protein") - nutrilevel += reagent_total * 1.75 - yield_mod += reagent_total * 0.15 - health_value = 0.25 - if("radium") - toxins += reagent_total * 2 - handle_mutagens(reagent_total, 10, 10) - mutation_mod += reagent_total * 0.2 - health_value = -1.5 - if("robustharvest") - nutrilevel += reagent_total * 1 - yield_mod += reagent_total * 0.2 - if("sacid") - toxins += reagent_total * 1.5 - weedlevel += reagent_total * -2 - health_value = -1 - if("saltpetre") - health_value = 0.25 - production_stat_value = -0.02 - potency_stat_value = 0.01 - if("sodawater") - nutrilevel += reagent_total * 0.1 - water_value = 1 - health_value = 0.1 - if("sugar") - nutrilevel += reagent_total * 0.1 - weedlevel += reagent_total * 2 - pestlevel += reagent_total * 2 - if("toxin") - toxins += reagent_total * 2 - if("water") - water_value = 1 - - //END SWITCH - - //Handle water changes - if(water_value) - var/water_change = 0 - water_change = reagent_total * water_value - waterlevel += water_change - if(water_value > 0) //adding water dilutes toxins - toxins -= round(water_change/4) - - //Handle health and stat changes (these require a non-dead seed to be present) - if(seed && !dead) - //Health - if(health_value) - health += reagent_total * health_value - //Stats - if(seed.get_trait(TRAIT_IMMUTABLE) <= 0) - //Production - if(production_stat_value && seed.get_trait(TRAIT_PRODUCTION) > 2) - if(!isnull(plant_controller.seeds[seed.name])) //This is so we don't affect plants in other trays unintentionally - seed = seed.diverge(2) //ENHANCE! - else - seed.update_name_prefixes(2) - var/new_production = seed.get_trait(TRAIT_PRODUCTION) + (reagent_total * production_stat_value) - seed.set_trait(TRAIT_PRODUCTION, max(2, new_production)) //can't drop below 2 with this method - //Potency - if(potency_stat_value) - if(!isnull(plant_controller.seeds[seed.name])) //This is so we don't affect plants in other trays unintentionally - seed = seed.diverge(2) //ENHANCE! - else - seed.update_name_prefixes(2) - var/new_potency = seed.get_trait(TRAIT_POTENCY) + (reagent_total * potency_stat_value) - seed.set_trait(TRAIT_POTENCY, max(0, min(100, new_potency))) //can't go above 100 or below 0 with this method - - //END FOR LOOP - - reagents.clear_reagents() - check_health() //This calls check_level_sanity, which is why it's not called from here directly - -/obj/machinery/portable_atmospherics/hydroponics/proc/handle_mutagens(var/amount, var/min_amount, var/step_amount) - //shouldn't be getting called without having reagent values supplied - if(!amount || !step_amount || !step_amount) - return - //shouldn't be getting called with negative values - if(amount < 0 || min_amount < 0 || step_amount < 0) - return - - if(amount > min_amount) - if(amount >= min_amount + (3 * step_amount)) - mutate(4) - else if(amount >= min_amount + (2 * step_amount)) - mutate(3) - else if(amount >= min_amount + step_amount) - mutate(2) - else if(amount >= min_amount) - mutate(1) diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm deleted file mode 100644 index d8c207c1c67..00000000000 --- a/code/modules/hydroponics/trays/tray_soil.dm +++ /dev/null @@ -1,70 +0,0 @@ -/obj/machinery/portable_atmospherics/hydroponics/soil - name = "soil" - icon_state = "soil" - density = 0 - use_power = 0 - mechanical = 0 - tray_light = 0 - -/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O,/obj/item/weapon/tank)) - return - else if(istype(O,/obj/item/weapon/crowbar)) - return - else - ..() - -/obj/machinery/portable_atmospherics/hydroponics/soil/New() - ..() - verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb - verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label - verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/setlight - verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/eject_tank_verb - -/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass() - return 1 - -// Holder for vine plants. -// Icons for plants are generated as overlays, so setting it to invisible wouldn't work. -// Hence using a blank icon. -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible - name = "plant" - icon = 'icons/obj/seeds.dmi' - icon_state = "blank" - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/New(var/newloc,var/datum/seed/newseed) - ..() - seed = newseed - dead = 0 - age = 1 - health = seed.get_trait(TRAIT_ENDURANCE) - lastcycle = world.time - pixel_y = rand(-5,5) - check_health() - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/remove_dead() - ..() - qdel(src) - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/harvest() - ..() - if(!seed) // Repeat harvests are a thing. - qdel(src) - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/die() - qdel(src) - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/process() - if(!seed) - qdel(src) - return - else if(name=="plant") - name = seed.display_name - ..() - -/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/Destroy() - // Check if we're masking a decal that needs to be visible again. - for(var/obj/effect/plant/plant in get_turf(src)) - if(plant.invisibility == INVISIBILITY_MAXIMUM) - plant.invisibility = initial(plant.invisibility) - return ..() diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm deleted file mode 100644 index 4086403c6e0..00000000000 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ /dev/null @@ -1,431 +0,0 @@ -//Analyzer, pestkillers, weedkillers, nutrients, hatchets, cutters, Rapid-Seed-Producer (RSP), corn cob. - -/obj/item/weapon/wirecutters/clippers - name = "plant clippers" - desc = "A tool used to take samples from plants." - -/obj/item/device/analyzer/plant_analyzer - name = "plant analyzer" - desc = "A scanner used to evaluate a plant's various areas of growth." - icon = 'icons/obj/device.dmi' - icon_state = "hydro" - item_state = "analyzer" - origin_tech = "magnets=1;biotech=1" - var/form_title - var/last_data - var/print_cooldown = 0 - var/cooldown_length = 50 // Five seconds - -/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb() - set name = "Print Plant Report" - set category = "Object" - set src = usr - - if(usr.incapacitated()) - return - - print_report(usr) - -/obj/item/device/analyzer/plant_analyzer/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["print"]) - print_report(usr) - -/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user) - if(!last_data) - to_chat(user, "There is no scan data to print.") - return - if(print_cooldown > world.time) - to_chat(user, "The printer is still cooling down.") - return - print_cooldown = world.time + cooldown_length - - playsound(loc, "sound/goonstation/machines/printer_thermal.ogg", 50, 1) - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src)) - P.name = "paper - [form_title]" - P.info = "[last_data]" - if(istype(user,/mob/living/carbon/human) && !(user.l_hand && user.r_hand)) - user.put_in_hands(P) - user.visible_message("\The [src] spits out a piece of paper.") - return - -/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user as mob) - print_report(user) - return 0 - -/obj/item/device/analyzer/plant_analyzer/afterattack(obj/target, mob/user, flag) - if(!flag) return - - var/datum/seed/grown_seed - var/datum/reagents/grown_reagents - - //--FalseIncarnate - var/IS_TRAY = 0 //used to track if the target is a hydroponics tray or soil. 1 if true, otherwise 0 - var/tray_age //age of the plant in the tray - var/tray_weed_level //weed level of tray - var/tray_pest_level //pest level of tray - var/tray_toxins //toxicity of the tray - var/tray_yield_mod //yield modifier of the tray - var/tray_mutation_mod //mutation modifier of the tray - //--FalseIncarnate - - if(istype(target,/obj/structure/table)) - return ..() - else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown)) - - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target - grown_seed = plant_controller.seeds[G.plantname] - grown_reagents = G.reagents - - else if(istype(target,/obj/item/weapon/grown)) - - var/obj/item/weapon/grown/G = target - grown_seed = plant_controller.seeds[G.plantname] - grown_reagents = G.reagents - - else if(istype(target,/obj/item/seeds)) - - var/obj/item/seeds/S = target - grown_seed = S.seed - - else if(istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - - var/obj/machinery/portable_atmospherics/hydroponics/H = target - - //--FalseIncarnate - //Flag the target as a tray for showing tray-specific stats - IS_TRAY = 1 - //Save tray data to matching variables - tray_age = H.age - tray_weed_level = H.weedlevel - tray_pest_level = H.pestlevel - tray_toxins = H.toxins - tray_yield_mod = H.yield_mod - tray_mutation_mod = H.mutation_mod - //--FalseIncarnate - - grown_seed = H.seed - grown_reagents = H.reagents - - if(!grown_seed) - to_chat(user, "[src] can tell you nothing about \the [target].") - return - - form_title = "[grown_seed.seed_name] (#[grown_seed.uid])" - var/dat = "

Plant data for [form_title]

" - user.visible_message("[user] runs the scanner over \the [target].") - - dat += "

General Data

" - - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - - //--FalseIncarnate - //Tray-specific stats like Age and Mutation Modifier, not shown if target was not a hydroponics tray or soil - if(IS_TRAY == 1) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - //--FalseIncarnate - - dat += "
Endurance[grown_seed.get_trait(TRAIT_ENDURANCE)]
Yield[grown_seed.get_trait(TRAIT_YIELD)]
Maturation time[grown_seed.get_trait(TRAIT_MATURATION)]
Production time[grown_seed.get_trait(TRAIT_PRODUCTION)]
Potency[grown_seed.get_trait(TRAIT_POTENCY)]
Species Discovery Value[grown_seed.get_trait(TRAIT_RARITY)]
Age[tray_age]
Weed Level[tray_weed_level]
Pest Level[tray_pest_level]
Toxins[tray_toxins]
Yield Modifier[tray_yield_mod]
Mutation Modifier[tray_mutation_mod]
" - - if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len) - dat += "

Reagent Data

" - - dat += "
This sample contains: " - for(var/datum/reagent/R in grown_reagents.reagent_list) - dat += "
- [R.id], [grown_reagents.get_reagent_amount(R.id)] unit(s)" - - dat += "

Other Data

" - - if(grown_seed.get_trait(TRAIT_HARVEST_REPEAT)) - dat += "This plant can be harvested repeatedly.
" - - if(grown_seed.get_trait(TRAIT_IMMUTABLE) == -1) - dat += "This plant is highly mutable.
" - else if(grown_seed.get_trait(TRAIT_IMMUTABLE) > 0) - dat += "This plant does not possess genetics that are alterable.
" - - if(grown_seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) - if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) - dat += "It consumes a small amount of nutrient fluid.
" - else if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) - dat += "It requires a heavy supply of nutrient fluid.
" - else - dat += "It requires a supply of nutrient fluid.
" - - if(grown_seed.get_trait(TRAIT_REQUIRES_WATER)) - if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) - dat += "It requires very little water.
" - else if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) - dat += "It requires a large amount of water.
" - else - dat += "It requires a stable supply of water.
" - - if(grown_seed.mutants && grown_seed.mutants.len) - dat += "It exhibits a high degree of potential subspecies shift.
" - - dat += "It thrives in a temperature of [grown_seed.get_trait(TRAIT_IDEAL_HEAT)] Kelvin." - - if(grown_seed.consume_gasses && grown_seed.consume_gasses.len) - for(var/gas in grown_seed.consume_gasses) - if(gas == "carbon_dioxide") gas = "carbon dioxide" - if(gas == "toxins") gas = "plasma" - dat += "
It requires an environment rich in [gas] gas to thrive." - - if(grown_seed.exude_gasses && grown_seed.exude_gasses.len) - for(var/gas in grown_seed.exude_gasses) - if(gas == "carbon_dioxide") gas = "carbon dioxide" - if(gas == "toxins") gas = "plasma" - dat += "
It releases [gas] gas as a byproduct of it's growth." - - if(grown_seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) - dat += "
It is well adapted to low pressure levels." - if(grown_seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) - dat += "
It is well adapted to high pressure levels." - - if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) - dat += "
It is well adapted to a range of temperatures." - else if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) - dat += "
It is very sensitive to temperature shifts." - - dat += "
It thrives in a light level of [grown_seed.get_trait(TRAIT_IDEAL_LIGHT)] lumen[grown_seed.get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]." - - if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) - dat += "
It is well adapted to a range of light levels." - else if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) - dat += "
It is very sensitive to light level shifts." - - if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) - dat += "
It is highly sensitive to toxins." - else if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) - dat += "
It is remarkably resistant to toxins." - - if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) - dat += "
It is highly sensitive to pests." - else if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) - dat += "
It is remarkably resistant to pests." - - if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) - dat += "
It is highly sensitive to weeds." - else if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) - dat += "
It is remarkably resistant to weeds." - - switch(grown_seed.get_trait(TRAIT_SPREAD)) - if(1) - dat += "
It is able to be planted outside of a tray." - if(2) - dat += "
It is a robust and vigorous vine that will spread rapidly." - - switch(grown_seed.get_trait(TRAIT_CARNIVOROUS)) - if(1) - dat += "
It is carniovorous and will eat tray pests for sustenance." - if(2) - dat += "
It is carnivorous and poses a significant threat to living things around it." - - if(grown_seed.get_trait(TRAIT_PARASITE)) - dat += "
It is capable of parisitizing and gaining sustenance from tray weeds." - if(grown_seed.get_trait(TRAIT_ALTER_TEMP)) - dat += "
It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] Kelvin." - - if(grown_seed.get_trait(TRAIT_BIOLUM)) - dat += "
It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]." - - if(grown_seed.get_trait(TRAIT_PRODUCES_POWER)) - dat += "
The fruit will function as a battery if prepared appropriately." - - if(grown_seed.get_trait(TRAIT_BATTERY_RECHARGE)) - dat += "
The fruit hums with an odd electrical energy." - - if(grown_seed.get_trait(TRAIT_STINGS)) - dat += "
The fruit is covered in stinging spines." - - if(grown_seed.get_trait(TRAIT_JUICY) == 1) - dat += "
The fruit is soft-skinned and juicy." - else if(grown_seed.get_trait(TRAIT_JUICY) == 2) - dat += "
The fruit is excessively juicy." - - if(grown_seed.get_trait(TRAIT_EXPLOSIVE)) - dat += "
The fruit is internally unstable." - - if(grown_seed.get_trait(TRAIT_TELEPORTING)) - dat += "
The fruit is temporal/spatially unstable." - - if(dat) - last_data = dat - dat += "

\[print report\]" - user << browse(dat,"window=plant_analyzer") - - return - -/obj/item/weapon/minihoe // -- Numbers - name = "mini hoe" - desc = "It's used for removing weeds or scratching your back." - icon = 'icons/obj/weapons.dmi' - icon_state = "hoe" - item_state = "hoe" - flags = CONDUCT | NOBLUDGEON - force = 5 - throwforce = 7 - w_class = 2 - materials = list(MAT_METAL=50) - attack_verb = list("slashed", "sliced", "cut", "clawed") - hitsound = 'sound/weapons/bladeslice.ogg' - -//Hatchets and things to kill kudzu -/obj/item/weapon/hatchet - name = "hatchet" - desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." - icon = 'icons/obj/weapons.dmi' - icon_state = "hatchet" - flags = CONDUCT - force = 12 - sharp = 1 - edge = 1 - w_class = 2 - throwforce = 15 - throw_speed = 4 - throw_range = 4 - materials = list(MAT_METAL=15000) - origin_tech = "materials=2;combat=1" - attack_verb = list("chopped", "torn", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - -/obj/item/weapon/hatchet/unathiknife - name = "duelling knife" - desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude." - icon = 'icons/obj/weapons.dmi' - icon_state = "unathiknife" - attack_verb = list("ripped", "torn", "cut") - -/obj/item/weapon/scythe - icon_state = "scythe0" - name = "scythe" - desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." - force = 13 - throwforce = 5 - sharp = 1 - edge = 1 - throw_speed = 2 - throw_range = 3 - w_class = 4 - var/extend = 1 - flags = CONDUCT - armour_penetration = 20 - slot_flags = SLOT_BACK - origin_tech = "materials=2;combat=2" - attack_verb = list("chopped", "sliced", "cut", "reaped") - hitsound = 'sound/weapons/bladeslice.ogg' - -/obj/item/weapon/scythe/afterattack(atom/A, mob/user as mob, proximity) - if(!proximity) return - if(istype(A, /obj/effect/plant) && extend == 1) - for(var/obj/effect/plant/B in orange(A,1)) - if(prob(80)) - B.die_off(1) - qdel(A) - -/obj/item/weapon/scythe/tele - icon_state = "tscythe0" - name = "telescopic scythe" - desc = "A sharp and curved blade on a collapsable fibremetal handle, this tool is the pinnacle of covert reaping technology." - force = 3.0 - sharp = 0 - edge = 0 - throw_speed = 2 - throw_range = 3 - w_class = 2 - extend = 0 - armour_penetration = 20 - slot_flags = SLOT_BELT - origin_tech = "materials=3;combat=3" - attack_verb = list("chopped", "sliced", "cut", "reaped") - hitsound = "swing_hit" - -/obj/item/weapon/scythe/tele/attack_self(mob/user as mob) - extend = !extend - if(extend) - to_chat(user, "With a flick of the wrist, you extend the scythe. It's reaping time!") - icon_state = "tscythe1" - item_state = "scythe0" - slot_flags &= ~SLOT_BELT - w_class = 4 //doesnt fit in backpack when its on for balance - force = 13 //normal scythe damage - attack_verb = list("chopped", "sliced", "cut", "reaped") - hitsound = 'sound/weapons/bladeslice.ogg' - //Extend sound (blade unsheath) - playsound(src.loc, 'sound/weapons/blade_unsheath.ogg', 50, 1) //Sound credit to Qat of Freesound.org - else - to_chat(user, "You collapse the scythe, folding it for easy storage.") - icon_state = "tscythe0" - item_state = "tscythe0" //no sprite in other words - slot_flags |= SLOT_BELT - w_class = 2 - force = 3 //not so robust now - attack_verb = list("hit", "poked") - hitsound = "swing_hit" - //Collapse sound (blade sheath) - playsound(src.loc, 'sound/weapons/blade_sheath.ogg', 50, 1) //Sound credit to Q.K. of Freesound.org - 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) - if(!blood_DNA) return - if(blood_overlay && (blood_DNA.len >= 1)) //updates blood overlay, if any - overlays.Cut()//this might delete other item overlays as well but eeeeeeeh - - var/icon/I = new /icon(src.icon, src.icon_state) - I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD) - I.Blend(new /icon('icons/effects/blood.dmi', "itemblood"),ICON_MULTIPLY) - blood_overlay = I - - overlays += blood_overlay - - return - -/obj/item/weapon/rsp - name = "\improper Rapid-Seed-Producer (RSP)" - desc = "A device used to rapidly deploy seeds." - icon = 'icons/obj/items.dmi' - icon_state = "rcd" - opacity = 0 - density = 0 - anchored = 0.0 - var/matter = 0 - var/mode = 1 - w_class = 3 - -/obj/item/weapon/bananapeel - name = "banana peel" - desc = "A peel from a banana." - icon = 'icons/obj/items.dmi' - icon_state = "banana_peel" - item_state = "banana_peel" - w_class = 1 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - -/obj/item/weapon/corncob - name = "corn cob" - desc = "A reminder of meals gone by." - icon = 'icons/obj/harvest.dmi' - icon_state = "corncob" - item_state = "corncob" - w_class = 1 - throwforce = 0 - throw_speed = 4 - throw_range = 20 diff --git a/code/modules/hydroponics/trays/tray_update_icons.dm b/code/modules/hydroponics/trays/tray_update_icons.dm deleted file mode 100644 index aac0822a283..00000000000 --- a/code/modules/hydroponics/trays/tray_update_icons.dm +++ /dev/null @@ -1,86 +0,0 @@ -//Refreshes the icon and sets the luminosity -/obj/machinery/portable_atmospherics/hydroponics/update_icon() - // Update name. - if(seed) - if(mechanical) - name = "[base_name] (#[seed.uid])" - else - name = "[seed.seed_name]" - else - name = initial(name) - - if(labelled) - name += " ([labelled])" - - overlays.Cut() - // Updates the plant overlay. - if(!isnull(seed)) - - if(mechanical && health <= (seed.get_trait(TRAIT_ENDURANCE) / 2)) - overlays += "over_lowhealth3" - - if(dead) - var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-dead" - var/image/dead_overlay = plant_controller.plant_icon_cache["[ikey]"] - if(!dead_overlay) - dead_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") - dead_overlay.color = DEAD_PLANT_COLOUR - overlays |= dead_overlay - else - if(!seed.growth_stages) - seed.update_growth_stages() - if(!seed.growth_stages) - to_chat(world, "Seed type [seed.get_trait(TRAIT_PLANT_ICON)] cannot find a growth stage value.") - return - var/overlay_stage = 1 - if(age >= seed.get_trait(TRAIT_MATURATION)) - overlay_stage = seed.growth_stages - else - var/maturation = seed.get_trait(TRAIT_MATURATION)/seed.growth_stages - if(maturation < 1) - maturation = 1 - overlay_stage = maturation ? max(1,round(age/maturation)) : 1 - var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]" - var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] - if(!plant_overlay) - plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") - plant_overlay.color = seed.get_trait(TRAIT_PLANT_COLOUR) - plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay - overlays |= plant_overlay - last_plant_ikey = ikey - - if(harvest && overlay_stage == seed.growth_stages) - ikey = "[seed.get_trait(TRAIT_PRODUCT_ICON)]" - var/image/harvest_overlay = plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] - if(!harvest_overlay) - harvest_overlay = image('icons/obj/hydroponics_products.dmi', "[ikey]") - harvest_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) - plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay - overlays |= harvest_overlay - - //Draw the cover. - if(closed_system) - overlays += "hydrocover" - - //Updated the various alert icons. - if(mechanical) - if(waterlevel <= 10) - overlays += "over_lowwater3" - if(nutrilevel <= 2) - overlays += "over_lownutri3" - if(weedlevel >= 5 || pestlevel >= 5 || toxins >= 40) - overlays += "over_alert3" - if(harvest) - overlays += "over_harvest3" - - // Update bioluminescence. - if(seed) - if(seed.get_trait(TRAIT_BIOLUM)) - var/clr - if(seed.get_trait(TRAIT_BIOLUM_COLOUR)) - clr = seed.get_trait(TRAIT_BIOLUM_COLOUR) - set_light(round(seed.get_trait(TRAIT_POTENCY)/10), l_color = clr) - return - - set_light(0) - return \ No newline at end of file diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm index 2c0932f1707..2decc555693 100644 --- a/code/modules/library/computers/checkout.dm +++ b/code/modules/library/computers/checkout.dm @@ -459,5 +459,5 @@ B.title = newbook.title B.author = newbook.author B.dat = newbook.content - B.icon_state = "book[rand(1,9)]" + B.icon_state = "book[rand(1,16)]" visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?") diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index ac6507ee720..6afe3f84518 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -217,8 +217,8 @@ var/global/list/library_section_names = list("Any", "Fiction", "Non-Fiction", "A var/obj/item/weapon/book/b = new(loc) b.dat = P.info b.name = "Print Job #[rand(100, 999)]" - b.icon_state = "book[rand(1,7)]" + b.icon_state = "book[rand(1,16)]" qdel(P) return 1 else - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/lighting/light_source.dm b/code/modules/lighting/light_source.dm deleted file mode 100644 index fd92e6675f1..00000000000 --- a/code/modules/lighting/light_source.dm +++ /dev/null @@ -1,257 +0,0 @@ -/datum/light_source - var/atom/top_atom - var/atom/source_atom - - var/turf/source_turf - var/light_power - var/light_range - var/light_color // string, decomposed by parse_light_color() - - var/lum_r - var/lum_g - var/lum_b - - var/tmp/applied_lum_r - var/tmp/applied_lum_g - var/tmp/applied_lum_b - - var/list/effect_str - var/list/effect_turf - - var/applied - - var/vis_update //Whetever we should smartly recalculate visibility. and then only update tiles that became (in) visible to us - var/needs_update - var/destroyed - var/force_update - -/datum/light_source/New(atom/owner, atom/top) - source_atom = owner - if(!source_atom.light_sources) source_atom.light_sources = list() - source_atom.light_sources += src - top_atom = top - if(top_atom != source_atom) - if(!top.light_sources) top.light_sources = list() - top_atom.light_sources += src - - source_turf = top_atom - light_power = source_atom.light_power - light_range = source_atom.light_range - light_color = source_atom.light_color - - parse_light_color() - - effect_str = list() - effect_turf = list() - - update() - - return ..() - -/datum/light_source/proc/destroy() - destroyed = 1 - force_update() - if(source_atom && source_atom.light_sources) source_atom.light_sources -= src - if(top_atom && top_atom.light_sources) top_atom.light_sources -= src - -/datum/light_source/proc/update(atom/new_top_atom) - if(new_top_atom && new_top_atom != top_atom) - if(top_atom != source_atom) top_atom.light_sources -= src - top_atom = new_top_atom - if(top_atom != source_atom) - if(!top_atom.light_sources) top_atom.light_sources = list() - top_atom.light_sources += src - - if(!needs_update) //Incase we're already updating either way. - lighting_update_lights += src - needs_update = 1 - -/datum/light_source/proc/force_update() - force_update = 1 - if(!needs_update) //Incase we're already updating either way. - needs_update = 1 - lighting_update_lights += src - -/datum/light_source/proc/vis_update() - if(!needs_update) - needs_update = 1 - lighting_update_lights += src - - vis_update = 1 - -/datum/light_source/proc/check() - if(!source_atom || !light_range || !light_power) - destroy() - return 1 - - if(!top_atom) - top_atom = source_atom - . = 1 - - if(istype(top_atom, /turf)) - if(source_turf != top_atom) - source_turf = top_atom - . = 1 - else if(top_atom.loc != source_turf) - source_turf = top_atom.loc - . = 1 - - if(source_atom.light_power != light_power) - light_power = source_atom.light_power - . = 1 - - if(source_atom.light_range != light_range) - light_range = source_atom.light_range - . = 1 - - if(light_range && light_power && !applied) - . = 1 - - if(source_atom.light_color != light_color) - light_color = source_atom.light_color - parse_light_color() - . = 1 - -/datum/light_source/proc/parse_light_color() - if(light_color) - lum_r = color2R(light_color) / 255 - lum_g = color2G(light_color) / 255 - lum_b = color2B(light_color) / 255 - else - lum_r = 1 - lum_g = 1 - lum_b = 1 - -#if LIGHTING_FALLOFF == 1 //circular - #define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT - #if LIGHTING_LAMBERTIAN == 1 - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1))) - #else - #define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range)) - #endif -#elif LIGHTING_FALLOFF == 2 //square - #define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT - #if LIGHTING_LAMBERTIAN == 1 - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1))) - #else - #define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range)) - #endif -#endif - -#define LUM_FALLOFF(swapvar, O, T) \ - LUM_DISTANCE(swapvar, O, T); \ - LUM_ATTENUATION(swapvar); - -/datum/light_source/proc/apply_lum() - applied = 1 - - // Cache the applied lum counts. - applied_lum_r = lum_r - applied_lum_g = lum_g - applied_lum_b = lum_b - - if(istype(source_turf)) - FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING) - if(T.lighting_overlay) - var/strength - LUM_FALLOFF(strength, T, source_turf) - strength *= light_power - - if(!strength) //Don't add turfs that aren't affected to the affected turfs. - continue - - strength = round(strength, LIGHTING_ROUND_VALUE) //Screw sinking points. - - effect_str += strength - - T.lighting_overlay.update_lumcount( - lum_r * strength, - lum_g * strength, - lum_b * strength - ) - - else - effect_str += 0 - - if(!T.affecting_lights) - T.affecting_lights = list() - - T.affecting_lights += src - effect_turf += T - END_FOR_DVIEW - -/datum/light_source/proc/remove_lum() - applied = 0 - var/i = 1 - for(var/turf/T in effect_turf) - if(T.affecting_lights) - T.affecting_lights -= src - - if(T.lighting_overlay) - var/str = effect_str[i] - T.lighting_overlay.update_lumcount(-str * applied_lum_r, -str * applied_lum_g, -str * applied_lum_b) - - i++ - - effect_str.Cut() - effect_turf.Cut() - -/datum/light_source/proc/forget_turf(turf/T) - var/idx = effect_turf.Find(T) - effect_turf.Cut(idx, idx + 1) - effect_str.Cut(idx, idx + 1) - -//Smartly updates the lighting, only removes lum from and adds lum to turfs that actually got changed. -//This is for lights that need to reconsider due to nearby opacity changes. -//Stupid dumb copy pasta because BYOND and speed. -/datum/light_source/proc/smart_vis_update() - var/list/view[0] - FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING) - view += T //Filter out turfs. - END_FOR_DVIEW - //This is the part where we calculate new turfs (if any) - var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added. - for(var/turf/T in new_turfs) - if(T.lighting_overlay) - LUM_FALLOFF(., T, source_turf) - . *= light_power - - if(!.) //Don't add turfs that aren't affected to the affected turfs. - continue - - . = round(., LIGHTING_ROUND_VALUE) - - effect_str += . - - T.lighting_overlay.update_lumcount( - lum_r * ., - lum_g * ., - lum_b * . - ) - - else - effect_str += 0 - - if(!T.affecting_lights) - T.affecting_lights = list() - - T.affecting_lights += src - effect_turf += T - - var/list/old_turfs = effect_turf - view - for(var/turf/T in old_turfs) - //Insert not-so-huge copy paste from remove_lum(). - var/idx = effect_turf.Find(T) //Get the index, luckily Find() is cheap in small lists like this. (with small I mean under a couple thousand len) - if(T.affecting_lights) - T.affecting_lights -= src - - if(T.lighting_overlay) - var/str = effect_str[idx] - T.lighting_overlay.update_lumcount(-str * lum_r, -str * lum_g, -str * lum_b) - - effect_turf.Cut(idx, idx + 1) - effect_str.Cut(idx, idx + 1) - -#undef LUM_FALLOFF -#undef LUM_DISTANCE -#undef LUM_ATTENUATION \ No newline at end of file diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm new file mode 100644 index 00000000000..92923e6b0d5 --- /dev/null +++ b/code/modules/lighting/lighting_area.dm @@ -0,0 +1,9 @@ +/area + luminosity = TRUE + var/dynamic_lighting = TRUE + +/area/New() + . = ..() + + if(dynamic_lighting) + luminosity = FALSE \ No newline at end of file diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm index 92500ecc1d9..679f6fb86ef 100644 --- a/code/modules/lighting/lighting_atom.dm +++ b/code/modules/lighting/lighting_atom.dm @@ -1,19 +1,30 @@ /atom var/light_power = 1 // intensity of the light var/light_range = 0 // range in tiles of the light - var/light_color // RGB string representing the colour of the light + var/light_color // Hexadecimal RGB string representing the colour of the light var/datum/light_source/light var/list/light_sources -/atom/proc/set_light(l_range, l_power, l_color) - if(l_power != null) light_power = l_power - if(l_range != null) light_range = l_range - if(l_color != null) light_color = l_color +// Nonsensical value for l_color default, so we can detect if it gets set to null. +#define NONSENSICAL_VALUE -99999 +/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE) + if(l_power != null) + light_power = l_power + + if(l_range != null) + light_range = l_range + + if(l_color != NONSENSICAL_VALUE) + light_color = l_color update_light() +#undef NONSENSICAL_VALUE + /atom/proc/update_light() + set waitfor = FALSE + if(!light_power || !light_range) if(light) light.destroy() @@ -31,9 +42,14 @@ /atom/New() . = ..() + if(light_power && light_range) update_light() + if(opacity && isturf(loc)) + var/turf/T = loc + T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. + /atom/Destroy() if(light) light.destroy() @@ -62,11 +78,22 @@ new_loc.reconsider_lights() /atom/proc/set_opacity(new_opacity) - var/old_opacity = opacity + if(new_opacity == opacity) + return + opacity = new_opacity var/turf/T = loc - if(old_opacity != new_opacity && istype(T)) + if(!isturf(T)) + return + + if(new_opacity == TRUE) + T.has_opaque_atom = TRUE T.reconsider_lights() + else + var/old_has_opaque_atom = T.has_opaque_atom + T.recalc_atom_opacity() + if(old_has_opaque_atom != T.has_opaque_atom) + T.reconsider_lights() /obj/item/equipped() . = ..() diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm new file mode 100644 index 00000000000..a464f5af2d0 --- /dev/null +++ b/code/modules/lighting/lighting_corner.dm @@ -0,0 +1,125 @@ +/var/list/datum/lighting_corner/all_lighting_corners = list() +/var/datum/lighting_corner/dummy/dummy_lighting_corner = new +// Because we can control each corner of every lighting overlay. +// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't). +// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting. + +// This list is what the code that assigns corners listens to, the order in this list is the order in which corners are added to the /turf/corners list. +/var/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST) + +/datum/lighting_corner + var/list/turf/masters = list() + var/list/datum/light_source/affecting = list() // Light sources affecting us. + var/active = FALSE // TRUE if one of our masters has dynamic lighting. + + var/x = 0 + var/y = 0 + var/z = 0 + + var/lum_r = 0 + var/lum_g = 0 + var/lum_b = 0 + + var/needs_update = FALSE + + var/cache_r = LIGHTING_SOFT_THRESHOLD + var/cache_g = LIGHTING_SOFT_THRESHOLD + var/cache_b = LIGHTING_SOFT_THRESHOLD + var/cache_mx = 0 + + var/update_gen = 0 + +/datum/lighting_corner/New(var/turf/new_turf, var/diagonal) + . = ..() + + all_lighting_corners += src + + masters[new_turf] = turn(diagonal, 180) + z = new_turf.z + + var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction. + var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one. + + x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5) + y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5) + + // My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal). + // Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered. + // So we'll have this hardcode instead. + var/turf/T + var/i + + // Diagonal one is easy. + T = get_step(new_turf, diagonal) + if (T) // In case we're on the map's border. + if (!T.corners) + T.corners = list(null, null, null, null) + + masters[T] = diagonal + i = LIGHTING_CORNER_DIAGONAL.Find(turn(diagonal, 180)) + T.corners[i] = src + + // Now the horizontal one. + T = get_step(new_turf, horizontal) + if (T) // Ditto. + if (!T.corners) + T.corners = list(null, null, null, null) + + masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates. + i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180)) + T.corners[i] = src + + // And finally the vertical one. + T = get_step(new_turf, vertical) + if (T) + if (!T.corners) + T.corners = list(null, null, null, null) + + masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates. + i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180)) + T.corners[i] = src + + update_active() + +/datum/lighting_corner/proc/update_active() + active = FALSE + for (var/turf/T in masters) + if (T.lighting_overlay) + active = TRUE + +// God that was a mess, now to do the rest of the corner code! Hooray! +/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b) + lum_r += delta_r + lum_g += delta_g + lum_b += delta_b + + if (!needs_update) + needs_update = TRUE + lighting_update_corners += src + +/datum/lighting_corner/proc/update_overlays() + + // Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually. + var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1. + . = 1 // factor + if (mx > 1) + . = 1 / mx + + else if (mx < LIGHTING_SOFT_THRESHOLD) + . = 0 // 0 means soft lighting. + + cache_r = lum_r * . || LIGHTING_SOFT_THRESHOLD + cache_g = lum_g * . || LIGHTING_SOFT_THRESHOLD + cache_b = lum_b * . || LIGHTING_SOFT_THRESHOLD + cache_mx = mx + + for (var/TT in masters) + var/turf/T = TT + if (T.lighting_overlay) + if (!T.lighting_overlay.needs_update) + T.lighting_overlay.needs_update = TRUE + lighting_update_overlays += T.lighting_overlay + + +/datum/lighting_corner/dummy/New() + return diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index 525de63a0af..7c2e1a55842 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -1,96 +1,81 @@ +var/list/all_lighting_overlays = list() // Global list of lighting overlays. /atom/movable/lighting_overlay name = "" mouse_opacity = 0 simulated = 0 anchored = 1 - flags = NOREACT icon = LIGHTING_ICON layer = LIGHTING_LAYER invisibility = INVISIBILITY_LIGHTING - color = "#000000" + color = LIGHTING_BASE_MATRIX icon_state = "light1" auto_init = 0 // doesn't need special init + blend_mode = BLEND_MULTIPLY - var/lum_r - var/lum_g - var/lum_b + var/lum_r = 0 + var/lum_g = 0 + var/lum_b = 0 - var/needs_update + var/needs_update = FALSE -/atom/movable/lighting_overlay/New() +/atom/movable/lighting_overlay/New(var/atom/loc, var/no_update = FALSE) . = ..() verbs.Cut() + global.all_lighting_overlays += src var/turf/T = loc //If this runtimes atleast we'll know what's creating overlays outside of turfs. + T.lighting_overlay = src T.luminosity = 0 - -/atom/movable/lighting_overlay/proc/get_clamped_lum(var/minlum = 0, var/maxlum = 1) - var/lum = max(lum_r, lum_g, lum_b) - if(lum <= minlum) - return 0 - else if(lum >= maxlum) - return 1 - else - return (lum - minlum) / (maxlum - minlum) - -/atom/movable/lighting_overlay/proc/update_lumcount(delta_r, delta_g, delta_b) - if(!delta_r && !delta_g && !delta_b) //Nothing is being changed all together. + if(no_update) return - - var/should_update = 0 - - if(!needs_update) //If this isn't true, we're already updating anyways. - if(max(lum_r, lum_g, lum_b) < 1) //Any change that could happen WILL change appearance. - should_update = 1 - - else if(max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b) < 1) //The change would bring us under 1 max lum, again, guaranteed to change appearance. - should_update = 1 - - else //We need to make sure that the colour ratios won't change in this code block. - var/mx1 = max(lum_r, lum_g, lum_b) - var/mx2 = max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b) - - if(lum_r / mx1 != (lum_r + delta_r) / mx2 || lum_g / mx1 != (lum_g + delta_g) / mx2 || lum_b / mx1 != (lum_b + delta_b) / mx2) //Stuff would change. - should_update = 1 - - lum_r = max(lum_r + delta_r, 0) //Lum shouldn't drop below 1 - lum_g = max(lum_g + delta_g, 0) - lum_b = max(lum_b + delta_b, 0) - - if(!needs_update && should_update) - needs_update = 1 - lighting_update_overlays += src + update_overlay() /atom/movable/lighting_overlay/proc/update_overlay() + set waitfor = FALSE var/turf/T = loc - if(istype(T)) //Incase we're not on a turf, pool ourselves, something happened. - if(lum_r == lum_g && lum_r == lum_b) //greyscale - blend_mode = BLEND_OVERLAY - if(lum_r <= 0) - T.luminosity = 0 - color = "#000000" - alpha = 255 - else - T.luminosity = 1 - color = "#000000" - alpha = (1 - min(lum_r, 1)) * 255 + if(!istype(T)) + if(loc) + log_debug("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!") else - alpha = 255 - var/mx = max(lum_r, lum_g, lum_b) - . = 1 // factor - if(mx > 1) - . = 1/mx - blend_mode = BLEND_MULTIPLY - color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .) - if(color != "#000000") - T.luminosity = 1 - else //No light, set the turf's luminosity to 0 to remove it from view() - T.luminosity = 0 - else - //warning("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!") //fucking bullshit bugs means this spams when shuttles move, feel free to fix - log_debug("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!") + log_debug("A lighting overlay realised it was in nullspace in update_overlay() and got pooled!") qdel(src) + return + + // To the future coder who sees this and thinks + // "Why didn't he just use a loop?" + // Well my man, it's because the loop performed like shit. + // And there's no way to improve it because + // without a loop you can make the list all at once which is the fastest you're gonna get. + // Oh it's also shorter line wise. + // Including with these comments. + + // See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are. + // No I seriously cannot think of a more efficient method, fuck off Comic. + var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner + var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner + var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner + var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner + + var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) + + var/list/new_matrix = list( + cr.cache_r, cr.cache_g, cr.cache_b, 0, + cg.cache_r, cg.cache_g, cg.cache_b, 0, + cb.cache_r, cb.cache_g, cb.cache_b, 0, + ca.cache_r, ca.cache_g, ca.cache_b, 0, + 0, 0, 0, 1 + ) + var/lum = max > LIGHTING_SOFT_THRESHOLD + + if(lum) + luminosity = 1 + animate(src, color = new_matrix, time = 5) + else + animate(src, color = new_matrix, time = 5) + animate(luminosity = 0, time = 0) + + /atom/movable/lighting_overlay/singularity_act() return @@ -99,10 +84,13 @@ return /atom/movable/lighting_overlay/Destroy() - lighting_update_overlays -= src + global.all_lighting_overlays -= src + global.lighting_update_overlays -= src + global.lighting_update_overlays_old -= src var/turf/T = loc if(istype(T)) T.lighting_overlay = null + T.luminosity = 1 return ..() diff --git a/code/modules/lighting/lighting_process.dm b/code/modules/lighting/lighting_process.dm deleted file mode 100644 index 916920393ba..00000000000 --- a/code/modules/lighting/lighting_process.dm +++ /dev/null @@ -1,35 +0,0 @@ -/datum/controller/process/lighting - var/last_light_count = 0 - var/last_overlay_count = 0 - -/datum/controller/process/lighting/doWork() - var/list/lighting_update_lights_old = lighting_update_lights //We use a different list so any additions to the update lists during a delay from SCHECK don't cause things to be cut from the list without being updated. - last_light_count = lighting_update_lights.len - lighting_update_lights = null //Nulling it first because of http://www.byond.com/forum/?post=1854520 - lighting_update_lights = list() - - for(var/datum/light_source/L in lighting_update_lights_old) - if(L.destroyed || L.check() || L.force_update) - L.remove_lum() - if(!L.destroyed) - L.apply_lum() - - else if(L.vis_update) //We smartly update only tiles that became (in) visible to use. - L.smart_vis_update() - - L.vis_update = 0 - L.force_update = 0 - L.needs_update = 0 - - SCHECK - - var/list/lighting_update_overlays_old = lighting_update_overlays //Same as above. - last_overlay_count = lighting_update_overlays.len - lighting_update_overlays = null //Same as above - lighting_update_overlays = list() - - for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old) - O.update_overlay() - O.needs_update = 0 - - SCHECK diff --git a/code/modules/lighting/lighting_setup.dm b/code/modules/lighting/lighting_setup.dm new file mode 100644 index 00000000000..981de658649 --- /dev/null +++ b/code/modules/lighting/lighting_setup.dm @@ -0,0 +1,16 @@ +/proc/create_all_lighting_overlays() + for(var/zlevel = 1 to world.maxz) + create_lighting_overlays_zlevel(zlevel) + +/proc/create_lighting_overlays_zlevel(var/zlevel) + ASSERT(zlevel) + + for(var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))) + if(!T.dynamic_lighting) + continue + + var/area/A = T.loc + if(!A.dynamic_lighting) + continue + + new /atom/movable/lighting_overlay(T, TRUE) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm new file mode 100644 index 00000000000..c26522dc5a7 --- /dev/null +++ b/code/modules/lighting/lighting_source.dm @@ -0,0 +1,283 @@ +// This is where the fun begins. +// These are the main datums that emit light. + +/datum/light_source + var/atom/top_atom // The atom we're emitting light from(for example a mob if we're from a flashlight that's being held). + var/atom/source_atom // The atom that we belong to. + + var/turf/source_turf // The turf under the above. + var/light_power // Intensity of the emitter light. + var/light_range // The range of the emitted light. + var/light_color // The colour of the light, string, decomposed by parse_light_color() + + // Variables for keeping track of the colour. + var/lum_r + var/lum_g + var/lum_b + + // The lumcount values used to apply the light. + var/tmp/applied_lum_r + var/tmp/applied_lum_g + var/tmp/applied_lum_b + + var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners. + var/list/turf/affecting_turfs + + var/applied = FALSE // Whether we have applied our light yet or not. + + var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became(in)visible to us. + var/needs_update // Whether we are queued for an update. + var/destroyed // Whether we are destroyed and need to stop emitting light. + var/force_update + +/datum/light_source/New(var/atom/owner, var/atom/top) + source_atom = owner // Set our new owner. + if(!source_atom.light_sources) + source_atom.light_sources = list() + + source_atom.light_sources += src // Add us to the lights of our owner. + top_atom = top + if(top_atom != source_atom) + if(!top.light_sources) + top.light_sources = list() + + top_atom.light_sources += src + + source_turf = top_atom + light_power = source_atom.light_power + light_range = source_atom.light_range + light_color = source_atom.light_color + + parse_light_color() + + effect_str = list() + affecting_turfs = list() + + update() + + return ..() + +// Kill ourselves. +/datum/light_source/proc/destroy() + destroyed = TRUE + force_update() + if(source_atom) + source_atom.light_sources -= src + + if(top_atom) + top_atom.light_sources -= src + +// Call it dirty, I don't care. +// This is here so there's no performance loss on non-instant updates from the fact that the engine can also do instant updates. +// If you're wondering what's with the "BYOND" argument: BYOND won't let me have a() macro that has no arguments :|. +#define effect_update(BYOND) \ + if(!needs_update) \ + { \ + lighting_update_lights += src; \ + needs_update = TRUE; \ + } + +// This proc will cause the light source to update the top atom, and add itself to the update queue. +/datum/light_source/proc/update(var/atom/new_top_atom) + // This top atom is different. + if(new_top_atom && new_top_atom != top_atom) + if(top_atom != source_atom) // Remove ourselves from the light sources of that top atom. + top_atom.light_sources -= src + + top_atom = new_top_atom + + if(top_atom != source_atom) + if(!top_atom.light_sources) + top_atom.light_sources = list() + + top_atom.light_sources += src // Add ourselves to the light sources of our new top atom. + + effect_update(null) + +// Will force an update without checking if it's actually needed. +/datum/light_source/proc/force_update() + force_update = 1 + + effect_update(null) + +// Will cause the light source to recalculate turfs that were removed or added to visibility only. +/datum/light_source/proc/vis_update() + vis_update = 1 + + effect_update(null) + +// Will check if we actually need to update, and update any variables that may need to be updated. +/datum/light_source/proc/check() + if(!source_atom || !light_range || !light_power) + destroy() + return 1 + + if(!top_atom) + top_atom = source_atom + . = 1 + + if(isturf(top_atom)) + if(source_turf != top_atom) + source_turf = top_atom + . = 1 + else if(top_atom.loc != source_turf) + source_turf = top_atom.loc + . = 1 + + if(source_atom.light_power != light_power) + light_power = source_atom.light_power + . = 1 + + if(source_atom.light_range != light_range) + light_range = source_atom.light_range + . = 1 + + if(light_range && light_power && !applied) + . = 1 + + if(source_atom.light_color != light_color) + light_color = source_atom.light_color + parse_light_color() + . = 1 + +// Decompile the hexadecimal colour into lumcounts of each perspective. +/datum/light_source/proc/parse_light_color() + if(light_color) + lum_r = GetRedPart (light_color) / 255 + lum_g = GetGreenPart(light_color) / 255 + lum_b = GetBluePart (light_color) / 255 + else + lum_r = 1 + lum_g = 1 + lum_b = 1 + +// Macro that applies light to a new corner. +// It is a macro in the interest of speed, yet not having to copy paste it. +// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line. +// As such this all gets counted as a single line. +// The braces and semicolons are there to be able to do this on a single line. + +#define APPLY_CORNER(C) \ + . = LUM_FALLOFF(C, source_turf); \ + \ + . *= light_power; \ + \ + effect_str[C] = .; \ + \ + C.update_lumcount \ + ( \ + . * applied_lum_r, \ + . * applied_lum_g, \ + . * applied_lum_b \ + ); + +// I don't need to explain what this does, do I? +#define REMOVE_CORNER(C) \ + . = -effect_str[C]; \ + C.update_lumcount \ + ( \ + . * applied_lum_r, \ + . * applied_lum_g, \ + . * applied_lum_b \ + ); + +// This is the define used to calculate falloff. +#define LUM_FALLOFF(C, T)(1 - CLAMP01(sqrt((C.x - T.x) ** 2 +(C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range))) + +/datum/light_source/proc/apply_lum() + var/static/update_gen = 1 + applied = 1 + + // Keep track of the last applied lum values so that the lighting can be reversed + applied_lum_r = lum_r + applied_lum_g = lum_g + applied_lum_b = lum_b + + FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING) + if(!T.lighting_corners_initialised) + T.generate_missing_corners() + + for(var/datum/lighting_corner/C in T.get_corners()) + if(C.update_gen == update_gen) + continue + + C.update_gen = update_gen + C.affecting += src + + if(!C.active) + effect_str[C] = 0 + continue + + APPLY_CORNER(C) + + if(!T.affecting_lights) + T.affecting_lights = list() + + T.affecting_lights += src + affecting_turfs += T + + update_gen++ + +/datum/light_source/proc/remove_lum() + applied = FALSE + + for(var/turf/T in affecting_turfs) + if(!T.affecting_lights) + T.affecting_lights = list() + else + T.affecting_lights -= src + + affecting_turfs.Cut() + + for(var/datum/lighting_corner/C in effect_str) + REMOVE_CORNER(C) + + C.affecting -= src + + effect_str.Cut() + +/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C) + if(effect_str.Find(C)) // Already have one. + REMOVE_CORNER(C) + + APPLY_CORNER(C) + +/datum/light_source/proc/smart_vis_update() + var/list/datum/lighting_corner/corners = list() + var/list/turf/turfs = list() + FOR_DVIEW(var/turf/T, light_range, source_turf, 0) + if(!T.lighting_corners_initialised) + T.generate_missing_corners() + corners |= T.get_corners() + turfs += T + + var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them. + affecting_turfs += L + for(var/turf/T in L) + if(!T.affecting_lights) + T.affecting_lights = list(src) + else + T.affecting_lights += src + + L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights. + affecting_turfs -= L + for(var/turf/T in L) + T.affecting_lights -= src + + for(var/datum/lighting_corner/C in corners - effect_str) // New corners + C.affecting += src + if(!C.active) + effect_str[C] = 0 + continue + + APPLY_CORNER(C) + + for(var/datum/lighting_corner/C in effect_str - corners) // Old, now gone, corners. + REMOVE_CORNER(C) + C.affecting -= src + effect_str -= C + +#undef effect_update +#undef LUM_FALLOFF +#undef REMOVE_CORNER +#undef APPLY_CORNER diff --git a/code/modules/lighting/lighting_system.dm b/code/modules/lighting/lighting_system.dm deleted file mode 100644 index bdad6316395..00000000000 --- a/code/modules/lighting/lighting_system.dm +++ /dev/null @@ -1,25 +0,0 @@ -/var/list/lighting_update_lights = list() -/var/list/lighting_update_overlays = list() - -/area/var/lighting_use_dynamic = 1 - -// duplicates lots of code, but this proc needs to be as fast as possible. -/proc/create_lighting_overlays(zlevel = 0) - var/area/A - if(zlevel == 0) // populate all zlevels - for(var/turf/T in world) - if(T.dynamic_lighting) - A = T.loc - if(A.lighting_use_dynamic) - var/atom/movable/lighting_overlay/O = new(T) - T.lighting_overlay = O - - else - for(var/x = 1; x <= world.maxx; x++) - for(var/y = 1; y <= world.maxy; y++) - var/turf/T = locate(x, y, zlevel) - if(T.dynamic_lighting) - A = T.loc - if(A.lighting_use_dynamic) - var/atom/movable/lighting_overlay/O = new(T) - T.lighting_overlay = O \ No newline at end of file diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 53d9ab0455c..ddb934aed61 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -1,26 +1,102 @@ /turf - var/list/affecting_lights - var/atom/movable/lighting_overlay/lighting_overlay + var/dynamic_lighting = TRUE + luminosity = 1 + var/tmp/lighting_corners_initialised = FALSE + + var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf. + var/tmp/atom/movable/lighting_overlay/lighting_overlay // Our lighting overlay. + var/tmp/list/datum/lighting_corner/corners + var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. + +/turf/New() + . = ..() + + if(opacity) + has_opaque_atom = TRUE + +// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() for(var/datum/light_source/L in affecting_lights) L.vis_update() -/turf/proc/lighting_clear_overlays() +/turf/proc/lighting_clear_overlay() if(lighting_overlay) qdel(lighting_overlay) -/turf/proc/lighting_build_overlays() + for(var/datum/lighting_corner/C in corners) + C.update_active() + +// Builds a lighting overlay for us, but only if our area is dynamic. +/turf/proc/lighting_build_overlay() if(lighting_overlay) return var/area/A = loc - if(A.lighting_use_dynamic) - var/atom/movable/lighting_overlay/O = new(src) - lighting_overlay = O - // forcibly refresh lighting on this tile - // must make light forget tile or it wil remain - // convinced that it is already lighting it - for(var/datum/light_source/L in affecting_lights) - L.forget_turf(src) - L.vis_update() \ No newline at end of file + if(A.dynamic_lighting) + if(!lighting_corners_initialised) + generate_missing_corners() + + new /atom/movable/lighting_overlay(src) + + for(var/datum/lighting_corner/C in corners) + if(!C.active) // We would activate the corner, calculate the lighting for it. + for(var/L in C.affecting) + var/datum/light_source/S = L + S.recalc_corner(C) + + C.active = TRUE + +// Used to get a scaled lumcount. +/turf/proc/get_lumcount(var/minlum = 0, var/maxlum = 1) + if(!lighting_overlay) + return 1 + + var/totallums = 0 + for(var/datum/lighting_corner/L in corners) + totallums += max(L.lum_r, L.lum_g, L.lum_b) + + totallums /= 4 // 4 corners, max channel selected, return the average + + totallums =(totallums - minlum) /(maxlum - minlum) + + return CLAMP01(totallums) + +// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. +/turf/proc/recalc_atom_opacity() + has_opaque_atom = FALSE + for(var/atom/A in src.contents + src) // Loop through every movable atom on our tile PLUS ourselves (we matter too...) + if(A.opacity) + has_opaque_atom = TRUE + +// If an opaque movable atom moves around we need to potentially update visibility. +/turf/Entered(var/atom/movable/Obj, var/atom/OldLoc) + . = ..() + + if(Obj && Obj.opacity) + has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case. + reconsider_lights() + +/turf/Exited(var/atom/movable/Obj, var/atom/newloc) + . = ..() + + if(Obj && Obj.opacity) + recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates. + reconsider_lights() + +/turf/proc/get_corners() + if(has_opaque_atom) + return null // Since this proc gets used in a for loop, null won't be looped though. + + return corners + +/turf/proc/generate_missing_corners() + lighting_corners_initialised = TRUE + if(!corners) + corners = list(null, null, null, null) + + for(var/i = 1 to 4) + if(corners[i]) // Already have a corner on this direction. + continue + + corners[i] = new /datum/lighting_corner(src, LIGHTING_CORNER_DIAGONAL[i]) diff --git a/code/modules/lighting/~lighting_undefs.dm b/code/modules/lighting/~lighting_undefs.dm index 09100322b8a..2de3f9dbe26 100644 --- a/code/modules/lighting/~lighting_undefs.dm +++ b/code/modules/lighting/~lighting_undefs.dm @@ -1,9 +1,7 @@ -#undef LIGHTING_INTERVAL - #undef LIGHTING_FALLOFF #undef LIGHTING_LAMBERTIAN #undef LIGHTING_HEIGHT -#undef LIGHTING_RESOLUTION -#undef LIGHTING_LAYER -#undef LIGHTING_ICON \ No newline at end of file +#undef LIGHTING_ICON + +#undef LIGHTING_BASE_MATRIX diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index cd229550880..c7212fe5a15 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -22,7 +22,7 @@ switch(loot) if(1 to 5) //5% chance new /obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src) - new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus(src) + new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus(src) new /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey(src) new /obj/item/weapon/lighter(src) if(6 to 10) @@ -41,11 +41,9 @@ if(21 to 25) for(var/i in 1 to 5) new /obj/item/weapon/contraband/poster(src) - if(26 to 30) + if(26 to 35) for(var/i in 1 to 3) new /obj/item/weapon/reagent_containers/glass/beaker/noreact(src) - if(31 to 35) - new /obj/item/seeds/cash(src) if(36 to 40) new /obj/item/weapon/melee/baton(src) if(41 to 45) @@ -65,7 +63,7 @@ if(57 to 58) new /obj/item/toy/syndicateballoon(src) if(59 to 60) - new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper(src) + new /obj/item/borg/upgrade/modkit/aoe/mobs(src) new /obj/item/clothing/suit/space(src) new /obj/item/clothing/head/helmet/space(src) if(61 to 62) diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index fb98f3a8c15..cc6529f665d 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -313,7 +313,7 @@ anchored = 1.0 var/obj/item/weapon/card/id/inserted_id var/list/prize_list = list( - new /datum/data/mining_equipment("Stimpack", /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack, 50), + new /datum/data/mining_equipment("Stimpack", /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack, 50), new /datum/data/mining_equipment("Teporone MediPen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/teporone, 50), new /datum/data/mining_equipment("MediPen Bundle", /obj/item/weapon/storage/box/autoinjector/utility, 200), new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 100), @@ -324,10 +324,10 @@ new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 400), new /datum/data/mining_equipment("Hivelord Stabilizer", /obj/item/weapon/hivelordstabilizer, 400), new /datum/data/mining_equipment("Mining Drone", /obj/item/weapon/mining_drone_cube, 500), - new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_ugprade, 400), - new /datum/data/mining_equipment("Drone Health Upgrade",/obj/item/device/mine_bot_ugprade/health, 400), - new /datum/data/mining_equipment("Drone Ranged Upgrade",/obj/item/device/mine_bot_ugprade/cooldown, 600), - new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/weapon/twohanded/required/mining_hammer, 750), + new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_upgrade, 400), + new /datum/data/mining_equipment("Drone Health Upgrade",/obj/item/device/mine_bot_upgrade/health, 400), + new /datum/data/mining_equipment("Drone Ranged Upgrade",/obj/item/device/mine_bot_upgrade/cooldown, 600), + new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/weapon/twohanded/required/mining_hammer, 750), new /datum/data/mining_equipment("Drone AI Upgrade", /obj/item/slimepotion/sentience/mining, 1000), new /datum/data/mining_equipment("GAR mesons", /obj/item/clothing/glasses/meson/gar, 500), new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/weapon/storage/firstaid/brute, 600), @@ -342,7 +342,14 @@ new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000), new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), new /datum/data/mining_equipment("Super Resonator", /obj/item/weapon/resonator/upgraded, 2500), - new /datum/data/mining_equipment("Super Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator/super, 3000), + new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100), + new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150), + new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250), + new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300), + new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000), + new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000), + new /datum/data/mining_equipment("KA Cooldown Decrease",/obj/item/borg/upgrade/modkit/cooldown, 1000), + new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000), new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500), ) @@ -727,7 +734,7 @@ ranged = 1 sentience_type = SENTIENCE_MINEBOT ranged_message = "shoots" - ranged_cooldown_cap = 3 + ranged_cooldown_time = 30 projectiletype = /obj/item/projectile/kinetic projectilesound = 'sound/weapons/Gunshot4.ogg' speak_emote = list("states") @@ -737,6 +744,7 @@ healable = 0 var/mode = MINEDRONE_COLLECT var/light_on = 0 + var/mesons_active var/datum/action/innate/minedrone/toggle_light/toggle_light_action var/datum/action/innate/minedrone/toggle_meson_vision/toggle_meson_vision_action @@ -863,6 +871,28 @@ mode = MINEDRONE_COLLECT SetCollectBehavior() + +/mob/living/simple_animal/hostile/mining_drone/update_sight() + if(!client) + return + if(stat == DEAD) + grant_death_vision() + return + + if(mesons_active) + sight |= SEE_TURFS + see_invisible = SEE_INVISIBLE_MINIMUM + else + sight &= ~SEE_TURFS + see_invisible = SEE_INVISIBLE_LIVING + + see_in_dark = initial(see_in_dark) + + if(client.eye != src) + var/atom/A = client.eye + if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. + return + //Actions for sentient minebots /datum/action/innate/minedrone @@ -889,15 +919,10 @@ /datum/action/innate/minedrone/toggle_meson_vision/Activate() var/mob/living/simple_animal/hostile/mining_drone/user = owner + user.mesons_active = !user.mesons_active + user.update_sight() - if(user.sight & SEE_TURFS) - user.sight &= ~SEE_TURFS - user.see_invisible = SEE_INVISIBLE_LIVING - else - user.sight |= SEE_TURFS - user.see_invisible = SEE_INVISIBLE_MINIMUM - - to_chat(user, "You toggle your meson vision [(user.sight & SEE_TURFS) ? "on" : "off"].") + to_chat(user, "You toggle your meson vision [(user.mesons_active) ? "on" : "off"].") /datum/action/innate/minedrone/toggle_mode name = "Toggle Mode" @@ -920,18 +945,18 @@ //Melee -/obj/item/device/mine_bot_ugprade +/obj/item/device/mine_bot_upgrade name = "minebot melee upgrade" desc = "A minebot upgrade." icon_state = "door_electronics" icon = 'icons/obj/doors/door_assembly.dmi' -/obj/item/device/mine_bot_ugprade/afterattack(mob/living/simple_animal/hostile/mining_drone/M, mob/user, proximity) +/obj/item/device/mine_bot_upgrade/afterattack(mob/living/simple_animal/hostile/mining_drone/M, mob/user, proximity) if(!istype(M) || !proximity) return upgrade_bot(M, user) -/obj/item/device/mine_bot_ugprade/proc/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) +/obj/item/device/mine_bot_upgrade/proc/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) if(M.melee_damage_upper != initial(M.melee_damage_upper)) to_chat(user, "[M] already has a combat upgrade installed!") return @@ -942,10 +967,10 @@ //Health -/obj/item/device/mine_bot_ugprade/health +/obj/item/device/mine_bot_upgrade/health name = "minebot chassis upgrade" -/obj/item/device/mine_bot_ugprade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) +/obj/item/device/mine_bot_upgrade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) if(M.maxHealth != initial(M.maxHealth)) to_chat(user, "[M] already has a reinforced chassis!") return @@ -956,14 +981,14 @@ //Cooldown -/obj/item/device/mine_bot_ugprade/cooldown +/obj/item/device/mine_bot_upgrade/cooldown name = "minebot cooldown upgrade" -/obj/item/device/mine_bot_ugprade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) - if(M.ranged_cooldown_cap != initial(M.ranged_cooldown_cap)) +/obj/item/device/mine_bot_upgrade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user) + if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time)) to_chat(user, "[M] already has a decreased weapon cooldown!") return - M.ranged_cooldown_cap = 1 + M.ranged_cooldown_time = 10 to_chat(user, "You upgrade [M]'s ranged weaponry, reducing its cooldown.") qdel(src) diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm new file mode 100644 index 00000000000..922dd34a166 --- /dev/null +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -0,0 +1,205 @@ +/obj/structure/flora/ash + gender = PLURAL + icon = 'icons/obj/lavaland/ash_flora.dmi' + icon_state = "l_mushroom" + name = "large mushrooms" + desc = "A number of large mushrooms, covered in a faint layer of ash and what can only be spores." + var/harvested_name = "shortened mushrooms" + var/harvested_desc = "Some quickly regrowing mushrooms, formerly known to be quite large." + var/needs_sharp_harvest = TRUE + var/harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings + var/harvest_amount_low = 1 + var/harvest_amount_high = 3 + var/harvest_time = 60 + var/harvest_message_low = "You pick a mushroom, but fail to collect many shavings from its cap." + var/harvest_message_med = "You pick a mushroom, carefully collecting the shavings from its cap." + var/harvest_message_high = "You harvest and collect shavings from several mushroom caps." + var/harvested = FALSE + var/base_icon + var/regrowth_time_low = 4800 + var/regrowth_time_high = 8400 + +/obj/structure/flora/ash/New() + ..() + base_icon = "[icon_state][rand(1, 4)]" + icon_state = base_icon + if(prob(15)) + harvest(null, TRUE) + +/obj/structure/flora/ash/proc/harvest(user, no_drop) + if(harvested) + return 0 + if(!no_drop) + var/rand_harvested = rand(harvest_amount_low, harvest_amount_high) + if(rand_harvested) + if(user) + var/msg = harvest_message_med + if(rand_harvested == harvest_amount_low) + msg = harvest_message_low + else if(rand_harvested == harvest_amount_high) + msg = harvest_message_high + to_chat(user, "[msg]") + for(var/i in 1 to rand_harvested) + new harvest(get_turf(src)) + icon_state = "[base_icon]p" + name = harvested_name + desc = harvested_desc + harvested = TRUE + addtimer(src, "regrow", rand(regrowth_time_low, regrowth_time_high)) + return 1 + +/obj/structure/flora/ash/proc/regrow() + icon_state = base_icon + name = initial(name) + desc = initial(desc) + harvested = FALSE + +/obj/structure/flora/ash/attackby(obj/item/weapon/W, mob/user, params) + if(!harvested && needs_sharp_harvest && W.sharp) + user.visible_message("[user] starts to harvest from [src] with [W].","You begin to harvest from [src] with [W].") + if(do_after(user, harvest_time, target = src)) + harvest(user) + else + return ..() + +/obj/structure/flora/ash/attack_hand(mob/user) + if(!harvested && !needs_sharp_harvest) + user.visible_message("[user] starts to harvest from [src].","You begin to harvest from [src].") + if(do_after(user, harvest_time, target = src)) + harvest(user) + else + ..() + +/obj/structure/flora/ash/tall_shroom //exists only so that the spawning check doesn't allow these spawning near other things + regrowth_time_low = 4200 + +/obj/structure/flora/ash/leaf_shroom + icon_state = "s_mushroom" + name = "leafy mushrooms" + desc = "A number of mushrooms, each of which surrounds a greenish sporangium with a number of leaf-like structures." + harvested_name = "leafless mushrooms" + harvested_desc = "A bunch of formerly-leafed mushrooms, with their sporangiums exposed. Scandalous?" + harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf + needs_sharp_harvest = FALSE + harvest_amount_high = 4 + harvest_time = 20 + harvest_message_low = "You pluck a single, suitable leaf." + harvest_message_med = "You pluck a number of leaves, leaving a few unsuitable ones." + harvest_message_high = "You pluck quite a lot of suitable leaves." + regrowth_time_low = 2400 + regrowth_time_high = 6000 + +/obj/structure/flora/ash/cap_shroom + icon_state = "r_mushroom" + name = "tall mushrooms" + desc = "Several mushrooms, the larger of which have a ring of conks at the midpoint of their stems." + harvested_name = "small mushrooms" + harvested_desc = "Several small mushrooms near the stumps of what likely were larger mushrooms." + harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap + harvest_amount_high = 4 + harvest_time = 50 + harvest_message_low = "You slice the cap off of a mushroom." + harvest_message_med = "You slice off a few conks from the larger mushrooms." + harvest_message_high = "You slice off a number of caps and conks from these mushrooms." + regrowth_time_low = 3000 + regrowth_time_high = 5400 + +/obj/structure/flora/ash/stem_shroom + icon_state = "t_mushroom" + name = "numerous mushrooms" + desc = "A large number of mushrooms, some of which have long, fleshy stems. They're radiating light!" + luminosity = 1 + harvested_name = "tiny mushrooms" + harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back." + harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem + harvest_amount_high = 4 + harvest_time = 40 + harvest_message_low = "You pick and slice the cap off of a mushroom, leaving the stem." + harvest_message_med = "You pick and decapitate several mushrooms for their stems." + harvest_message_high = "You acquire a number of stems from these mushrooms." + regrowth_time_low = 3000 + regrowth_time_high = 6000 + +/obj/structure/flora/ash/cacti + icon_state = "cactus" + name = "fruiting cacti" + desc = "Several prickly cacti, brimming with ripe fruit and covered in a thin layer of ash." + harvested_name = "cacti" + harvested_desc = "A bunch of prickly cacti. You can see fruits slowly growing beneath the covering of ash." + harvest = /obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit + needs_sharp_harvest = FALSE + harvest_amount_high = 2 + harvest_time = 10 + harvest_message_low = "You pick a cactus fruit." + harvest_message_med = "You pick several cactus fruit." //shouldn't show up, because you can't get more than two + harvest_message_high = "You pick a pair of cactus fruit." + regrowth_time_low = 4800 + regrowth_time_high = 7200 + +/obj/structure/flora/ash/cacti/Crossed(mob/AM) + if(ishuman(AM) && has_gravity(loc) && prob(70)) + var/mob/living/carbon/human/H = AM + if(!H.shoes && !H.lying) //ouch, my feet. + var/picked_def_zone = pick("l_leg", "r_leg") + var/obj/item/organ/external/affected = H.get_organ(picked_def_zone) + if(!istype(affected)) + return + H.apply_damage(rand(3, 6), BRUTE, picked_def_zone) + H.Weaken(2) + H.visible_message("[H] steps on a cactus!", \ + "You step on a cactus!") + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora + name = "mushroom shavings" + desc = "Some shavings from a tall mushroom. With enough, might serve as a bowl." + icon = 'icons/obj/lavaland/ash_flora.dmi' + icon_state = "mushroom_shavings" + list_reagents = list("sugar" = 3, "ethanol" = 2, "stabilizing_agent" = 3, "minttoxin" = 2) + w_class = 1 + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/New() + ..() + pixel_x = rand(-4, 4) + pixel_y = rand(-4, 4) + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings //for actual crafting + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_leaf + name = "mushroom leaf" + desc = "A leaf, from a mushroom." + list_reagents = list("nutriment" = 3, "vitfro" = 2, "nicotine" = 2) + icon_state = "mushroom_leaf" + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_cap + name = "mushroom cap" + desc = "The cap of a large mushroom." + list_reagents = list("lsd" = 2, "entpoly" = 4, "psilocybin" = 2) + icon_state = "mushroom_cap" + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/mushroom_stem + name = "mushroom stem" + desc = "A long mushroom stem. It's slightly glowing." + list_reagents = list("tinlux" = 2, "vitamin" = 1, "space_drugs" = 1) + icon_state = "mushroom_stem" + luminosity = 1 + +/obj/item/weapon/reagent_containers/food/snacks/ash_flora/cactus_fruit + name = "cactus fruit" + list_reagents = list("vitamin" = 2, "nutriment" = 2, "vitfro" = 4) + desc = "A cactus fruit covered in a thick, reddish skin. And some ash." + icon_state = "cactus_fruit" + +/obj/item/mushroom_bowl + name = "mushroom bowl" + desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point." + icon = 'icons/obj/lavaland/ash_flora.dmi' + icon_state = "mushroom_bowl" + w_class = 2 + +//what you can craft with these things +/datum/crafting_recipe/mushroom_bowl + name = "Mushroom Bowl" + result = /obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl + reqs = list(/obj/item/weapon/reagent_containers/food/snacks/ash_flora/shavings = 5) + time = 30 + category = CAT_PRIMAL diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm new file mode 100644 index 00000000000..4565039d52e --- /dev/null +++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm @@ -0,0 +1,217 @@ +/obj/structure/closet/crate/necropolis/dragon + name = "dragon chest" + +/obj/structure/closet/crate/necropolis/dragon/New() + ..() + var/loot = rand(1,4) + switch(loot) + if(1) + new /obj/item/weapon/melee/ghost_sword(src) + if(2) + new /obj/item/weapon/lava_staff(src) + if(3) + new /obj/item/weapon/spellbook/oneuse/sacredflame(src) + new /obj/item/weapon/gun/magic/wand/fireball(src) + if(4) + new /obj/item/weapon/dragons_blood(src) + +// Spectral Blade + +/obj/item/weapon/melee/ghost_sword + name = "spectral blade" + desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly." + icon_state = "spectral" + item_state = "spectral" + flags = CONDUCT + sharp = 1 + edge = 1 + w_class = 4 + force = 1 + throwforce = 1 + hitsound = 'sound/effects/ghost2.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended") + var/summon_cooldown = 0 + var/list/mob/dead/observer/spirits + +/obj/item/weapon/melee/ghost_sword/New() + ..() + spirits = list() + processing_objects.Add(src) + poi_list |= src + +/obj/item/weapon/melee/ghost_sword/Destroy() + for(var/mob/dead/observer/G in spirits) + G.invisibility = initial(G.invisibility) + spirits.Cut() + processing_objects.Remove(src) + poi_list -= src + . = ..() + +/obj/item/weapon/melee/ghost_sword/attack_self(mob/user) + if(summon_cooldown > world.time) + to_chat(user, "You just recently called out for aid. You don't want to annoy the spirits.") + return + to_chat(user, "You call out for aid, attempting to summon spirits to your side.") + + notify_ghosts("[user] is raising their [src], calling for your help!", enter_link="(Click to help)", source = user, action = NOTIFY_FOLLOW) + + summon_cooldown = world.time + 600 + +/obj/item/weapon/melee/ghost_sword/Topic(href, href_list) + if(href_list["follow"]) + var/mob/dead/observer/ghost = usr + if(istype(ghost)) + ghost.ManualFollow(src) + +/obj/item/weapon/melee/ghost_sword/process() + ghost_check() + +/obj/item/weapon/melee/ghost_sword/proc/ghost_check() + var/ghost_counter = 0 + var/turf/T = get_turf(src) + var/list/contents = T.GetAllContents() + var/mob/dead/observer/current_spirits = list() + + for(var/mob/dead/observer/O in player_list) + if(is_type_in_list(O.following, contents)) + ghost_counter++ + O.invisibility = 0 + current_spirits |= O + + for(var/mob/dead/observer/G in spirits - current_spirits) + G.invisibility = initial(G.invisibility) + + spirits = current_spirits + + return ghost_counter + +/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user) + force = 0 + var/ghost_counter = ghost_check() + + force = Clamp((ghost_counter * 4), 0, 75) + user.visible_message("[user] strikes with the force of [ghost_counter] vengeful spirits!") + ..() + +/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + var/ghost_counter = ghost_check() + final_block_chance += Clamp((ghost_counter * 5), 0, 75) + owner.visible_message("[owner] is protected by a ring of [ghost_counter] ghosts!") + return ..() + +// Blood + +/obj/item/weapon/dragons_blood + name = "bottle of dragons blood" + desc = "You're not actually going to drink this, are you?" + icon = 'icons/obj/wizard.dmi' + icon_state = "vial" + +/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user) + if(!istype(user)) + return + + var/mob/living/carbon/human/H = user + var/random = rand(1,3) + + switch(random) + if(1) + to_chat(user, "Your flesh begins to melt! Miraculously, you seem fine otherwise.") + H.set_species("Skeleton") + if(2) + to_chat(user, "Power courses through you! You can now shift your form at will.") + if(user.mind) + var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new + user.mind.AddSpell(D) + if(3) + to_chat(user, "You feel like you could walk straight through lava now.") + H.weather_immunities |= "lava" + + playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1) + qdel(src) + +/datum/disease/transformation/dragon + name = "dragon transformation" + cure_text = "nothing" + cures = list("adminordrazine") + agent = "dragon's blood" + desc = "What do dragons have to do with Space Station 13?" + stage_prob = 20 + severity = BIOHAZARD + visibility_flags = 0 + stage1 = list("Your bones ache.") + stage2 = list("Your skin feels scaley.") + stage3 = list("You have an overwhelming urge to terrorize some peasants.", "Your teeth feel sharper.") + stage4 = list("Your blood burns.") + stage5 = list("You're a fucking dragon. However, any previous allegiances you held still apply. It'd be incredibly rude to eat your still human friends for no reason.") + new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser + +//Lava Staff + +/obj/item/weapon/lava_staff + name = "staff of lava" + desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?" + icon_state = "staffofstorms" + item_state = "staffofstorms" + icon = 'icons/obj/guns/magic.dmi' + slot_flags = SLOT_BACK + item_state = "staffofstorms" + w_class = 4 + force = 25 + damtype = BURN + hitsound = 'sound/weapons/sear.ogg' + burn_state = LAVA_PROOF | FIRE_PROOF + unacidable = 1 + var/turf_type = /turf/unsimulated/floor/lava // /turf/simulated/floor/plating/lava/smooth once Lavaland turfs are added + var/transform_string = "lava" + var/reset_turf_type = /turf/simulated/floor/plating/airless/asteroid // /turf/simulated/floor/plating/asteroid/basalt once Lavaland turfs are added + var/reset_string = "basalt" + var/create_cooldown = 100 + var/create_delay = 30 + var/reset_cooldown = 50 + var/timer = 0 + var/banned_turfs + +/obj/item/weapon/lava_staff/New() + . = ..() + banned_turfs = typecacheof(list(/turf/space/transit, /turf/unsimulated)) + +/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + ..() + if(timer > world.time) + return + + if(is_type_in_typecache(target, banned_turfs)) + return + + if(target in view(user.client.view, get_turf(user))) + + var/turf/simulated/T = get_turf(target) + if(!istype(T)) + return + if(!istype(T, turf_type)) + var/obj/effect/overlay/temp/lavastaff/L = new /obj/effect/overlay/temp/lavastaff(T) + L.alpha = 0 + animate(L, alpha = 255, time = create_delay) + user.visible_message("[user] points [src] at [T]!") + timer = world.time + create_delay + 1 + if(do_after(user, create_delay, target = T)) + user.visible_message("[user] turns \the [T] into [transform_string]!") + message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)] (JMP).") + log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).") + T.ChangeTurf(turf_type) + timer = world.time + create_cooldown + qdel(L) + else + timer = world.time + qdel(L) + return + else + user.visible_message("[user] turns \the [T] into [reset_string]!") + T.ChangeTurf(reset_turf_type) + timer = world.time + reset_cooldown + playsound(T,'sound/magic/Fireball.ogg', 200, 1) + +/obj/effect/overlay/temp/lavastaff + icon_state = "lavastaff_warn" + duration = 50 \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/bubblegum_loot.dm b/code/modules/mining/lavaland/loot/bubblegum_loot.dm new file mode 100644 index 00000000000..8ee0ecacd8d --- /dev/null +++ b/code/modules/mining/lavaland/loot/bubblegum_loot.dm @@ -0,0 +1,81 @@ +/obj/structure/closet/crate/necropolis/bubblegum + name = "bubblegum chest" + +/obj/structure/closet/crate/necropolis/bubblegum/New() + ..() + var/loot = rand(1,3) + switch(loot) + if(1) + new /obj/item/mayhem(src) + if(2) + new /obj/item/blood_contract(src) + if(3) + new /obj/item/weapon/gun/magic/staff/spellblade(src) + +// Mayhem + +/obj/item/mayhem + name = "mayhem in a bottle" + desc = "A magically infused bottle of blood, the scent of which will drive anyone nearby into a murderous frenzy." + icon = 'icons/obj/wizard.dmi' + icon_state = "vial" + +/obj/item/mayhem/attack_self(mob/user) + for(var/mob/living/carbon/human/H in range(7,user)) + spawn() + var/obj/effect/mine/pickup/bloodbath/B = new(H) + B.mineEffect(H) + to_chat(user, "You shatter the bottle!") + playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) + qdel(src) + +// Blood Contract + +/obj/item/blood_contract + name = "blood contract" + icon = 'icons/obj/wizard.dmi' + icon_state = "scroll2" + color = "#FF0000" + desc = "Mark your target for death." + var/used = FALSE + +/obj/item/blood_contract/attack_self(mob/user) + if(used) + return + + used = TRUE + var/choice = input(user,"Who do you want dead?","Choose Your Victim") as null|anything in player_list + + if(!choice) + used = FALSE + return + else if(!isliving(choice)) + to_chat(user, "[choice] is already dead!") + used = FALSE + return + else if(choice == user) + to_chat(user, "You feel like writing your own name into a cursed death warrant would be unwise.") + used = FALSE + return + else + var/mob/living/L = choice + + message_admins("[key_name_admin(L)] has been marked for death by [key_name_admin(user)].") + log_admin("[key_name(L)] has been marked for death by [key_name(user)].") + + var/datum/objective/survive/survive = new + survive.owner = L.mind + L.mind.objectives += survive + to_chat(L, "You've been marked for death! Don't let the demons get you!") + L.color = "#FF0000" + spawn() + var/obj/effect/mine/pickup/bloodbath/B = new(L) + B.mineEffect(L) + + for(var/mob/living/carbon/human/H in player_list) + if(H == L) + continue + to_chat(H, "You have an overwhelming desire to kill [L]. They have been marked red! Go kill them!") + H.put_in_hands(new /obj/item/weapon/kitchen/knife/butcher(H)) + + qdel(src) \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm new file mode 100644 index 00000000000..fc950b429d2 --- /dev/null +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -0,0 +1,495 @@ +//Black Box + +/obj/machinery/smartfridge/black_box + name = "black box" + desc = "A completely indestructible chunk of crystal, rumoured to predate the start of this universe. It looks like you could store things inside it." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "blackbox" + icon_on = "blackbox" + icon_off = "blackbox" + luminosity = 8 + max_n_of_items = INFINITY + unacidable = 1 + burn_state = LAVA_PROOF | FIRE_PROOF + pixel_y = -4 + use_power = 0 + var/memory_saved = FALSE + var/list/stored_items = list() + var/static/list/blacklist = typecacheof(list(/obj/item/weapon/spellbook)) + +/obj/machinery/smartfridge/black_box/update_icon() + return + +/obj/machinery/smartfridge/black_box/accept_check(obj/item/O) + if(!istype(O)) + return FALSE + if(is_type_in_typecache(O, blacklist)) + return FALSE + return TRUE + +/obj/machinery/smartfridge/black_box/New() + var/static/obj/machinery/smartfridge/black_box/current + if(current && current != src) + qdel(src, force=TRUE) + return + current = src + ReadMemory() + . = ..() + +/obj/machinery/smartfridge/black_box/process() + ..() + if(!memory_saved && ticker.current_state == GAME_STATE_FINISHED) + WriteMemory() + +/obj/machinery/smartfridge/black_box/proc/WriteMemory() + var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav") + stored_items = list() + + for(var/obj/O in (contents-component_parts)) + stored_items += O.type + + S["stored_items"] << stored_items + memory_saved = TRUE + +/obj/machinery/smartfridge/black_box/proc/ReadMemory() + var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav") + S["stored_items"] >> stored_items + + if(isnull(stored_items)) + stored_items = list() + + for(var/item in stored_items) + create_item(item) + +//in it's own proc to avoid issues with items that nolonger exist in the code base. +//try catch doesn't always prevent byond runtimes from halting a proc, +/obj/machinery/smartfridge/black_box/proc/create_item(item_type) + new item_type(src) + +/obj/machinery/smartfridge/black_box/Destroy(force = FALSE) + if(force) + for(var/thing in src) + qdel(thing) + return ..() + else + return QDEL_HINT_LETMELIVE + + +//No taking it apart + +/obj/machinery/smartfridge/black_box/default_deconstruction_screwdriver() + return + +/obj/machinery/smartfridge/black_box/exchange_parts() + return + +/obj/machinery/smartfridge/black_box/default_unfasten_wrench() + return + +/obj/machinery/smartfridge/black_box/default_deconstruction_crowbar() + return + +///Anomolous Crystal/// + +/obj/machinery/anomalous_crystal + name = "anomalous crystal" + desc = "A strange chunk of crystal, being in the presence of it fills you with equal parts excitement and dread." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "anomaly_crystal" + luminosity = 8 + use_power = 0 + density = 1 + burn_state = LAVA_PROOF | FIRE_PROOF + unacidable = 1 + var/activation_method = "touch" + var/activation_damage_type = null + var/last_use_timer = 0 + var/cooldown_add = 30 + var/list/affected_targets = list() + var/activation_sound = 'sound/effects/break_stone.ogg' + +/obj/machinery/anomalous_crystal/New() + activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","weapon","speech") // "heat" removed due to lack of is_hot() + ..() + +/obj/machinery/anomalous_crystal/hear_talk(mob/speaker, message) + ..() + if(isliving(speaker) && message) + ActivationReaction(speaker, "speech") + +/obj/machinery/anomalous_crystal/attack_hand(mob/user) + ..() + ActivationReaction(user,"touch") + +/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params) + ActivationReaction(user,"weapon") + ..() + +/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone) + ..() + if(istype(P, /obj/item/projectile/magic)) + ActivationReaction(P.firer, "magic", P.damage_type) + return + ActivationReaction(P.firer, P.flag, P.damage_type) + +/obj/machinery/anomalous_crystal/proc/ActivationReaction(mob/user, method, damtype) + if(world.time < last_use_timer) + return 0 + if(activation_damage_type && activation_damage_type != damtype) + return 0 + if(method != activation_method) + return 0 + last_use_timer = (world.time + cooldown_add) + playsound(user, activation_sound, 100, 1) + return 1 + +/obj/machinery/anomalous_crystal/Bumped(atom/AM as mob|obj) + ..() + if(ismob(AM)) + ActivationReaction(AM,"mob_bump") + +/obj/machinery/anomalous_crystal/ex_act() + ActivationReaction(null,"bomb") + +/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot + var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random - /obj/machinery/anomalous_crystal) + new random_crystal(loc) + qdel(src) + +/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing + activation_method = "mob_bump" + activation_sound = 'sound/items/bikehorn.ogg' + +/obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user) + if(..() && ishuman(user) && !(user in affected_targets)) + var/mob/living/carbon/human/H = user + for(var/obj/item/W in H) + H.unEquip(W) + var/datum/job/clown/C = job_master.GetJob("Clown") + C.equip(H) + affected_targets.Add(H) + +/obj/machinery/anomalous_crystal/honk/New() + ..() + activation_method = pick("mob_bump","speech") + +/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one + activation_method = "touch" + cooldown_add = 200 + var/terrain_theme = "winter" + var/NewTerrainFloors + var/NewTerrainWalls + var/NewTerrainChairs + var/NewTerrainTables + var/list/NewFlora = list() + var/florachance = 8 + +/obj/machinery/anomalous_crystal/theme_warp/New() + ..() + terrain_theme = pick("lavaland","winter","jungle","alien") + switch(terrain_theme) + if("lavaland")//Depressurizes the place... and free cult metal, I guess. + NewTerrainFloors = /turf/simulated/floor/basalt // Needs to be updated after turf update + NewTerrainWalls = /turf/simulated/wall/cult + NewFlora = list(/mob/living/simple_animal/hostile/asteroid/goldgrub) + florachance = 1 + if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway. + NewTerrainFloors = /turf/simulated/floor/snow // Needs to be updated after turf update + NewTerrainWalls = /turf/simulated/wall/mineral/wood + NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal + NewTerrainTables = /obj/structure/table/glass + NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both) + if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys and bows and arrows. + NewTerrainFloors = /turf/simulated/floor/grass + NewTerrainWalls = /turf/simulated/wall/mineral/sandstone + NewTerrainChairs = /obj/structure/stool/bed/chair/wood/normal + NewTerrainTables = /obj/structure/table/woodentable + NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush, + /obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/human/monkey, + /obj/item/weapon/gun/projectile/bow, /obj/item/weapon/storage/backpack/quiver/full) + florachance = 20 + if("alien") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos. + NewTerrainFloors = /turf/simulated/floor/mineral/abductor + NewTerrainWalls = /turf/simulated/wall/mineral/abductor + NewTerrainChairs = /obj/structure/stool/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline. + NewTerrainTables = /obj/structure/table/abductor + +/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method) + if(..()) + var/area/A = get_area(src) + if(!A.outdoors && !(A in affected_targets)) + for(var/atom/Stuff in A) + if(isturf(Stuff)) + var/turf/T = Stuff + if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors) + var/turf/simulated/O = T.ChangeTurf(NewTerrainFloors) + if(O.air) + var/datum/gas_mixture/G = O.air + G.copy_from(O.air) + if(prob(florachance) && NewFlora.len && !is_blocked_turf(O)) + var/atom/Picked = pick(NewFlora) + new Picked(O) + continue + if(iswallturf(T) && NewTerrainWalls) + T.ChangeTurf(NewTerrainWalls) + continue + if(istype(Stuff, /obj/structure/stool/bed/chair) && NewTerrainChairs) + var/obj/structure/stool/bed/chair/Original = Stuff + var/obj/structure/stool/bed/chair/C = new NewTerrainChairs(Original.loc) + C.dir = Original.dir + qdel(Stuff) + continue + if(istype(Stuff, /obj/structure/table) && NewTerrainTables) + var/obj/structure/table/Original = Stuff + var/obj/structure/table/T = new NewTerrainTables(Original.loc) + T.dir = Original.dir + qdel(Stuff) + continue + affected_targets += A + +/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with + activation_method = "touch" + cooldown_add = 50 + var/generated_projectile = /obj/item/projectile/beam/emitter + +/obj/machinery/anomalous_crystal/emitter/New() + ..() + generated_projectile = pick(/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade, + /obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray, /obj/item/projectile/colossus) + +/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method) + if(..()) + var/obj/item/projectile/P = new generated_projectile(get_turf(src)) + P.dir = dir + switch(dir) + if(NORTH) + P.yo = 20 + P.xo = 0 + if(EAST) + P.yo = 0 + P.xo = 20 + if(WEST) + P.yo = 0 + P.xo = -20 + else + P.yo = -20 + P.xo = 0 + P.fire() + +/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople and renders them uncloneable, so the crystal is your only hope of getting up again if you go down. + activation_method = "touch" + activation_sound = 'sound/hallucinations/growl1.ogg' + +/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method) + if(..()) + for(var/i in range(1, src)) + if(isturf(i)) + new /obj/effect/overlay/temp/cult/sparks(i) + continue + if(ishuman(i)) + var/mob/living/carbon/human/H = i + if(H.stat == DEAD) + H.set_species("Shadow") + H.revive() + H.disabilities |= NOCLONE //Free revives, but significantly limits your options for reviving except via the crystal + H.grab_ghost(force = TRUE) + +/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans + activation_method = "touch" + var/ready_to_deploy = 0 + +/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method) + if(..() && !ready_to_deploy) + ready_to_deploy = 1 + notify_ghosts("An anomalous crystal has been activated in [get_area(src)]! This crystal can always be used by ghosts hereafter.", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK) + +/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user) + ..() + if(ready_to_deploy) + var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No") + if(be_helper == "No") + return + var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc)) + W.key = user.key + +/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list) + if(href_list["ghostjoin"]) + var/mob/dead/observer/ghost = usr + if(istype(ghost)) + attack_ghost(ghost) + +/mob/living/simple_animal/hostile/lightgeist + name = "lightgeist" + desc = "This small floating creature is a completely unknown form of life... being near it fills you with a sense of tranquility." + icon_state = "lightgeist" + icon_living = "lightgeist" + icon_dead = "butterfly_dead" + turns_per_move = 1 + response_help = "waves away" + response_disarm = "brushes aside" + response_harm = "disrupts" + speak_emote = list("oscillates") + maxHealth = 2 + health = 2 + harm_intent_damage = 1 + friendly = "mends" + density = 0 + flying = 1 + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + ventcrawler = 2 + mob_size = MOB_SIZE_TINY + gold_core_spawnable = 0 + speak_emote = list("warps") + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) + luminosity = 4 + faction = list("neutral") + universal_understand = 1 + del_on_death = 1 + unsuitable_atmos_damage = 0 + flying = 1 + minbodytemp = 0 + maxbodytemp = 1500 + environment_smash = 0 + AIStatus = AI_OFF + stop_automated_movement = 1 + var/heal_power = 5 + +/mob/living/simple_animal/hostile/lightgeist/New() + ..() + verbs -= /mob/living/verb/pulled + verbs -= /mob/verb/me_verb + var/datum/atom_hud/medsensor = huds[DATA_HUD_MEDICAL_ADVANCED] + medsensor.add_hud_to(src) + +/mob/living/simple_animal/hostile/lightgeist/AttackingTarget() + ..() + if(isliving(target) && target != src) + var/mob/living/L = target + if(L.stat < DEAD) + L.heal_overall_damage(heal_power, heal_power) + new /obj/effect/overlay/temp/heal(get_turf(target), "#80F5FF") + +/mob/living/simple_animal/hostile/lightgeist/ghostize() + if(..()) + death() + +/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it. + activation_method = "touch" + cooldown_add = 50 + activation_sound = 'sound/magic/TIMEPARADOX2.ogg' + var/list/banned_items_typecache = list(/obj/item/weapon/storage, /obj/item/weapon/implant, /obj/item/weapon/implanter, /obj/item/weapon/disk/nuclear, /obj/item/projectile, /obj/item/weapon/spellbook) + +/obj/machinery/anomalous_crystal/refresher/New() + ..() + banned_items_typecache = typecacheof(banned_items_typecache) + + +/obj/machinery/anomalous_crystal/refresher/ActivationReaction(mob/user, method) + if(..()) + var/list/L = list() + var/turf/T = get_step(src, dir) + new /obj/effect/overlay/temp/emp/pulse(T) + for(var/i in T) + if(istype(i, /obj/item) && !is_type_in_typecache(i, banned_items_typecache)) + var/obj/item/W = i + if(!W.admin_spawned) + L += W + if(L.len) + var/obj/item/CHOSEN = pick(L) + new CHOSEN.type(T) + qdel(CHOSEN) + +/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU. + activation_method = "touch" + +/obj/machinery/anomalous_crystal/possessor/ActivationReaction(mob/user, method) + if(..()) + if(ishuman(user)) + var/mobcheck = 0 + for(var/mob/living/simple_animal/A in range(1, src)) + if(A.melee_damage_upper > 5 || A.mob_size >= MOB_SIZE_LARGE || A.ckey || A.stat) + break + var/obj/structure/closet/stasis/S = new /obj/structure/closet/stasis(A) + user.forceMove(S) + mobcheck = 1 + break + if(!mobcheck) + new /mob/living/simple_animal/cockroach(get_step(src,dir)) //Just in case there aren't any animals on the station, this will leave you with a terrible option to possess if you feel like it + +/obj/structure/closet/stasis + name = "quantum entanglement stasis warp field" + desc = "You can hardly comprehend this thing... which is why you can't see it." + icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice + density = 1 + anchored = 1 + var/mob/living/simple_animal/holder_animal + +/obj/structure/closet/stasis/process() + if(holder_animal) + if(holder_animal.stat == DEAD && !qdeleted(holder_animal)) + dump_contents() + holder_animal.gib() + return + +/obj/structure/closet/stasis/New() + ..() + if(isanimal(loc)) + holder_animal = loc + processing_objects.Add(src) + +/obj/structure/closet/stasis/Entered(atom/A) + if(isliving(A) && holder_animal) + var/mob/living/L = A + L.notransform = 1 + L.disabilities |= MUTE + L.status_flags |= GODMODE + L.mind.transfer_to(holder_animal) + var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession + holder_animal.mind.AddSpell(P) + holder_animal.verbs -= /mob/living/verb/pulled + +/obj/structure/closet/stasis/dump_contents(var/kill = 1) + processing_objects.Remove(src) + for(var/mob/living/L in src) + L.disabilities &= ~MUTE + L.status_flags &= ~GODMODE + L.notransform = 0 + if(holder_animal && !qdeleted(holder_animal)) + holder_animal.mind.transfer_to(L) + L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession) + if(kill || !isanimal(loc)) + L.death(0) + ..() + +/obj/structure/closet/stasis/emp_act() + return + +/obj/structure/closet/stasis/ex_act() + return + +/obj/effect/proc_holder/spell/targeted/exit_possession + name = "Exit Possession" + desc = "Exits the body you are possessing" + charge_max = 60 + clothes_req = 0 + invocation_type = "none" + max_targets = 1 + range = -1 + include_user = 1 + selection_type = "view" + action_icon_state = "exit_possession" + sound = null + +/obj/effect/proc_holder/spell/targeted/exit_possession/cast(list/targets, mob/user = usr) + if(!isfloorturf(user.loc)) + return + var/datum/mind/target_mind = user.mind + var/mob/living/current = user // Saving the current mob here to gib as usr seems to get confused after the mind's been transferred, due to delay in transfer_to + for(var/i in user) + if(istype(i, /obj/structure/closet/stasis)) + var/obj/structure/closet/stasis/S = i + S.dump_contents(0) + qdel(S) + break + current.gib() + target_mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession) diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm new file mode 100644 index 00000000000..f06fd25d428 --- /dev/null +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -0,0 +1,188 @@ +/obj/item/weapon/hierophant_staff + name = "Hierophant's staff" + desc = "A large club with intense magic power infused into it." + icon_state = "hierophant_staff" + item_state = "hierophant_staff" + icon = 'icons/obj/guns/magic.dmi' + slot_flags = SLOT_BACK + w_class = 4 + force = 20 + hitsound = "swing_hit" + //hitsound = 'sound/weapons/sonic_jackhammer.ogg' + actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire) + var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is + var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is + var/chaser_timer = 0 //what our current chaser cooldown is + var/timer = 0 //what our current cooldown is + var/blast_range = 3 //how long the cardinal blast's walls are + var/obj/effect/hierophant/rune //the associated rune we teleport to + var/teleporting = FALSE //if we ARE teleporting + var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets + +/obj/item/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + ..() + var/turf/T = get_turf(target) + if(!T || timer > world.time) + return + timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown + if(proximity_flag) + spawn(0) + aoe_burst(T, user) + add_logs(user, target, "fired 3x3 blast at", src) + else + if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it) + spawn(0) + cardinal_blasts(T, user) + timer = world.time + cooldown_time + else if(target in view(5, get_turf(user))) //if the target is in view, hit it + timer = world.time + cooldown_time + if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one! + chaser_timer = world.time + chaser_cooldown + new /obj/effect/overlay/temp/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check) + add_logs(user, target, "fired a chaser at", src) + else + spawn(0) + cardinal_blasts(T, user) //otherwise, just do cardinal blast + add_logs(user, target, "fired cardinal blast at", src) + else + to_chat(user, "That target is out of range!") //too far away + +/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype) + if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire... + friendly_fire_check = !friendly_fire_check + to_chat(user, "You toggle friendly fire [friendly_fire_check ? "off":"on"]!") + return + if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport + to_chat(user, "You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!") + return + if(!rune) + if(isturf(user.loc)) + user.visible_message("[user] holds [src] carefully in front of them, moving it in a strange pattern...", \ + "You start creating a hierophant rune to teleport to...") + timer = world.time + 51 + if(do_after(user, 50, target = user)) + var/turf/T = get_turf(user) + playsound(T,'sound/magic/Blind.ogg', 200, 1, -4) + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user) + var/obj/effect/hierophant/H = new/obj/effect/hierophant(T) + rune = H + user.update_action_buttons_icon() + user.visible_message("[user] creates a strange rune beneath them!", \ + "You create a hierophant rune, which you can teleport yourself and any allies to at any time!\n\ + You can remove the rune to place a new one by striking it with the staff.") + else + timer = world.time + else + to_chat(user, "You need to be on solid ground to produce a rune!") + return + if(get_dist(user, rune) <= 2) //rune too close abort + to_chat(user, "You are too close to the rune to teleport to it!") + return + if(is_blocked_turf(get_turf(rune))) + to_chat(user, "The rune is blocked by something, preventing teleportation!") + return + teleporting = TRUE //start channel + user.update_action_buttons_icon() + user.visible_message("[user] starts to glow faintly...") + timer = world.time + 50 + if(do_after(user, 40, target = user) && rune) + var/turf/T = get_turf(rune) + var/turf/source = get_turf(user) + if(is_blocked_turf(T)) + teleporting = FALSE + to_chat(user, "The rune is blocked by something, preventing teleportation!") + user.update_action_buttons_icon() + return + new /obj/effect/overlay/temp/hierophant/telegraph(T, user) + new /obj/effect/overlay/temp/hierophant/telegraph(source, user) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1) + playsound(source,'sound/magic/blink.ogg', 200, 1) + //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1) + if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord + teleporting = FALSE + if(user) + user.update_action_buttons_icon() + return + if(is_blocked_turf(T)) + teleporting = FALSE + to_chat(user, "The rune is blocked by something, preventing teleportation!") + user.update_action_buttons_icon() + return + add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to") + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user) + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(source, user) + for(var/t in RANGE_TURFS(1, T)) + var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //blasts produced will not hurt allies + B.damage = 30 + for(var/t in RANGE_TURFS(1, source)) + var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies + B.damage = 30 + for(var/mob/living/L in range(1, source)) + spawn(0) + teleport_mob(source, L, T, user) //regardless, take all mobs near us along + sleep(6) //at this point the blasts detonate + else + timer = world.time + teleporting = FALSE + if(user) + user.update_action_buttons_icon() + +/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user) + var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster + if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to)) + return + animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out + sleep(1) + if(!M) + return + M.visible_message("[M] fades out!") + sleep(2) + if(!M) + return + M.forceMove(turf_to_teleport_to) + sleep(1) + if(!M) + return + animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN + sleep(1) + if(!M) + return + M.visible_message("[M] fades in!") + if(user != M) + add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])") + +/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph/cardinal(T, user) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + new /obj/effect/overlay/temp/hierophant/blast(T, user, friendly_fire_check) + for(var/d in cardinal) + spawn(0) + blast_wall(T, d, user) + +/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long + if(!T) + return + var/range = blast_range + var/turf/previousturf = T + var/turf/J = get_step(previousturf, dir) + for(var/i in 1 to range) + if(!J) + return + new /obj/effect/overlay/temp/hierophant/blast(J, user, friendly_fire_check) + previousturf = J + J = get_step(previousturf, dir) + +/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph(T, user) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + for(var/t in RANGE_TURFS(1, T)) + new /obj/effect/overlay/temp/hierophant/blast(t, user, friendly_fire_check) \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/legion_loot.dm b/code/modules/mining/lavaland/loot/legion_loot.dm new file mode 100644 index 00000000000..49e64f3349e --- /dev/null +++ b/code/modules/mining/lavaland/loot/legion_loot.dm @@ -0,0 +1,52 @@ +/obj/item/weapon/staff/storm + name = "staff of storms" + desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it." + icon_state = "staffofstorms" + item_state = "staffofstorms" + icon = 'icons/obj/guns/magic.dmi' + slot_flags = SLOT_BACK + item_state = "staffofstorms" + w_class = 4 + force = 25 + damtype = BURN + hitsound = 'sound/weapons/sear.ogg' + var/storm_type = /datum/weather/ash_storm + var/storm_cooldown = 0 + +/obj/item/weapon/staff/storm/attack_self(mob/user) + if(storm_cooldown > world.time) + to_chat(user, "The staff is still recharging!") + return + + var/area/user_area = get_area(user) + var/datum/weather/A + var/z_level_name = space_manager.levels_by_name[user.z] + for(var/V in weather_master.existing_weather) + var/datum/weather/W = V + if(W.target_z == z_level_name && W.area_type == user_area.type) + A = W + break + if(A) + + if(A.stage != END_STAGE) + if(A.stage == WIND_DOWN_STAGE) + to_chat(user, "The storm is already ending! It would be a waste to use the staff now.") + return + user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \ + "You hold [src] skyward, dispelling the storm!") + playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0) + A.wind_down() + return + else + A = new storm_type + A.name = "staff storm" + A.area_type = user_area.type + A.target_z = z_level_name + A.telegraph_duration = 100 + A.end_duration = 100 + + user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \ + "You hold [src] skyward, calling down a terrible storm!") + playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0) + A.telegraph() + storm_cooldown = world.time + 200 \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm new file mode 100644 index 00000000000..ed8b400337a --- /dev/null +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -0,0 +1,394 @@ +//Shared Bag + +//Internal +/obj/item/weapon/storage/backpack/shared + name = "paradox bag" + desc = "Somehow, it's in two places at once." + max_combined_w_class = 60 + max_w_class = 3 + +//External +/obj/item/device/shared_storage + name = "paradox bag" + desc = "Somehow, it's in two places at once." + icon = 'icons/obj/storage.dmi' + icon_state = "cultpack" + slot_flags = SLOT_BACK + var/obj/item/weapon/storage/backpack/shared/bag + +/obj/item/device/shared_storage/red + name = "paradox bag" + desc = "Somehow, it's in two places at once." + +/obj/item/device/shared_storage/red/New() + ..() + if(!bag) + var/obj/item/weapon/storage/backpack/shared/S = new(src) + var/obj/item/device/shared_storage/blue = new(loc) + + bag = S + blue.bag = S + +/obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params) + if(bag) + bag.loc = user + bag.attackby(W, user, params) + +/obj/item/device/shared_storage/attack_self(mob/living/carbon/user) + if(!iscarbon(user)) + return + if(src == user.l_hand || src == user.r_hand) + if(bag) + bag.loc = user + bag.attack_hand(user) + else + ..() + +/obj/item/device/shared_storage/attack_hand(mob/living/carbon/user) + if(!iscarbon(user)) + return + if(loc == user && user.back && user.back == src) + if(bag) + bag.loc = user + bag.attack_hand(user) + else + ..() + +/obj/item/device/shared_storage/MouseDrop(atom/over_object) + if(iscarbon(usr)) + var/mob/M = usr + + if(!over_object) + return + + if(istype(M.loc, /obj/mecha)) + return + + if(!M.restrained() && !M.stat) + playsound(loc, "rustle", 50, 1, -5) + + if(istype(over_object, /obj/screen/inventory/hand)) + if(!M.unEquip(src)) + return + M.put_in_active_hand(src) + else if(bag) + bag.loc = usr + bag.attack_hand(usr) + + add_fingerprint(M) + +//Potion of Flight: as we do not have the "Angel" species this currently does not work. + +/obj/item/weapon/reagent_containers/glass/bottle/potion + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "potionflask" + +/obj/item/weapon/reagent_containers/glass/bottle/potion/flight + name = "strange elixir" + desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'." + list_reagents = list("flightpotion" = 5) + +/obj/item/weapon/reagent_containers/glass/bottle/potion/update_icon() + if(reagents.total_volume) + icon_state = "potionflask" + else + icon_state = "potionflask_empty" + +/datum/reagent/flightpotion + name = "Flight Potion" + id = "flightpotion" + description = "Strange mutagenic compound of unknown origins." + reagent_state = LIQUID + color = "#FFEBEB" + +/datum/reagent/flightpotion/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1) + to_chat(M, "This item is currently non-functional.") + /*if(ishuman(M) && M.stat != DEAD) + var/mob/living/carbon/human/H = M + if(H.species.name != "Human" || reac_volume < 5) // implying xenohumans are holy + if(method == INGEST && show_message) + to_chat(H, "You feel nothing but a terrible aftertaste.") + return ..() + + to_chat(H, "A terrible pain travels down your back as wings burst out!") + H.set_species("Angel") + playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1, -1) + H.adjustBruteLoss(20) + H.emote("scream") + ..()*/ + +//Boat + +/obj/vehicle/lavaboat + name = "lava boat" + desc = "A boat used for traversing lava." + icon_state = "goliath_boat" + icon = 'icons/obj/lavaland/dragonboat.dmi' + keytype = /obj/item/weapon/oar + burn_state = LAVA_PROOF | FIRE_PROOF + +/obj/vehicle/lavaboat/relaymove(mob/user, direction) + var/turf/next = get_step(src, direction) + var/turf/current = get_turf(src) + + if(istype(next, /turf/unsimulated/floor/lava) || istype(current, /turf/unsimulated/floor/lava)) //We can move from land to lava, or lava to land, but not from land to land + ..() + else + to_chat(user, "Boats don't go on land!") + return 0 + +/obj/item/weapon/oar + name = "oar" + icon = 'icons/obj/vehicles.dmi' + icon_state = "oar" + item_state = "rods" + desc = "Not to be confused with the kind Research hassles you for." + force = 12 + w_class = 3 + burn_state = LAVA_PROOF | FIRE_PROOF + +/datum/crafting_recipe/oar + name = "goliath bone oar" + result = /obj/item/weapon/oar + reqs = list(/obj/item/stack/sheet/bone = 2) + time = 15 + category = CAT_PRIMAL + +/datum/crafting_recipe/boat + name = "goliath hide boat" + result = /obj/vehicle/lavaboat + reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3) + time = 50 + category = CAT_PRIMAL + +//Dragon Boat + +/obj/item/ship_in_a_bottle + name = "ship in a bottle" + desc = "A tiny ship inside a bottle." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "ship_bottle" + +/obj/item/ship_in_a_bottle/attack_self(mob/user) + to_chat(user, "You're not sure how they get the ships in these things, but you're pretty sure you know how to get it out.") + playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) + new /obj/vehicle/lavaboat/dragon(get_turf(src)) + qdel(src) + +/obj/vehicle/lavaboat/dragon + name = "mysterious boat" + desc = "This boat moves where you will it, without the need for an oar." + keytype = null + icon_state = "dragon_boat" + generic_pixel_y = 2 + generic_pixel_x = 1 + vehicle_move_delay = 1 + +// Wisp Lantern +/obj/item/device/wisp_lantern + name = "spooky lantern" + desc = "This lantern gives off no light, but is home to a friendly wisp." + icon = 'icons/obj/lighting.dmi' + icon_state = "lantern-blue" + var/obj/effect/wisp/wisp + +/obj/item/device/wisp_lantern/attack_self(mob/user) + if(!wisp) + to_chat(user, "The wisp has gone missing!") + return + if(wisp.loc == src) + to_chat(user, "You release the wisp. It begins to bob around your head.") + user.sight |= SEE_MOBS + icon_state = "lantern" + wisp.orbit(user, 20, forceMove = TRUE) + feedback_add_details("wisp_lantern","F") // freed + + else + to_chat(user, "You return the wisp to the lantern.") + + if(wisp.orbiting) + var/atom/A = wisp.orbiting + if(isliving(A)) + var/mob/living/M = A + M.sight &= ~SEE_MOBS + to_chat(M, "Your vision returns to normal.") + + wisp.stop_orbit() + wisp.loc = src + icon_state = "lantern-blue" + feedback_add_details("wisp_lantern","R") // returned + +/obj/item/device/wisp_lantern/New() + ..() + wisp = new(src) + +/obj/item/device/wisp_lantern/Destroy() + if(wisp) + if(wisp.loc == src) + qdel(wisp) + else + wisp.visible_message("[wisp] has a sad feeling for a moment, then it passes.") + return ..() + +/obj/effect/wisp + name = "friendly wisp" + desc = "Happy to light your way." + icon = 'icons/obj/lighting.dmi' + icon_state = "orb" + layer = ABOVE_ALL_MOB_LAYER + light_power = 1 + light_range = 7 + +//Red/Blue Cubes + +/obj/item/device/warp_cube + name = "blue cube" + desc = "A mysterious blue cube." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "blue_cube" + var/obj/item/device/warp_cube/linked + +/obj/item/device/warp_cube/Destroy() + if(linked) + linked.linked = null + linked = null + return ..() + +/obj/item/device/warp_cube/attack_self(mob/user) + if(!linked) + to_chat(user, "[src] fizzles uselessly.") + return + + var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread() + smoke.set_up(1, 0, user.loc) + smoke.start() + + user.forceMove(get_turf(linked)) + feedback_add_details("warp_cube","[src.type]") + + var/datum/effect/system/harmless_smoke_spread/smoke2 = new /datum/effect/system/harmless_smoke_spread() + smoke2.set_up(1, 0, user.loc) + smoke2.start() + +/obj/item/device/warp_cube/red + name = "red cube" + desc = "A mysterious red cube." + icon_state = "red_cube" + +/obj/item/device/warp_cube/red/New() + ..() + if(!linked) + var/obj/item/device/warp_cube/blue = new(src.loc) + linked = blue + blue.linked = src + +//Meat Hook + +/obj/item/weapon/gun/magic/hook + name = "meat hook" + desc = "Mid or feed." + ammo_type = /obj/item/ammo_casing/magic/hook + icon_state = "hook" + item_state = "chain" + fire_sound = 'sound/weapons/batonextend.ogg' + max_charges = 1 + flags = NOBLUDGEON + force = 18 + +/obj/item/ammo_casing/magic/hook + name = "hook" + desc = "a hook." + projectile_type = /obj/item/projectile/hook + caliber = "hook" + icon_state = "hook" + +/obj/item/projectile/hook + name = "hook" + icon_state = "hook" + icon = 'icons/obj/lavaland/artefacts.dmi' + pass_flags = PASSTABLE + damage = 25 + armour_penetration = 100 + damage_type = BRUTE + hitsound = 'sound/effects/splat.ogg' + weaken = 3 + var/chain + +/obj/item/projectile/hook/fire(setAngle) + if(firer) + chain = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY) + ..() + //TODO: root the firer until the chain returns + +/obj/item/projectile/hook/on_hit(atom/target) + . = ..() + if(isliving(target)) + var/mob/living/L = target + if(!L.anchored) + L.visible_message("[L] is snagged by [firer]'s hook!") + L.forceMove(get_turf(firer)) + +/obj/item/projectile/hook/Destroy() + qdel(chain) + return ..() + +//Immortality Talisman + +/obj/item/device/immortality_talisman + name = "Immortality Talisman" + desc = "A dread talisman that can render you completely invulnerable." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "talisman" + actions_types = list(/datum/action/item_action/immortality) + var/cooldown = 0 + +/datum/action/item_action/immortality + name = "Immortality" + +/obj/item/device/immortality_talisman/Destroy(force) + if(force) + . = ..() + else + return QDEL_HINT_LETMELIVE + +/obj/item/device/immortality_talisman/attack_self(mob/user) + if(cooldown < world.time) + feedback_add_details("immortality_talisman","U") // usage + cooldown = world.time + 600 + user.visible_message("[user] vanishes from reality, leaving a a hole in their place!") + var/obj/effect/immortality_talisman/Z = new(get_turf(src.loc)) + Z.name = "hole in reality" + Z.desc = "It's shaped an awful lot like [user.name]." + Z.setDir(user.dir) + user.forceMove(Z) + user.notransform = 1 + user.status_flags |= GODMODE + spawn(100) + user.status_flags &= ~GODMODE + user.notransform = 0 + user.forceMove(get_turf(Z)) + user.visible_message("[user] pops back into reality!") + Z.can_destroy = TRUE + qdel(Z) + else + to_chat(user, "[src] is still recharging.") + +/obj/effect/immortality_talisman + icon_state = "blank" + icon = 'icons/effects/effects.dmi' + var/can_destroy = FALSE + +/obj/effect/immortality_talisman/attackby() + return + +/obj/effect/immortality_talisman/ex_act() + return + +/obj/effect/immortality_talisman/singularity_pull() + return 0 + +/obj/effect/immortality_talisman/Destroy(force) + if(!can_destroy && !force) + return QDEL_HINT_LETMELIVE + else + . = ..() \ No newline at end of file diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm new file mode 100644 index 00000000000..3910baf10de --- /dev/null +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -0,0 +1,72 @@ +//The chests dropped by mob spawner tendrils. Also contains associated loot. + +/obj/structure/closet/crate/necropolis + name = "necropolis chest" + desc = "It's watching you closely." + icon_state = "necrocrate" + icon_opened = "necrocrateopen" + icon_closed = "necrocrate" + burn_state = LAVA_PROOF | FIRE_PROOF + unacidable = 1 + +/obj/structure/closet/crate/necropolis/tendril + desc = "It's watching you suspiciously." + +/obj/structure/closet/crate/necropolis/tendril/New() + ..() + var/loot = rand(1,24) + switch(loot) + if(1) + new /obj/item/device/shared_storage/red(src) + if(2) + new /obj/item/clothing/head/helmet/space/cult(src) + new /obj/item/clothing/suit/space/cult(src) + if(3) + new /obj/item/device/soulstone/anybody(src) + if(4) + new /obj/item/weapon/katana/cursed(src) + if(5) + new /obj/item/clothing/glasses/godeye(src) + if(6) + new /obj/item/weapon/pickaxe/diamond(src) + if(7) + new /obj/item/clothing/head/culthood(src) + new /obj/item/clothing/suit/hooded/cultrobes(src) + new /obj/item/weapon/bedsheet/cult(src) + if(8) + new /obj/item/organ/internal/brain/xeno(src) + if(9) + new /obj/item/organ/internal/heart/cursed(src) + if(10) + new /obj/item/ship_in_a_bottle(src) + if(11) + new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/berserker(src) + new /obj/item/clothing/suit/space/rig/ert/paranormal/berserker(src) + if(12) + new /obj/item/weapon/sord(src) + if(13) + new /obj/item/weapon/nullrod/scythe/talking(src) + if(14) + new /obj/item/weapon/nullrod/armblade(src) + if(15) + new /obj/item/weapon/guardiancreator(src) + if(16) + new /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs(src) + if(17) + new /obj/item/device/warp_cube/red(src) + if(18) + new /obj/item/device/wisp_lantern(src) + if(19) + new /obj/item/device/immortality_talisman(src) + if(20) + new /obj/item/weapon/gun/magic/hook(src) + if(21) + new /obj/item/voodoo(src) + if(22) + new /obj/item/weapon/grenade/clusterbuster/inferno(src) + if(23) + new /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/hell(src) + new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/inquisitor(src) + new /obj/item/clothing/suit/space/rig/ert/paranormal/inquisitor(src) + if(24) + new /obj/item/weapon/spellbook/oneuse/summonitem(src) \ No newline at end of file diff --git a/code/modules/mining/mine_areas.dm b/code/modules/mining/mine_areas.dm index 96ef9d3104b..e07d779c9a8 100644 --- a/code/modules/mining/mine_areas.dm +++ b/code/modules/mining/mine_areas.dm @@ -13,6 +13,7 @@ power_environ = 0 power_equip = 0 power_light = 0 + outdoors = 1 ambientsounds = list('sound/ambience/ambimine.ogg') /area/mine/dangerous/unexplored @@ -25,6 +26,7 @@ power_environ = 0 power_equip = 0 power_light = 0 + outdoors = 1 ambientsounds = list('sound/ambience/ambimine.ogg') /area/mine/lobby diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 83e794b9d20..6027a0272d8 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -2,10 +2,12 @@ //this item is intended to give the effect of entering the mine, so that light gradually fades /obj/effect/light_emitter - name = "Light-emtter" + name = "Light emtter" anchored = 1 + invisibility = 101 unacidable = 1 light_range = 8 + light_power = 0 /**********************Miner Lockers**************************/ @@ -89,7 +91,7 @@ var/excavation_amount = 100 /obj/item/weapon/pickaxe/proc/playDigSound() - playsound(src, pick(digsound),20,1) + playsound(src, pick(digsound),20,1) /obj/item/weapon/pickaxe/silver name = "silver-plated pickaxe" diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index ec36988cb20..9e4d268281c 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -62,6 +62,10 @@ points = 1 refined_type = /obj/item/stack/sheet/glass materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) + +/obj/item/weapon/ore/glass/basalt + name = "volcanic ash" + icon_state = "volcanic_sand" /obj/item/weapon/ore/glass/attack_self(mob/living/user as mob) to_chat(user, "You use the sand to make sandstone.") diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 9ff0fed374e..5cf24a394ee 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -10,6 +10,9 @@ pressure_resistance = 5*ONE_ATMOSPHERE /obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/device/t_scanner/adv_mining_scanner)) + attack_hand(user) + return if(istype(W, /obj/item/weapon/ore)) if(!user.drop_item()) return diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index 18a066d03a9..f9cb1123ca3 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -14,10 +14,6 @@ /mob/camera/experience_pressure_difference() return -/mob/camera/Destroy() - ..() - return QDEL_HINT_HARDDEL_NOW - /mob/camera/Login() ..() update_interface() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 9954b8e12b2..db6ef63ad22 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -226,6 +226,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(client.statpanel == "Status") show_stat_station_time() show_stat_emergency_shuttle_eta() + stat(null, "Respawnability: [(src in respawnable_list) ? "Yes" : "No"]") /mob/dead/observer/verb/reenter_corpse() set category = "Ghost" @@ -667,4 +668,4 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp mind.active = 1 mind.transfer_to(new_char) else - new_char.key = key \ No newline at end of file + new_char.key = key diff --git a/code/modules/mob/dead/observer/spells.dm b/code/modules/mob/dead/observer/spells.dm index 39dae4c0746..620c1854e73 100644 --- a/code/modules/mob/dead/observer/spells.dm +++ b/code/modules/mob/dead/observer/spells.dm @@ -25,7 +25,7 @@ var/global/list/boo_phrases=list( invocation_type = "none" range = 1 // Or maybe 3? -/obj/effect/proc_holder/spell/aoe_turf/boo/cast(list/targets) +/obj/effect/proc_holder/spell/aoe_turf/boo/cast(list/targets, mob/user = usr) for(var/turf/T in targets) for(var/atom/A in T.contents) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index be101742dfa..2b495f02062 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -22,7 +22,7 @@ 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) +/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4) if(!syllables || !syllables.len || english_names) if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) @@ -40,7 +40,7 @@ return "[trim(full_name)]" -/datum/language/proc/scramble(var/input) +/datum/language/proc/scramble(input) if(!syllables || !syllables.len) return stars(input) @@ -95,10 +95,11 @@ // if you yell, you'll be heard from two tiles over instead of one return (copytext(message, length(message)) == "!") ? 2 : 1 -/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) +/datum/language/proc/broadcast(mob/living/speaker, message, speaker_mask) log_say("[key_name(speaker)]: ([name]) [message]") - if(!speaker_mask) speaker_mask = speaker.name + if(!speaker_mask) + speaker_mask = speaker.name var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]" for(var/mob/player in player_list) @@ -110,10 +111,10 @@ else if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player, speaker))) to_chat(player, msg) -/datum/language/proc/check_special_condition(var/mob/other, var/mob/living/speaker) - return 1 +/datum/language/proc/check_special_condition(mob/other, mob/living/speaker) + return TRUE -/datum/language/proc/get_spoken_verb(var/msg_end) +/datum/language/proc/get_spoken_verb(msg_end) switch(msg_end) if("!") return exclaim_verb @@ -170,8 +171,7 @@ "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ "hal","ket","jurl","mah","tul","cresh","azu","ragh") -/datum/language/tajaran/get_random_name(var/gender) - +/datum/language/tajaran/get_random_name(gender) var/new_name = ..(gender,1) if(prob(80)) new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" @@ -286,13 +286,13 @@ key = "^" flags = RESTRICTED | HIVEMIND -/datum/language/grey/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) +/datum/language/grey/broadcast(mob/living/speaker, message, speaker_mask) ..(speaker,message,speaker.real_name) -/datum/language/grey/check_special_condition(var/mob/living/carbon/human/other, var/mob/living/carbon/human/speaker) +/datum/language/grey/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker) if(other in range(7, speaker)) - return 1 - return 0 + return TRUE + return FALSE /datum/language/drask name = "Orluum" @@ -322,7 +322,7 @@ 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) +/datum/language/common/get_spoken_verb(msg_end) switch(msg_end) if("!") return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. @@ -341,7 +341,7 @@ 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) +/datum/language/human/get_spoken_verb(msg_end) switch(msg_end) if("!") return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. @@ -396,15 +396,14 @@ key = "y" flags = RESTRICTED | HIVEMIND -/datum/language/wryn/check_special_condition(var/mob/other) - +/datum/language/wryn/check_special_condition(mob/other) var/mob/living/carbon/M = other if(!istype(M)) - return 1 + return TRUE if(locate(/obj/item/organ/internal/wryn/hivenode) in M.internal_organs) - return 1 + return TRUE - return 0 + return FALSE /datum/language/xenocommon name = "Xenomorph" @@ -428,7 +427,6 @@ flags = RESTRICTED | HIVEMIND follow = 1 - /datum/language/terrorspider name = "Spider Hivemind" desc = "Terror spiders have a limited ability to commune over a psychic hivemind, similar to xenomorphs." @@ -440,7 +438,6 @@ flags = RESTRICTED | HIVEMIND follow = 1 - /datum/language/ling name = "Changeling" desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." @@ -449,6 +446,14 @@ key = "g" flags = RESTRICTED | HIVEMIND +/datum/language/ling/broadcast(mob/living/speaker, message, speaker_mask) + if(speaker.mind && speaker.mind.changeling) + ..(speaker,message,speaker.mind.changeling.changelingID) + else if(speaker.mind && speaker.mind.linglink) + ..() + else + ..(speaker,message) + /datum/language/shadowling name = "Shadowling Hivemind" desc = "Shadowlings and their thralls are capable of communicating over a psychic hivemind." @@ -457,20 +462,12 @@ key = "8" flags = RESTRICTED | HIVEMIND - -/datum/language/shadowling/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) +/datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask) if(speaker.mind && speaker.mind.special_role) ..(speaker, message, "([speaker.mind.special_role]) [speaker]") else ..(speaker, message) -/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - - if(speaker.mind && speaker.mind.changeling) - ..(speaker,message,speaker.mind.changeling.changelingID) - else - ..(speaker,message) - /datum/language/abductor name = "Abductor Mindlink" desc = "Abductors are incapable of speech, but have a psychic link attuned to their own team." @@ -481,14 +478,14 @@ key = "zw" //doesn't matter, this is their default and only language flags = RESTRICTED | HIVEMIND -/datum/language/abductor/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) +/datum/language/abductor/broadcast(mob/living/speaker, message, speaker_mask) ..(speaker,message,speaker.real_name) -/datum/language/abductor/check_special_condition(var/mob/living/carbon/human/other, var/mob/living/carbon/human/speaker) +/datum/language/abductor/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker) if(other.mind && other.mind.abductor) if(other.mind.abductor.team == speaker.mind.abductor.team) - return 1 - return 0 + return TRUE + return FALSE /datum/language/corticalborer name = "Cortical Link" @@ -500,11 +497,11 @@ key = "x" flags = RESTRICTED | HIVEMIND -/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) +/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask) var/mob/living/simple_animal/borer/B - if(istype(speaker,/mob/living/carbon)) + if(iscarbon(speaker)) var/mob/living/carbon/M = speaker B = M.has_brain_worms() else if(istype(speaker,/mob/living/simple_animal/borer)) @@ -526,7 +523,7 @@ follow = 1 var/drone_only -/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) +/datum/language/binary/broadcast(mob/living/speaker, message, speaker_mask) if(!speaker.binarycheck()) return @@ -538,15 +535,14 @@ var/message_body = "[speaker.say_quote(message)], \"[message]\"" for(var/mob/M in dead_mob_list) - if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) + if(!isnewplayer(M) && !isbrain(M)) var/message_start_dead = "[name], [speaker.name] ([ghost_follow_link(speaker, ghost=M)])" M.show_message("[message_start_dead] [message_body]", 2) for(var/mob/living/S in living_mob_list) - if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) continue - else if(istype(S , /mob/living/silicon/ai)) + else if(isAI(S)) message_start = "[name], [speaker.name]" else if(!S.binarycheck()) continue @@ -557,7 +553,7 @@ listening -= src for(var/mob/living/M in listening) - if(istype(M, /mob/living/silicon) || M.binarycheck()) + if(issilicon(M) || M.binarycheck()) continue M.show_message("synthesised voice beeps, \"beep beep beep\"",2) @@ -596,17 +592,17 @@ follow = 1 // Language handling. -/mob/proc/add_language(var/language) +/mob/proc/add_language(language) var/datum/language/new_language = all_languages[language] if(!istype(new_language) || new_language in languages) - return 0 + return FALSE languages |= new_language - return 1 + return TRUE -/mob/proc/remove_language(var/rem_language) +/mob/proc/remove_language(rem_language) var/datum/language/L = all_languages[rem_language] . = (L in languages) languages.Remove(L) @@ -620,7 +616,7 @@ // Can we speak this language, as opposed to just understanding it? /mob/proc/can_speak_language(datum/language/speaking) - return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) + return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in languages) //TBD /mob/verb/check_languages() @@ -661,7 +657,7 @@ if(L) set_default_language(L) check_languages() - return 1 + return TRUE else return ..() diff --git a/code/modules/mob/living/carbon/alien/alien_defenses.dm b/code/modules/mob/living/carbon/alien/alien_defenses.dm index c6e2bcc510d..c1ce34bf8e7 100644 --- a/code/modules/mob/living/carbon/alien/alien_defenses.dm +++ b/code/modules/mob/living/carbon/alien/alien_defenses.dm @@ -35,7 +35,7 @@ In all, this is a lot like the monkey code. /N visible_message("[M.name] bites [src]!", \ "[M.name] bites [src]!") adjustBruteLoss(damage) - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) updatehealth() else to_chat(M, "[name] is too injured for that.") diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index c7c8c1cefa8..a78ab9c4c77 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -116,7 +116,7 @@ "[M] [M.attacktext] [src]!") var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) updatehealth() diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 555fcff29da..e8afbb0360b 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -10,6 +10,7 @@ /mob/living/carbon/brain/New() create_reagents(330) + add_language("Galactic Common") ..() /mob/living/carbon/brain/Destroy() diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index e3ffe2074a7..064605001dd 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -116,12 +116,6 @@ mmi_icon_state = "slime_mmi" // parent_organ = "chest" Hello I am from the ministry of rubber forehead aliens how are you -/obj/item/organ/internal/brain/slime/take_damage(var/amount, var/silent = 1) - //Slimes are 150% more vulnerable to brain damage - damage = between(0, src.damage + (1.5*amount), max_damage) //Since they take the damage twice, this is +150% - return ..() - - /obj/item/organ/internal/brain/golem name = "Runic mind" desc = "A tightly furled roll of paper, covered with indecipherable runes." diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index fed16671887..d0289e1f32e 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -34,12 +34,12 @@ /mob/living/carbon/Move(NewLoc, direct) . = ..() if(.) - if(src.nutrition && src.stat != 2) - src.nutrition -= HUNGER_FACTOR/10 - if(src.m_intent == "run") - src.nutrition -= HUNGER_FACTOR/10 - if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360) - src.bodytemperature += 2 + if(nutrition && stat != DEAD) + nutrition -= hunger_drain / 10 + if(m_intent == "run") + nutrition -= hunger_drain / 10 + if((FAT in mutations) && m_intent == "run" && bodytemperature <= 360) + bodytemperature += 2 // Moving around increases germ_level faster if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8)) @@ -309,7 +309,7 @@ Stun(2) var/obj/item/organ/internal/eyes/E = get_int_organ(/obj/item/organ/internal/eyes) - if(!E) + if(!E || (E && E.weld_proof)) return switch(damage) @@ -914,14 +914,14 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/proc/slip(var/description, var/stun, var/weaken, var/tilesSlipped, var/walkSafely, var/slipAny) if(flying || buckled || (walkSafely && m_intent == "walk")) - return + return 0 if((lying) && (!(tilesSlipped))) - return + return 0 if(!(slipAny)) if(istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src if((isobj(H.shoes) && H.shoes.flags & NOSLIP) || H.species.bodyflags & FEET_NOSLIP) - return + return 0 if(tilesSlipped) for(var/t = 0, t<=tilesSlipped, t++) spawn (t) step(src, src.dir) @@ -939,9 +939,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/proc/eat(var/obj/item/weapon/reagent_containers/food/toEat, mob/user) if(!istype(toEat)) return 0 - var/fullness = 0 + var/fullness = nutrition + 10 if(istype(toEat, /obj/item/weapon/reagent_containers/food/snacks)) - fullness = nutrition + (reagents.get_reagent_amount("nutriment") * 20) + (reagents.get_reagent_amount("protein") * 25) + (reagents.get_reagent_amount("plantmatter") * 25) + for(var/datum/reagent/consumable/C in reagents.reagent_list) //we add the nutrition value of what we're currently digesting + fullness += C.nutriment_factor * C.volume / (C.metabolization_rate * metabolism_efficiency * digestion_ratio) if(user == src) if(istype(toEat, /obj/item/weapon/reagent_containers/food/drinks)) if(!selfDrink(toEat)) @@ -957,18 +958,21 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return 1 /mob/living/carbon/proc/selfFeed(var/obj/item/weapon/reagent_containers/food/toEat, fullness) - if(istype(toEat, /obj/item/weapon/reagent_containers/food/pill)) + if(ispill(toEat)) to_chat(src, "You [toEat.apply_method] [toEat].") else + if(toEat.junkiness && satiety < -150 && nutrition > NUTRITION_LEVEL_STARVING + 50 ) + to_chat(src, "You don't feel like eating any more junk food at the moment.") + return 0 if(fullness <= 50) to_chat(src, "You hungrily chew out a piece of [toEat] and gobble it!") - else if(fullness > 50 && fullness <= 150) + else if(fullness > 50 && fullness < 150) to_chat(src, "You hungrily begin to eat [toEat].") - else if(fullness > 150 && fullness <= 350) + else if(fullness > 150 && fullness < 500) to_chat(src, "You take a bite of [toEat].") - else if(fullness > 350 && fullness <= 550) + else if(fullness > 500 && fullness < 600) to_chat(src, "You unwillingly chew a bit of [toEat].") - else if(fullness > (550 * (1 + overeatduration / 2000))) // The more you eat - the more you can eat + else if(fullness > (600 * (1 + overeatduration / 2000))) // The more you eat - the more you can eat to_chat(src, "You cannot force any more of [toEat] to go down your throat.") return 0 return 1 @@ -977,7 +981,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return 1 /mob/living/carbon/proc/forceFed(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, fullness) - if(fullness <= (550 * (1 + overeatduration / 1000))) + if(ispill(toEat) || fullness <= (600 * (1 + overeatduration / 1000))) if(!toEat.instant_application) visible_message("[user] attempts to force [src] to [toEat.apply_method] [toEat].") else @@ -991,8 +995,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return 1 /mob/living/carbon/proc/forceFedAttackLog(var/obj/item/weapon/reagent_containers/food/toEat, mob/user) - attack_log += text("\[[time_stamp()]\] Has been fed [toEat.name] by [user.name] ([user.ckey]) Reagents: [toEat.reagentlist(toEat)]") - user.attack_log += text("\[[time_stamp()]\] Fed [toEat.name] to [name] ([ckey]) Reagents: [toEat.reagentlist(toEat)]") + create_attack_log("Has been fed [toEat.name] by [user.name] ([user.ckey]) Reagents: [toEat.reagentlist(toEat)]") + user.create_attack_log("Fed [toEat.name] to [name] ([ckey]) Reagents: [toEat.reagentlist(toEat)]") log_attack("[user.name] ([user.ckey]) fed [name] ([ckey]) with [toEat.name] Reagents: [toEat.reagentlist(toEat)] (INTENT: [uppertext(user.a_intent)])") if(!iscarbon(user)) LAssailant = null @@ -1005,15 +1009,14 @@ so that different stomachs can handle things in different ways VB*/ /mob/living/carbon/proc/consume(var/obj/item/weapon/reagent_containers/food/toEat) if(!toEat.reagents) return + if(satiety > -200) + satiety -= toEat.junkiness if(toEat.consume_sound) playsound(loc, toEat.consume_sound, rand(10,50), 1) if(toEat.reagents.total_volume) - toEat.reagents.reaction(src, toEat.apply_type) - spawn(0) - if(toEat.reagents.total_volume > toEat.bitesize) - toEat.reagents.trans_to(src, toEat.bitesize*toEat.transfer_efficiency) - else - toEat.reagents.trans_to(src, toEat.reagents.total_volume*toEat.transfer_efficiency) + var/fraction = min(toEat.bitesize/toEat.reagents.total_volume, 1) + toEat.reagents.reaction(src, toEat.apply_type, fraction) + toEat.reagents.trans_to(src, toEat.bitesize*toEat.transfer_efficiency) /mob/living/carbon/get_access() . = ..() diff --git a/code/modules/mob/living/carbon/carbon_defenses.dm b/code/modules/mob/living/carbon/carbon_defenses.dm index efebc58ffc1..b2dcf20f1b2 100644 --- a/code/modules/mob/living/carbon/carbon_defenses.dm +++ b/code/modules/mob/living/carbon/carbon_defenses.dm @@ -36,4 +36,4 @@ for(var/datum/disease/D in user.viruses) if(D.IsSpreadByTouch()) ContractDisease(D) - return 0 + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 558a6f8e9de..f9315966d27 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -83,12 +83,12 @@ message = "[src] pings at [param]." else message = "[src] pings." - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + playsound(loc, 'sound/machines/ping.ogg', 50, 0) m_type = 2 if("buzz2") message = "[src] emits an irritated buzzing sound." - playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) m_type = 2 if("buzz", "buzzes") @@ -105,7 +105,7 @@ message = "[src] buzzes at [param]." else message = "[src] buzzes." - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0) m_type = 2 if("beep", "beeps") @@ -122,7 +122,7 @@ message = "[src] beeps at [param]." else message = "[src] beeps." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + playsound(loc, 'sound/machines/twobeep.ogg', 50, 0) m_type = 2 if("drone", "drones", "hum", "hums", "rumble", "rumbles") @@ -139,7 +139,7 @@ message = "[src] drones at [param]." else message = "[src] rumbles." - playsound(src.loc, 'sound/voice/DraskTalk.ogg', 50, 0) + playsound(loc, 'sound/voice/DraskTalk.ogg', 50, 0) m_type = 2 if("squish", "squishes") @@ -156,7 +156,7 @@ message = "[src] squishes at [param]." else message = "[src] squishes." - playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. + playsound(loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. m_type = 2 if("yes") @@ -173,7 +173,7 @@ message = "[src] emits an affirmative blip at [param]." else message = "[src] emits an affirmative blip." - playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) + playsound(loc, 'sound/machines/synth_yes.ogg', 50, 0) m_type = 2 if("no") @@ -190,7 +190,7 @@ message = "[src] emits a negative blip at [param]." else message = "[src] emits a negative blip." - playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) + playsound(loc, 'sound/machines/synth_no.ogg', 50, 0) m_type = 2 if("wag", "wags") @@ -202,7 +202,7 @@ else if(species.bodyflags & TAIL_WAGGING) if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) message = "[src] starts wagging \his tail." - src.start_tail_wagging(1) + start_tail_wagging(1) else return else @@ -212,15 +212,25 @@ if("swag", "swags") if(species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging \his tail." - src.stop_tail_wagging(1) + stop_tail_wagging(1) else return m_type = 1 if("airguitar") - if(!src.restrained()) + if(!restrained()) message = "[src] is strumming the air and headbanging like a safari chimp." m_type = 1 + + if("dance") + if(!restrained()) + message = "[src] dances around happily." + m_type = 1 + + if("jump") + if(!restrained()) + message = "[src] jumps!" + m_type = 1 if("blink", "blinks") message = "[src] blinks." @@ -231,7 +241,7 @@ m_type = 1 if("bow", "bows") - if(!src.buckled) + if(!buckled) var/M = null if(param) for(var/mob/A in view(null, null)) @@ -248,7 +258,7 @@ m_type = 1 if("salute", "salutes") - if(!src.buckled) + if(!buckled) var/M = null if(param) for(var/mob/A in view(null, null)) @@ -288,13 +298,13 @@ message = "[src] makes a peculiar noise." m_type = 2 if("clap", "claps") - if(!src.restrained()) + if(!restrained()) message = "[src] claps." m_type = 2 if(miming) m_type = 1 if("flap", "flaps") - if(!src.restrained()) + if(!restrained()) message = "[src] flaps \his wings." m_type = 2 if(miming) @@ -302,7 +312,7 @@ if("flip", "flips") m_type = 1 - if(!src.restrained()) + if(!restrained()) var/M = null if(param) for(var/mob/A in view(1, null)) @@ -340,7 +350,7 @@ SpinAnimation(5,1) if("aflap", "aflaps") - if(!src.restrained()) + if(!restrained()) message = "[src] flaps \his wings ANGRILY!" m_type = 2 if(miming) @@ -376,7 +386,7 @@ if("faint", "faints") message = "[src] faints." - if(src.sleeping) + if(sleeping) return //Can't faint while asleep AdjustSleeping(2) m_type = 1 @@ -578,11 +588,11 @@ message = "[src] takes a drag from a cigarette and blows \"[M]\" out in smoke." m_type = 1 else - message = "[src] says, \"[M], please. They had a family.\" [src.name] takes a drag from a cigarette and blows their name out in smoke." + message = "[src] says, \"[M], please. They had a family.\" [name] takes a drag from a cigarette and blows their name out in smoke." m_type = 2 if("point", "points") - if(!src.restrained()) + if(!restrained()) var/atom/M = null if(param) for(var/atom/A as mob|obj|turf in view()) @@ -597,7 +607,7 @@ m_type = 1 if("raise", "raises") - if(!src.restrained()) + if(!restrained()) message = "[src] raises a hand." m_type = 1 @@ -610,12 +620,12 @@ m_type = 1 if("signal", "signals") - if(!src.restrained()) + if(!restrained()) var/t1 = round(text2num(param)) if(isnum(t1)) - if(t1 <= 5 && (!src.r_hand || !src.l_hand)) + if(t1 <= 5 && (!r_hand || !l_hand)) message = "[src] raises [t1] finger\s." - else if(t1 <= 10 && (!src.r_hand && !src.l_hand)) + else if(t1 <= 10 && (!r_hand && !l_hand)) message = "[src] raises [t1] finger\s." m_type = 1 @@ -699,7 +709,7 @@ if("hug", "hugs") m_type = 1 - if(!src.restrained()) + if(!restrained()) var/M = null if(param) for(var/mob/A in view(1, null)) @@ -716,7 +726,7 @@ if("handshake") m_type = 1 - if(!src.restrained() && !src.r_hand) + if(!restrained() && !r_hand) var/mob/M = null if(param) for(var/mob/A in view(1, null)) @@ -734,7 +744,7 @@ if("dap", "daps") m_type = 1 - if(!src.restrained()) + if(!restrained()) var/M = null if(param) for(var/mob/A in view(1, null)) @@ -748,7 +758,7 @@ if("slap", "slaps") m_type = 1 - if(!src.restrained()) + if(!restrained()) var/M = null if(param) for(var/mob/A in view(1, null)) @@ -757,11 +767,11 @@ break if(M) message = "[src] slaps [M] across the face. Ouch!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + playsound(loc, 'sound/effects/snap.ogg', 50, 1) else message = "[src] slaps \himself!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - src.adjustFireLoss(4) + playsound(loc, 'sound/effects/snap.ogg', 50, 1) + adjustFireLoss(4) if("scream", "screams") if(miming) @@ -772,9 +782,9 @@ message = "[src] [species.scream_verb]!" m_type = 2 if(gender == FEMALE) - playsound(src.loc, "[species.female_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) + playsound(loc, "[species.female_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) else - playsound(src.loc, "[species.male_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) //default to male screams if no gender is present. + playsound(loc, "[species.male_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) //default to male screams if no gender is present. else message = "[src] makes a very loud noise." @@ -799,24 +809,24 @@ return message = "[src] snaps \his fingers." - playsound(src.loc, 'sound/effects/fingersnap.ogg', 50, 1, -3) + playsound(loc, 'sound/effects/fingersnap.ogg', 50, 1, -3) else message = "[src] snaps \his fingers right off!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + playsound(loc, 'sound/effects/snap.ogg', 50, 1) // Needed for M_TOXIC_FART if("fart", "farts") if(reagents.has_reagent("simethicone")) return -// playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun +// playsound(loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun if(locate(/obj/item/weapon/storage/bible) in get_turf(src)) to_chat(viewers(src), "[src] farts on the Bible!") to_chat(viewers(src), "A mysterious force smites [src]!") var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() - src.gib() + gib() else if(TOXIC_FARTS in mutations) message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." else if(SUPER_FART in mutations) @@ -841,9 +851,9 @@ M.reagents.add_reagent("jenkem", 1) if("help") - var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dap(s)(none)/mob," \ - + " deathgasp(s), drool(s), eyebrow,fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), handshake-mob, hug(s)-(none)/mob," \ - + " glare(s)-(none)/mob, grin(s), johnny, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dance, dap(s)(none)/mob," \ + + " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), grin(s)," \ + + " handshake-mob, hug(s)-(none)/mob, johnny, jump, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ + " wag(s), wave(s), whimper(s), wink(s), yawn(s)" if(species.name == "Machine") diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index ff7622731d6..453402ec7e3 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -253,10 +253,10 @@ if(5) msg += "[t_He] looks absolutely soaked.\n" - if(nutrition < 100) + if(nutrition < NUTRITION_LEVEL_STARVING - 50) msg += "[t_He] [t_is] severely malnourished.\n" - else if(nutrition >= 500) - if(user.nutrition < 100) + else if(nutrition >= NUTRITION_LEVEL_FAT) + if(user.nutrition < NUTRITION_LEVEL_STARVING - 50) msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n" else msg += "[t_He] [t_is] quite chubby.\n" @@ -516,7 +516,7 @@ return istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.glasses, /obj/item/clothing/glasses/hud/health/health_advanced) || istype(CIH,/obj/item/organ/internal/cyberimp/eyes/hud/medical) else return 0 - else if(istype(M, /mob/living/silicon)) + else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system switch(hudtype) if("security") return 1 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index cd0e9d751c9..c2e2f090bb2 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -721,8 +721,6 @@ if(istype(id)) return id - - /mob/living/carbon/human/update_sight() if(!client) return @@ -805,10 +803,12 @@ unEquip(pocket_item) if(thief_mode) usr.put_in_hands(pocket_item) + add_logs(usr, src, "stripped", addition="of [pocket_item]", print_attack_log = isLivingSSD(src)) else if(place_item) usr.unEquip(place_item) equip_to_slot_if_possible(place_item, pocket_id, 0, 1) + add_logs(usr, src, "equipped", addition="with [pocket_item]", print_attack_log = isLivingSSD(src)) // Update strip window if(usr.machine == src && in_range(src, usr)) @@ -817,6 +817,7 @@ // Display a warning if the user mocks up if they don't have pickpocket gloves. if(!thief_mode) to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") + add_logs(usr, src, "attempted to strip", addition="of [pocket_item]", print_attack_log = isLivingSSD(src)) if(href_list["set_sensor"]) if(istype(w_uniform, /obj/item/clothing/under)) @@ -1530,11 +1531,8 @@ if(species.default_language) add_language(species.default_language) - see_in_dark = species.darksight - if(see_in_dark > 2) - see_invisible = SEE_INVISIBLE_LEVEL_ONE - else - see_invisible = SEE_INVISIBLE_LIVING + hunger_drain = species.hunger_drain + digestion_ratio = species.digestion_ratio if(species.base_color && default_colour) //Apply colour. @@ -1602,8 +1600,17 @@ dna.real_name = real_name species.handle_post_spawn(src) + + see_in_dark = species.get_resultant_darksight(src) + if(see_in_dark > 2) + see_invisible = SEE_INVISIBLE_LEVEL_ONE + else + see_invisible = SEE_INVISIBLE_LIVING + species.handle_dna(src) //Give them whatever special dna business they got. + update_client_colour(0) + spawn(0) overlays.Cut() update_mutantrace(1) @@ -1626,7 +1633,6 @@ return null return species.default_language ? all_languages[species.default_language] : null - /mob/living/carbon/human/proc/bloody_doodle() set category = "IC" set name = "Write in blood" diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index cea8c962af7..a8e075f2433 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -182,8 +182,8 @@ apply_effect(2, WEAKEN, run_armor_check(affecting, "melee")) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("[M] has pushed [src]!") - M.attack_log += text("\[[time_stamp()]\] Pushed [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] Has been pushed by [M.name] ([M.ckey])") + M.create_attack_log("Pushed [src.name] ([src.ckey])") + src.create_attack_log("Has been pushed by [M.name] ([M.ckey])") if(!iscarbon(M)) LAssailant = null else diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 0e2e95bc778..4cf009ec44f 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -28,13 +28,15 @@ med_hud_set_status() handle_hud_icons() -/mob/living/carbon/human/adjustBrainLoss(var/amount) +/mob/living/carbon/human/adjustBrainLoss(amount) if(status_flags & GODMODE) return 0 //godmode if(species && species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) + if(species) + amount = amount * species.brain_mod sponge.take_damage(amount, 1) brainloss = sponge.damage else @@ -42,14 +44,16 @@ else brainloss = 0 -/mob/living/carbon/human/setBrainLoss(var/amount) +/mob/living/carbon/human/setBrainLoss(amount) if(status_flags & GODMODE) return 0 //godmode if(species && species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) - sponge.damage = min(max(amount, 0),(maxHealth*2)) + if(species) + amount = amount * species.brain_mod + sponge.damage = min(max(amount, 0), (maxHealth*2)) brainloss = sponge.damage else brainloss = 200 @@ -84,25 +88,25 @@ return amount -/mob/living/carbon/human/adjustBruteLoss(var/amount) - if(species && species.brute_mod) - amount = amount*species.brute_mod +/mob/living/carbon/human/adjustBruteLoss(amount) + if(species) + amount = amount * species.brute_mod if(amount > 0) take_overall_damage(amount, 0) else heal_overall_damage(-amount, 0) -/mob/living/carbon/human/adjustFireLoss(var/amount) - if(species && species.burn_mod) - amount = amount*species.burn_mod +/mob/living/carbon/human/adjustFireLoss(amount) + if(species) + amount = amount * species.burn_mod if(amount > 0) take_overall_damage(0, amount) else heal_overall_damage(0, -amount) -/mob/living/carbon/human/proc/adjustBruteLossByPart(var/amount, var/organ_name, var/obj/damage_source = null) - if(species && species.brute_mod) - amount = amount*species.brute_mod +/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null) + if(species) + amount = amount * species.brute_mod if(organ_name in organs_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -114,9 +118,9 @@ O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) -/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null) - if(species && species.burn_mod) - amount = amount*species.burn_mod +/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null) + if(species) + amount = amount * species.burn_mod if(organ_name in organs_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -134,13 +138,11 @@ wearing_rig.notify_ai("Warning: user consciousness failure. Mobility control passed to integrated intelligence system.") ..() -/mob/living/carbon/human/adjustCloneLoss(var/amount) +/mob/living/carbon/human/adjustCloneLoss(amount) + if(species) + amount = amount * species.clone_mod ..() - if(species.flags & (NO_DNA)) - cloneloss = 0 - return - var/heal_prob = max(0, 80 - getCloneLoss()) var/mut_prob = min(80, getCloneLoss() + 10) if(amount > 0) //cloneloss is being added @@ -176,44 +178,30 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. -/mob/living/carbon/human/getOxyLoss() - if(species.flags & NO_BREATHE) - oxyloss = 0 - return ..() +/mob/living/carbon/human/adjustOxyLoss(amount) + if(species) + amount = amount * species.oxy_mod + ..() -/mob/living/carbon/human/adjustOxyLoss(var/amount) - if(species.flags & NO_BREATHE) - oxyloss = 0 - else - ..() +/mob/living/carbon/human/setOxyLoss(amount) + if(species) + amount = amount * species.oxy_mod + ..() -/mob/living/carbon/human/setOxyLoss(var/amount) - if(species.flags & NO_BREATHE) - oxyloss = 0 //this literally overrides three procs, excessive much? - else - ..() +/mob/living/carbon/human/adjustToxLoss(amount) + if(species) + amount = amount * species.tox_mod + ..() -/mob/living/carbon/human/getToxLoss() - if(species.flags & NO_POISON) - toxloss = 0 - return ..() - -/mob/living/carbon/human/adjustToxLoss(var/amount) - if(species.flags & NO_POISON) - toxloss = 0 - else - ..() - -/mob/living/carbon/human/setToxLoss(var/amount) - if(species.flags & NO_POISON) - toxloss = 0 //this *also* overrides three procs, definately excessive - else - ..() +/mob/living/carbon/human/setToxLoss(amount) + if(species) + amount = amount * species.tox_mod + ..() //////////////////////////////////////////// //Returns a list of damaged organs -/mob/living/carbon/human/proc/get_damaged_organs(var/brute, var/burn, var/flags = AFFECT_ALL_ORGANS) +/mob/living/carbon/human/proc/get_damaged_organs(brute, burn, flags = AFFECT_ALL_ORGANS) var/list/obj/item/organ/external/parts = list() for(var/obj/item/organ/external/O in organs) if((brute && O.brute_dam) || (burn && O.burn_dam)) @@ -235,7 +223,7 @@ //Heals ONE external organ, organ gets randomly selected from damaged ones. //It automatically updates damage overlays if necesary //It automatically updates health status -/mob/living/carbon/human/heal_organ_damage(var/brute, var/burn) +/mob/living/carbon/human/heal_organ_damage(brute, burn) var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn) if(!parts.len) return @@ -247,7 +235,7 @@ //Damages ONE external organ, organ gets randomly selected from damagable ones. //It automatically updates damage overlays if necesary //It automatically updates health status -/mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0) +/mob/living/carbon/human/take_organ_damage(brute, burn, sharp = 0, edge = 0) var/list/obj/item/organ/external/parts = get_damageable_organs() if(!parts.len) return @@ -259,7 +247,7 @@ //Heal MANY external organs, in random order -/mob/living/carbon/human/heal_overall_damage(var/brute, var/burn, var/internal=0, var/robotic=0) +/mob/living/carbon/human/heal_overall_damage(brute, burn, internal=0, robotic=0) var/list/obj/item/organ/external/parts = get_damaged_organs(brute,burn) var/update = 0 @@ -282,7 +270,7 @@ UpdateDamageIcon() // damage MANY external organs, in random order -/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null) +/mob/living/carbon/human/take_overall_damage(brute, burn, sharp = 0, edge = 0, used_weapon = null) if(status_flags & GODMODE) return //godmode var/list/obj/item/organ/external/parts = get_damageable_organs() @@ -337,7 +325,7 @@ This function restores all organs. return 0 -/mob/living/carbon/human/proc/get_organ(var/zone) +/mob/living/carbon/human/proc/get_organ(zone) if(!zone) zone = "chest" if(zone in list("eyes", "mouth")) @@ -345,7 +333,7 @@ This function restores all organs. return organs_by_name[zone] -/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null) +/mob/living/carbon/human/apply_damage(damage = 0, damagetype = BRUTE, def_zone = null, blocked = 0, sharp = 0, edge = 0, obj/used_weapon = null) //Handle other types of damage if((damagetype != BRUTE) && (damagetype != BURN)) ..(damage, damagetype, def_zone, blocked) @@ -373,7 +361,7 @@ This function restores all organs. switch(damagetype) if(BRUTE) damageoverlaytemp = 20 - if(species && species.brute_mod) + if(species) damage = damage * species.brute_mod if(organ.take_damage(damage, 0, sharp, edge, used_weapon)) @@ -398,7 +386,7 @@ This function restores all organs. if(BURN) damageoverlaytemp = 20 - if(species && species.burn_mod) + if(species) damage = damage * species.burn_mod if(organ.take_damage(0, damage, sharp, edge, used_weapon)) @@ -406,4 +394,4 @@ This function restores all organs. // Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life(). updatehealth() - return 1 + return 1 \ 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 0ceabc84bfe..986a3ffb9c4 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -38,6 +38,7 @@ emp_act var/obj/item/organ/external/organ = get_organ(check_zone(def_zone)) if(isnull(organ)) + . = bullet_act(P, "chest") //act on chest instead return //Shrapnel @@ -56,6 +57,18 @@ emp_act organ.add_autopsy_data(P.name, P.damage) // Add the bullet's name to the autopsy data return (..(P , def_zone)) + +/mob/living/carbon/human/check_projectile_dismemberment(obj/item/projectile/P, def_zone) + var/obj/item/organ/external/affecting = get_organ(check_zone(def_zone)) + if(affecting && !affecting.cannot_amputate && affecting.get_damage() >= (affecting.max_damage - P.dismemberment)) + var/damtype = DROPLIMB_EDGE + switch(P.damage_type) + if(BRUTE) + damtype = DROPLIMB_BLUNT + if(BURN) + damtype = DROPLIMB_BURN + + affecting.droplimb(FALSE, damtype) /mob/living/carbon/human/getarmor(var/def_zone, var/type) var/armorval = 0 @@ -187,8 +200,8 @@ emp_act --src.meatleft to_chat(user, "\red You hack off a chunk of meat from [src.name]") if(!src.meatleft) - src.attack_log += "\[[time_stamp()]\] Was chopped up into meat by [key_name(user)]" - user.attack_log += "\[[time_stamp()]\] Chopped up [key_name(src)] into meat
" + src.create_attack_log("Was chopped up into meat by [key_name(user)]") + user.create_attack_log("Chopped up [key_name(src)] into meat
") msg_admin_attack("[key_name_admin(user)] chopped up [key_name_admin(src)] into meat") if(!iscarbon(user)) LAssailant = null @@ -338,10 +351,7 @@ emp_act if(ismob(I.thrower)) var/mob/M = I.thrower if(M) - src.attack_log += text("\[[time_stamp()]\] Has been hit with a [I], thrown by [key_name(M)]") - M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [I]") - if(!istype(src,/mob/living/simple_animal/mouse)) - msg_admin_attack("[key_name_admin(src)] was hit by a [I], thrown by [key_name_admin(M)]") + add_logs(M, src, "hit", I, " (thrown)", print_attack_log = I.throwforce) //thrown weapon embedded object code. if(dtype == BRUTE && istype(I)) @@ -439,8 +449,8 @@ emp_act visible_message("[src] has been hit by [M.name].", \ "[src] has been hit by [M.name].") - attack_log += text("\[[time_stamp()]\] Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])") - M.occupant.attack_log += text("\[[time_stamp()]\] Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") + create_attack_log("Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])") + M.occupant.create_attack_log("Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") msg_admin_attack("[key_name_admin(M.occupant)] attacked [key_name_admin(src)] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") else diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm index 199530c4805..272b95d3577 100644 --- a/code/modules/mob/living/carbon/human/interactive/functions.dm +++ b/code/modules/mob/living/carbon/human/interactive/functions.dm @@ -119,15 +119,15 @@ internalBeaker.name = "Grow-U-All Super Spray" if(internalBeaker && internalBag) - var/obj/machinery/portable_atmospherics/hydroponics/HP + var/obj/machinery/hydroponics/HP //consider the appropriate target var/list/considered = list() - for(var/obj/machinery/portable_atmospherics/hydroponics/tester in view(12,src)) + for(var/obj/machinery/hydroponics/tester in view(12,src)) considered[tester] = 1 - if(!tester.seed) + if(!tester.myseed) considered[tester] += 50 if(tester.weedlevel > 0) considered[tester] += 5 @@ -154,7 +154,7 @@ else if(HP.harvest || HP.dead) HP.attack_hand(src) - else if(!HP.seed) + else if(!HP.myseed) var/obj/item/seeds/SEED = new /obj/item/seeds/random(src) custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")] towards [TARGET], producing a [SEED]!") HP.attackby(SEED, src) @@ -170,8 +170,8 @@ internalBeaker.reagents.add_reagent("diethylamine", 10) if(HP.nutrilevel < HP.maxnutri) change = 1 - if(!internalBeaker.reagents.has_reagent("eznutrient", 15)) - internalBeaker.reagents.add_reagent("eznutrient", 15) + if(!internalBeaker.reagents.has_reagent("eznutriment", 15)) + internalBeaker.reagents.add_reagent("eznutriment", 15) if(!internalBeaker.reagents.has_reagent("diethylamine", 15)) internalBeaker.reagents.add_reagent("diethylamine", 15) if(HP.waterlevel < HP.maxwater) @@ -261,7 +261,7 @@ var/pranksNearby = 100 for(var/turf/simulated/T in orange(1, C)) for(var/obj/item/A in T) - if(istype(A,/obj/item/weapon/soap) || istype(A,/obj/item/weapon/reagent_containers/food/snacks/grown/banana) || istype(A,/obj/item/weapon/bananapeel)) + if(istype(A,/obj/item/weapon/soap) || istype(A,/obj/item/weapon/reagent_containers/food/snacks/grown/banana) || istype(A,/obj/item/weapon/grown/bananapeel)) pranksNearby-- if(T.wet) pranksNearby -= 10 @@ -287,7 +287,7 @@ if(istype(A,/obj/item/weapon/reagent_containers/food/snacks/grown/banana)) var/obj/item/weapon/reagent_containers/food/snacks/B = A B.attack(src, src) - if(istype(A,/obj/item/weapon/bananapeel)) + if(istype(A,/obj/item/weapon/grown/bananapeel)) npcDrop(A) hasPranked = 1 if(!hasPranked) @@ -403,26 +403,6 @@ ingredients += I I.forceMove(null) - for(var/P in R.fruit) - for(var/i = 1 to R.fruit[P]) - var/obj/item/I = locate(P) in allContents - if(I) - ingredients += I - I.forceMove(null) - continue - - I = locate(P) in rangeCheck - TARGET = I - if(I && !Adjacent(I)) - tryWalk(get_turf(I)) - sleep(get_dist(src, I)) - if(!I || !(I in rangeCheck)) - refundrecipe(ingredients) - return 0 - custom_emote(1, "[pick("gibbers","drools","slobbers","claps wildly","spits")], picking up [I].") - ingredients += I - I.forceMove(null) - // cheaply cook the ingredients into result sleep(R.time) for(var/obj/I in ingredients) @@ -442,7 +422,7 @@ var/static/list/customableTypes = list(/obj/item/weapon/reagent_containers/food/snacks/customizable,/obj/item/weapon/reagent_containers/food/snacks/breadslice,/obj/item/weapon/reagent_containers/food/snacks/bun,/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/weapon/reagent_containers/food/snacks/boiledspagetti,/obj/item/trash/plate,/obj/item/trash/bowl) - var/static/list/rawtypes = list(/obj/item/weapon/reagent_containers/food/snacks/grown, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet, /obj/item/weapon/reagent_containers/food/snacks/rawmeatball, /obj/item/weapon/reagent_containers/food/snacks/rawsticks, /obj/item/weapon/reagent_containers/food/snacks/salmonmeat, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, /obj/item/weapon/reagent_containers/food/snacks/catfishmeat, /obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/dough_ball, /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/boiledrice, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/raw_bacon) + var/static/list/rawtypes = list(/obj/item/weapon/reagent_containers/food/snacks/grown, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet, /obj/item/weapon/reagent_containers/food/snacks/rawsticks, /obj/item/weapon/reagent_containers/food/snacks/salmonmeat, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, /obj/item/weapon/reagent_containers/food/snacks/catfishmeat, /obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/boiledrice, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/raw_bacon) try var/list/allContents = getAllContents() @@ -579,8 +559,8 @@ var/highest_count = 0 var/datum/recipe/winner = null for(var/datum/recipe/R in available_recipes) - if(R.check_items(ingredientZone) >= 0 && R.check_fruit(ingredientZone) >= 0) - var/count = (R.items ? R.items.len : 0) + (R.fruit ? R.fruit.len : 0) + if(R.check_items(ingredientZone) >= 0) + var/count = (R.items ? R.items.len : 0) if(count > highest_count) highest_count = count winner = R diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index 2dfc4f8d24e..fa8de8e2b87 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -349,10 +349,10 @@ favoured_types = list(/obj/item/weapon/mop, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable) functions += "dojanitor" if("Clown") - favoured_types = list(/obj/item/weapon/soap, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/bananapeel) + favoured_types = list(/obj/item/weapon/soap, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/grown/bananapeel) functions += "clowning" if("Botanist") - favoured_types = list(/obj/machinery/portable_atmospherics/hydroponics, /obj/item/weapon/reagent_containers, /obj/item/weapon) + favoured_types = list(/obj/machinery/hydroponics, /obj/item/weapon/reagent_containers, /obj/item/weapon) functions += "botany" restrictedJob = 1 else diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 4e90d763e9e..c375d718e3d 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -119,6 +119,7 @@ if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view) update_sight() update_inv_glasses() + update_client_colour() else if(I == head) head = null if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR) @@ -271,6 +272,7 @@ if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view) update_sight() update_inv_glasses(redraw_mob) + update_client_colour() if(slot_gloves) gloves = W update_inv_gloves(redraw_mob) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 052d528df0b..8448c786302 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -506,17 +506,14 @@ //END FIRE CODE /mob/living/carbon/human/proc/stabilize_temperature_from_calories() + var/body_temperature_difference = species.body_temperature - bodytemperature + if(bodytemperature <= species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. - if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. - nutrition -= 2 - var/body_temperature_difference = species.body_temperature - bodytemperature - bodytemperature += max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) + bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) if(bodytemperature >= species.cold_level_1 && bodytemperature <= species.heat_level_1) - var/body_temperature_difference = species.body_temperature - bodytemperature - bodytemperature += body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR + bodytemperature += body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR if(bodytemperature >= species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects. //We totally need a sweat system cause it totally makes sense...~ - var/body_temperature_difference = species.body_temperature - bodytemperature bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers @@ -676,11 +673,20 @@ becomeFat() // nutrition decrease - if(nutrition > 0 && stat != 2) - nutrition = max (0, nutrition - HUNGER_FACTOR) + if(nutrition > 0 && stat != DEAD) + // THEY HUNGER + var/hunger_rate = hunger_drain + if(satiety > 0) + satiety-- + if(satiety < 0) + satiety++ + if(prob(round(-satiety/40))) + Jitter(5) + hunger_rate = 3 * hunger_drain + nutrition = max(0, nutrition - hunger_rate) - if(nutrition > 450) - if(overeatduration < 800) //capped so people don't take forever to unfat + if(nutrition > NUTRITION_LEVEL_FULL) + if(overeatduration < 600) //capped so people don't take forever to unfat overeatduration++ else @@ -690,6 +696,22 @@ else overeatduration -= 2 + //metabolism change + if(nutrition > NUTRITION_LEVEL_FAT) + metabolism_efficiency = 1 + else if(nutrition > NUTRITION_LEVEL_FED && satiety > 80) + if(metabolism_efficiency != 1.25) + to_chat(src, "You feel vigorous.") + metabolism_efficiency = 1.25 + else if(nutrition < NUTRITION_LEVEL_STARVING + 50) + if(metabolism_efficiency != 0.8) + to_chat(src, "You feel sluggish.") + metabolism_efficiency = 0.8 + else + if(metabolism_efficiency == 1.25) + to_chat(src, "You no longer feel vigorous.") + metabolism_efficiency = 1 + if(drowsyness) AdjustDrowsy(-1) EyeBlurry(2) @@ -932,20 +954,8 @@ if(getToxLoss() >= 45 && nutrition > 20) lastpuke ++ if(lastpuke >= 25) // about 25 second delay I guess - Stun(5) - - visible_message("[src] throws up!", \ - "[src] throws up!") - playsound(loc, 'sound/effects/splat.ogg', 50, 1) - - var/turf/location = loc - if(istype(location, /turf/simulated)) - location.add_vomit_floor(src, 1) - - nutrition -= 20 + vomit(20, 0, 1, 0, 1) adjustToxLoss(-3) - - // make it so you can only puke so fast lastpuke = 0 //0.1% chance of playing a scary sound to someone who's in complete darkness diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 26ca4af83e8..7384ccc6796 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,10 +1,10 @@ -/mob/living/carbon/human/say(var/message) +/mob/living/carbon/human/say(var/message, var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE) var/alt_name = "" if(name != GetVoice()) alt_name = " (as [get_id_name("Unknown")])" - ..(message, alt_name = alt_name) //ohgod we should really be passing a datum here. + ..(message, alt_name = alt_name, sanitize = sanitize, ignore_speech_problems = ignore_speech_problems, ignore_atmospherics = ignore_atmospherics) //ohgod we should really be passing a datum here. /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index bb1f3dd2067..4690529524f 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -7,10 +7,21 @@ language = "Abductor Mindlink" default_language = "Abductor Mindlink" unarmed_type = /datum/unarmed_attack/punch - darksight = 3 eyes = "blank_eyes" + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight. + ) flags = HAS_LIPS | NO_BLOOD | NO_BREATHE + + oxy_mod = 0 + virus_immune = 1 clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS dietflags = DIET_OMNI diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/apollo.dm index 5642eedbcbe..4c871405c8d 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/apollo.dm @@ -9,7 +9,6 @@ punchdamagelow = 0 punchdamagehigh = 1 //primitive = /mob/living/carbon/monkey/wryn - darksight = 3 slowdown = 1 warning_low_pressure = -300 hazard_low_pressure = 1 @@ -32,15 +31,17 @@ has_organ = list( "heart" = /obj/item/organ/internal/heart, "brain" = /obj/item/organ/internal/brain, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes/wryn, //3 darksight. "appendix" = /obj/item/organ/internal/appendix, "antennae" = /obj/item/organ/internal/wryn/hivenode ) - flags = IS_WHITELISTED | HAS_LIPS | NO_BREATHE | HAS_SKIN_COLOR | NO_SCAN | NO_SCAN | HIVEMIND + flags = IS_WHITELISTED | HAS_LIPS | NO_BREATHE | HAS_SKIN_COLOR | NO_SCAN | HIVEMIND clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS dietflags = DIET_HERB //bees feed off nectar, so bee people feed off plants too + oxy_mod = 0 + reagent_tag = PROCESS_ORG base_color = "#704300" flesh_color = "#704300" @@ -77,8 +78,8 @@ head_organ.h_style = "Bald" H.update_hair() - M.attack_log += text("\[[time_stamp()]\] removed antennae [H.name] ([H.ckey])") - H.attack_log += text("\[[time_stamp()]\] Has had their antennae removed by [M.name] ([M.ckey])") + M.create_attack_log("removed antennae [H.name] ([H.ckey])") + H.create_attack_log("Has had their antennae removed by [M.name] ([M.ckey])") msg_admin_attack("[key_name(M)] removed [key_name(H)]'s antennae") return 0 @@ -87,7 +88,7 @@ name_plural = "Nucleations" icobase = 'icons/mob/human_races/r_nucleation.dmi' unarmed_type = /datum/unarmed_attack/punch - blurb = "A sub-race of unforunates who have been exposed to too much supermatter radiation. As a result, \ + blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \ supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \ has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \ negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \ @@ -97,6 +98,7 @@ language = "Sol Common" burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores brute_mod = 2 // damn, double wham, double dam + oxy_mod = 0 flags = IS_WHITELISTED | NO_BREATHE | NO_BLOOD | NO_PAIN | HAS_LIPS | NO_SCAN dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet @@ -106,8 +108,8 @@ reagent_tag = PROCESS_ORG has_organ = list( "heart" = /obj/item/organ/internal/heart, - "crystalized brain" = /obj/item/organ/internal/brain/crystal, - "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, + "crystallized brain" = /obj/item/organ/internal/brain/crystal, + "eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2. "strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal, "resonant crystal" = /obj/item/organ/internal/nucleation/resonant_crystal ) diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 1e255ea50cc..a2f2eb30467 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -7,6 +7,9 @@ default_language = "Galactic Common" flags = NO_BREATHE | NO_BLOOD | RADIMMUNE | NOGUNS + + oxy_mod = 0 + virus_immune = 1 dietflags = DIET_OMNI //golems can eat anything because they are magic or something reagent_tag = PROCESS_ORG @@ -37,7 +40,8 @@ has_organ = list( "brain" = /obj/item/organ/internal/brain/golem - ) + ) //Has standard darksight of 2. + suicide_messages = list( "is crumbling into dust!", "is smashing their body apart!") diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index dffc73d4e1d..6e29d658cfe 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -26,6 +26,7 @@ tail = "chimptail" bodyflags = FEET_PADDED | HAS_TAIL reagent_tag = PROCESS_ORG + //Has standard darksight of 2. //unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws) //inherent_verbs = list(/mob/living/proc/ventcrawl) @@ -54,7 +55,7 @@ /datum/species/monkey/handle_dna(var/mob/living/carbon/human/H) H.dna.SetSEState(MONKEYBLOCK,1) - genemutcheck(H, MONKEYBLOCK) + genemutcheck(H,MONKEYBLOCK,null,MUTCHK_FORCED) /datum/species/monkey/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user) switch(slot) @@ -105,6 +106,15 @@ base_color = "#000000" tail = "farwatail" reagent_tag = PROCESS_ORG + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/tajaran, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/tajaran/farwa //Tajara monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ.. + ) /datum/species/monkey/vulpkanin @@ -120,6 +130,15 @@ base_color = "#000000" tail = "wolpintail" reagent_tag = PROCESS_ORG + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/vulpkanin, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes/vulpkanin/wolpin //Vulpkanin monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ.. + ) /datum/species/monkey/skrell diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 5fe7d44ab6d..05f24facc65 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -6,7 +6,7 @@ //language = "Clatter" unarmed_type = /datum/unarmed_attack/punch - flags = IS_WHITELISTED | NO_BLOOD + flags = IS_WHITELISTED | NO_BLOOD | NOTRANSSTING dietflags = DIET_OMNI reagent_tag = PROCESS_ORG @@ -20,6 +20,8 @@ heat_level_2 = 400 // Heat damage level 2 above this point. heat_level_3 = 500 // Heat damage level 3 above this point. + //Has default darksight of 2. + suicide_messages = list( "is twisting their own neck!", "is letting some O2 in!", @@ -67,6 +69,9 @@ suit=/obj/item/clothing/suit/space/eva/plasmaman/security/ helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/ H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_in_backpack) + if("Internal Affairs Agent") + suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer + helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer if("Magistrate") suit=/obj/item/clothing/suit/space/eva/plasmaman/magistrate helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/magistrate diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index fa7dadfebcb..6f594768d4e 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -7,16 +7,22 @@ default_language = "Galactic Common" unarmed_type = /datum/unarmed_attack/claws - darksight = 8 + + ignored_by = list(/mob/living/simple_animal/hostile/faithless) blood_color = "#CCCCCC" flesh_color = "#AAAAAA" has_organ = list( - "brain" = /obj/item/organ/internal/brain + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes/shadow //8 darksight. ) flags = NO_BLOOD | NO_BREATHE | RADIMMUNE + + oxy_mod = 0 + virus_immune = 1 + dietflags = DIET_OMNI //the mutation process allowed you to now digest all foods regardless of initial race reagent_tag = PROCESS_ORG suicide_messages = list( @@ -25,13 +31,45 @@ "is twisting their own neck!", "is staring into the closest light source!") + var/grant_vision_toggle = 1 + var/datum/action/innate/shadow/darkvision/vision_toggle + +/datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is + name = "Toggle Darkvision" + check_flags = AB_CHECK_CONSCIOUS + background_icon_state = "bg_default" + button_icon_state = "blind" + +/datum/action/innate/shadow/darkvision/Activate() + var/mob/living/carbon/human/H = owner + if(!H.vision_type) + H.vision_type = new /datum/vision_override/nightvision + to_chat(H, "You adjust your vision to pierce the darkness.") + else + H.vision_type = null + to_chat(H, "You adjust your vision to recognize the shadows.") + +/datum/species/shadow/grant_abilities(var/mob/living/carbon/human/H) + . = ..() + if(grant_vision_toggle) + vision_toggle = new + vision_toggle.Grant(H) + +/datum/species/shadow/remove_abilities(var/mob/living/carbon/human/H) + . = ..() + if(grant_vision_toggle && vision_toggle) + H.vision_type = null + vision_toggle.Remove(H) + /datum/species/shadow/handle_life(var/mob/living/carbon/human/H) var/light_amount = 0 if(isturf(H.loc)) var/turf/T = H.loc - light_amount = T.get_lumcount()*10 + light_amount = T.get_lumcount() * 10 if(light_amount > 2) //if there's enough light, start dying H.take_overall_damage(1,1) + H.throw_alert("lightexposure", /obj/screen/alert/lightexposure) else if(light_amount < 2) //heal in the dark - H.heal_overall_damage(1,1) \ No newline at end of file + H.heal_overall_damage(1,1) + H.clear_alert("lightexposure") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/skeleton.dm b/code/modules/mob/living/carbon/human/species/skeleton.dm index 7a4f1bae4eb..d09c8dd1699 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -14,6 +14,9 @@ flesh_color = "#E6E6C6" flags = NO_BREATHE | NO_BLOOD | RADIMMUNE + + oxy_mod = 0 + virus_immune = 1 //why is this a var and not a flag? dietflags = DIET_OMNI reagent_tag = PROCESS_ORG @@ -38,7 +41,7 @@ "is twisting their skull off!") has_organ = list( "brain" = /obj/item/organ/internal/brain/golem, - ) + ) //Has default darksight of 2. /datum/species/skeleton/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) // Crazylemon is still silly diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 5730b1a49c1..d8769a3acea 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -43,11 +43,13 @@ var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing) var/reagent_tag //Used for metabolizing reagents. + var/hunger_drain = HUNGER_FACTOR + var/digestion_ratio = 1 //How quickly the species digests/absorbs reagents. var/siemens_coeff = 1 //base electrocution coefficient var/invis_sight = SEE_INVISIBLE_LIVING - var/darksight = 2 + var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning. @@ -66,8 +68,13 @@ "sa_sleep" = 5 ) - var/brute_mod = null // Physical damage reduction/malus. - var/burn_mod = null // Burn damage reduction/malus. + var/brute_mod = 1 // Physical damage reduction/amplification + var/burn_mod = 1 // Burn damage reduction/amplification + var/tox_mod = 1 // Toxin damage reduction/amplification + var/oxy_mod = 1 // Oxy damage reduction/amplification + var/clone_mod = 1 // Clone damage reduction/amplification + var/brain_mod = 1 // Brain damage damage reduction/amplification + var/stun_mod = 1 // If a species is more/less impacated by stuns/weakens/paralysis var/total_health = 100 var/punchdamagelow = 0 //lowest possible punch damage @@ -78,6 +85,8 @@ var/ventcrawler = 0 //Determines if the mob can go through the vents. var/has_fine_manipulation = 1 // Can use small items. + var/mob/living/list/ignored_by = list() // list of mobs that will ignore this species + var/list/allowed_consumed_mobs = list() //If a species can consume mobs, put the type of mobs it can consume here. var/flags = 0 // Various specific features. @@ -155,7 +164,6 @@ "l_foot" = list("path" = /obj/item/organ/external/foot), "r_foot" = list("path" = /obj/item/organ/external/foot/right) ) - var/cyborg_type = "Cyborg" var/list/proc/species_abilities = list() /datum/species/New() @@ -557,8 +565,12 @@ switch(H.nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) H.throw_alert("nutrition", /obj/screen/alert/fat) - if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL) - H.clear_alert("nutrition") + if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) + H.throw_alert("nutrition", /obj/screen/alert/full) + if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) + H.throw_alert("nutrition", /obj/screen/alert/well_fed) + if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) + H.throw_alert("nutrition", /obj/screen/alert/fed) if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) H.throw_alert("nutrition", /obj/screen/alert/hungry) else @@ -575,12 +587,23 @@ It'll return null if the organ doesn't correspond, so include null checks when u return null return has_organ[organ_slot] +/datum/species/proc/get_resultant_darksight(mob/living/carbon/human/H) //Returns default value of 2 if the mob doesn't have eyes, otherwise it grabs the eyes darksight. + var/resultant_darksight = 2 + var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes) + if(eyes) + resultant_darksight = eyes.get_dark_view() + return resultant_darksight /datum/species/proc/update_sight(mob/living/carbon/human/H) H.sight = initial(H.sight) - H.see_in_dark = darksight + H.see_in_dark = get_resultant_darksight(H) H.see_invisible = invis_sight + if(H.see_in_dark > 2) //Preliminary see_invisible handling as per set_species() in code\modules\mob\living\carbon\human\human.dm. + H.see_invisible = SEE_INVISIBLE_LEVEL_ONE + else + H.see_invisible = SEE_INVISIBLE_LIVING + if(H.client.eye != H) var/atom/A = H.client.eye if(A.update_remote_sight(H)) //returns 1 if we override all other sight updates. @@ -631,7 +654,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses) var/obj/item/clothing/glasses/G = rig.visor.vision.glasses if(istype(G)) - H.see_in_dark = (G.darkness_view ? G.darkness_view : darksight) // Otherwise we keep our darkness view with togglable nightvision. + H.see_in_dark = (G.darkness_view ? G.darkness_view : get_resultant_darksight(H)) // Otherwise we keep our darkness view with togglable nightvision. if(G.vision_flags) // MESONS H.sight |= G.vision_flags @@ -641,7 +664,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u H.see_in_dark = max(lesser_darkview_bonus, H.see_in_dark) if(H.vision_type) - H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark, darksight) + H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark, get_resultant_darksight(H)) H.see_invisible = H.vision_type.see_invisible if(H.vision_type.light_sensitive) H.weakeyes = 1 @@ -653,4 +676,4 @@ It'll return null if the organ doesn't correspond, so include null checks when u H.see_invisible = SEE_INVISIBLE_MINIMUM if(H.see_override) //Override all - H.see_invisible = H.see_override + H.see_invisible = H.see_override \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 1a6c8254a3e..1ea4387e477 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -18,6 +18,7 @@ worlds tumultous at best." reagent_tag = PROCESS_ORG + //Has standard darksight of 2. /datum/species/unathi name = "Unathi" @@ -30,7 +31,6 @@ tail = "sogtail" unarmed_type = /datum/unarmed_attack/claws primitive_form = "Stok" - darksight = 3 blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ Uuosa-Eso system, which roughly translates to 'burning mother'.

Coming from a harsh, radioactive \ @@ -66,7 +66,7 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight. ) allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, @@ -91,7 +91,6 @@ language = "Siik'tajr" tail = "tajtail" unarmed_type = /datum/unarmed_attack/claws - darksight = 8 blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ @@ -126,7 +125,8 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ ) allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, @@ -152,7 +152,6 @@ primitive_form = "Wolpin" tail = "vulptail" unarmed_type = /datum/unarmed_attack/claws - darksight = 8 blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \ dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \ @@ -176,7 +175,8 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ ) allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken, @@ -226,7 +226,7 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes //Default darksight of 2. ) suicide_messages = list( @@ -282,7 +282,7 @@ breath_type = "nitrogen" poison_type = "oxygen" - flags = NO_SCAN | IS_WHITELISTED + flags = NO_SCAN | IS_WHITELISTED | NOTRANSSTING clothing_flags = HAS_SOCKS dietflags = DIET_OMNI bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS @@ -315,7 +315,7 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. @@ -439,7 +439,7 @@ "liver" = /obj/item/organ/internal/liver, "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. "stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used ) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ. @@ -478,7 +478,7 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes //Default darksight of 2. ) allowed_consumed_mobs = list(/mob/living/simple_animal/diona) @@ -506,6 +506,9 @@ cold_level_3 = 200 cold_env_multiplier = 3 + oxy_mod = 0 + brain_mod = 2.5 + flags = IS_WHITELISTED | NO_BREATHE | HAS_LIPS | NO_INTORGANS | NO_SCAN clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_COLOR | NO_EYES @@ -514,6 +517,7 @@ exotic_blood = "water" //ventcrawler = 1 //ventcrawling commented out butt_sprite = "slime" + //Has default darksight of 2. has_organ = list( "brain" = /obj/item/organ/internal/brain/slime @@ -682,7 +686,6 @@ default_language = "Galactic Common" language = "Psionic Communication" unarmed_type = /datum/unarmed_attack/punch - darksight = 5 // BOOSTED from 2 eyes = "grey_eyes_s" butt_sprite = "grey" @@ -693,7 +696,7 @@ "kidneys" = /obj/item/organ/internal/kidneys, "brain" = /obj/item/organ/internal/brain/grey, "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, + "eyes" = /obj/item/organ/internal/eyes/grey //5 darksight. ) brute_mod = 1.25 //greys are fragile @@ -711,11 +714,9 @@ /datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove) if(!remove) C.dna.SetSEState(REMOTETALKBLOCK,1,1) - C.mutations |= REMOTE_TALK genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) else C.dna.SetSEState(REMOTETALKBLOCK,0,1) - C.mutations -= REMOTE_TALK genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) ..() @@ -756,6 +757,8 @@ clothing_flags = HAS_SOCKS dietflags = 0 //Diona regenerate nutrition in light, no diet necessary + oxy_mod = 0 + body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not blood_color = "#004400" flesh_color = "#907E4A" @@ -766,13 +769,13 @@ has_organ = list( "nutrient channel" = /obj/item/organ/internal/liver/diona, "neural strata" = /obj/item/organ/internal/heart/diona, - "receptor node" = /obj/item/organ/internal/diona_receptor, + "receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2. "gas bladder" = /obj/item/organ/internal/brain/diona, "polyp segment" = /obj/item/organ/internal/kidneys/diona, "anchoring ligament" = /obj/item/organ/internal/appendix/diona ) - vision_organ = /obj/item/organ/internal/diona_receptor + vision_organ = /obj/item/organ/internal/eyes/diona has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/diona), "groin" = list("path" = /obj/item/organ/external/groin/diona), @@ -803,8 +806,8 @@ return ..() /datum/species/diona/handle_life(var/mob/living/carbon/human/H) - var/rads = H.radiation/25 - H.radiation = Clamp(H.radiation - rads, 0, 100) + var/rads = H.radiation / 25 + H.apply_effect(-rads,IRRADIATE,0) H.nutrition += rads H.adjustBruteLoss(-(rads)) H.adjustOxyLoss(-(rads)) @@ -813,18 +816,23 @@ var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(H.loc)) //else, there's considered to be no light var/turf/T = H.loc - light_amount = min(T.get_lumcount()*10, 5) //hardcapped so it's not abused by having a ton of flashlights + light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights H.nutrition += light_amount H.traumatic_shock -= light_amount - if(H.nutrition > 450) - H.nutrition = 450 + if(H.nutrition > NUTRITION_LEVEL_WELL_FED) + H.nutrition = NUTRITION_LEVEL_WELL_FED + + if(light_amount > 0) + H.clear_alert("nolight") + else + H.throw_alert("nolight", /obj/screen/alert/nolight) if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal + H.adjustBruteLoss(-(light_amount/2)) H.adjustFireLoss(-(light_amount/4)) H.adjustOxyLoss(-(light_amount)) - if(H.nutrition < 200) H.take_overall_damage(10,0) H.traumatic_shock++ @@ -850,9 +858,12 @@ eyes = "blank_eyes" brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150% burn_mod = 2.5 // So they take 50% extra damage from brute/burn overall. + tox_mod = 0 + clone_mod = 0 + oxy_mod = 0 death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..." - flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA | NO_POISON | RADIMMUNE | ALL_RPARTS + flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | NO_DNA | RADIMMUNE | ALL_RPARTS| NOTRANSSTING clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY dietflags = 0 //IPCs can't eat, so no diet @@ -870,10 +881,10 @@ has_organ = list( "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, "cell" = /obj/item/organ/internal/cell, - "optics" = /obj/item/organ/internal/optical_sensor + "optics" = /obj/item/organ/internal/eyes/optical_sensor //Default darksight of 2. ) - vision_organ = /obj/item/organ/internal/optical_sensor + vision_organ = /obj/item/organ/internal/eyes/optical_sensor has_limbs = list( "chest" = list("path" = /obj/item/organ/external/chest/ipc), "groin" = list("path" = /obj/item/organ/external/groin/ipc), @@ -919,7 +930,6 @@ language = "Orluum" unarmed_type = /datum/unarmed_attack/punch eyes = "drask_eyes_s" - darksight = 5 speech_sounds = list('sound/voice/DraskTalk.ogg') speech_chance = 20 @@ -969,7 +979,7 @@ "heart" = /obj/item/organ/internal/heart/drask, "lungs" = /obj/item/organ/internal/lungs/drask, "metabolic strainer" = /obj/item/organ/internal/liver/drask, - "eyes" = /obj/item/organ/internal/eyes/drask, + "eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight. "brain" = /obj/item/organ/internal/brain/drask ) @@ -1007,4 +1017,4 @@ H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_2, BURN, "head", used_weapon = "Excessive Heat") if(heat_level_3_breathe to INFINITY) - H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") + H.apply_damage(hot_env_multiplier*HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm new file mode 100644 index 00000000000..5ca23f89f4f --- /dev/null +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -0,0 +1,19 @@ +/mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) + if(species) + amount = amount * species.stun_mod + ..() + +/mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0) + if(species) + amount = amount * species.stun_mod + ..() + +/mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0) + if(species) + amount = amount * species.stun_mod + ..() + +/mob/living/carbon/human/SetSleeping(amount, updating = 1) + if(species) + amount = amount * species.stun_mod + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index 634e9865e45..4952a4bd61b 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -264,8 +264,8 @@ playsound(loc, M.attack_sound, 50, 1, 1) visible_message("[M] [M.attacktext] [src]!", \ "[M] [M.attacktext] [src]!") - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + M.create_attack_log("attacked [src.name] ([src.ckey])") + src.create_attack_log("was attacked by [M.name] ([M.ckey])") var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) attacked += 10 adjustBruteLoss(damage) diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index 60e1cd82654..fac41aa66f7 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -147,69 +147,69 @@ action_icon_state = "spell_greytide" var/recruiting = 0 -/obj/effect/proc_holder/spell/targeted/recruit/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/recruit/cast(list/targets,mob/living/user = usr) for(var/mob/living/carbon/human/target in targets) var/obj/item/organ/external/head/head_organ = target.get_organ("head") if(ticker.mode.greyshirts.len >= 3) - to_chat(usr, "You have already recruited the maximum number of henchmen.") - if(!in_range(usr, target)) - to_chat(usr, "You need to be closer to enthrall [target].") + to_chat(user, "You have already recruited the maximum number of henchmen.") + if(!in_range(user, target)) + to_chat(user, "You need to be closer to enthrall [target].") charge_counter = charge_max return if(!target.ckey) - to_chat(usr, "The target has no mind.") + to_chat(user, "The target has no mind.") charge_counter = charge_max return if(target.stat) - to_chat(usr, "The target must be conscious.") + to_chat(user, "The target must be conscious.") charge_counter = charge_max return if(!ishuman(target)) - to_chat(usr, "You can only recruit humans.") + to_chat(user, "You can only recruit humans.") charge_counter = charge_max return if(target.mind.assigned_role != "Civilian") - to_chat(usr, "You can only recruit Civilians.") + to_chat(user, "You can only recruit Civilians.") if(recruiting) - to_chat(usr, "You are already recruiting!") + to_chat(user, "You are already recruiting!") charge_counter = charge_max return recruiting = 1 - to_chat(usr, "This target is valid. You begin the recruiting process.") - to_chat(target, "[usr] focuses in concentration. Your head begins to ache.") + to_chat(user, "This target is valid. You begin the recruiting process.") + to_chat(target, "[user] focuses in concentration. Your head begins to ache.") for(var/progress = 0, progress <= 3, progress++) switch(progress) if(1) - to_chat(usr, "You begin by introducing yourself and explaining what you're about.") - usr.visible_message("[usr]'s introduces himself and explains his plans.") + to_chat(user, "You begin by introducing yourself and explaining what you're about.") + user.visible_message("[user]'s introduces himself and explains his plans.") if(2) - to_chat(usr, "You begin the recruitment of [target].") - usr.visible_message("[usr] leans over towards [target], whispering excitedly as he gives a speech.") - to_chat(target, "You feel yourself agreeing with [usr], and a surge of loyalty begins building.") + to_chat(user, "You begin the recruitment of [target].") + user.visible_message("[user] leans over towards [target], whispering excitedly as he gives a speech.") + to_chat(target, "You feel yourself agreeing with [user], and a surge of loyalty begins building.") target.Weaken(12) sleep(20) if(isloyal(target)) - to_chat(usr, "They are enslaved by Nanotrasen. You feel their interest in your cause wane and disappear.") - usr.visible_message("[usr] stops talking for a moment, then moves back away from [target].") + to_chat(user, "They are enslaved by Nanotrasen. You feel their interest in your cause wane and disappear.") + user.visible_message("[user] stops talking for a moment, then moves back away from [target].") to_chat(target, "Your mindshield implant activates, protecting you from conversion.") return if(3) - to_chat(usr, "You begin filling out the application form with [target].") - usr.visible_message("[usr] pulls out a pen and paper and begins filling an application form with [target].") - to_chat(target, "You are being convinced by [usr] to fill out an application form to become a henchman.")//Ow the edge + to_chat(user, "You begin filling out the application form with [target].") + user.visible_message("[user] pulls out a pen and paper and begins filling an application form with [target].") + to_chat(target, "You are being convinced by [user] to fill out an application form to become a henchman.")//Ow the edge - if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a mindshield implant - to_chat(usr, "The enrollment process has been interrupted - you have lost the attention of [target].") - to_chat(target, "You move away and are no longer under the charm of [usr]. The application form is null and void.") + if(!do_mob(user, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a mindshield implant + to_chat(user, "The enrollment process has been interrupted - you have lost the attention of [target].") + to_chat(target, "You move away and are no longer under the charm of [user]. The application form is null and void.") recruiting = 0 return recruiting = 0 - to_chat(usr, "You have recruited [target] as your henchman!") - to_chat(target, "You have decided to enroll as a henchman for [usr]. You are now part of the feared 'Greyshirts'.") - to_chat(target, "You must follow the orders of [usr], and help him succeed in his dastardly schemes.") - to_chat(target, "You may not harm other Greyshirt or [usr]. However, you do not need to obey other Greyshirts.") + to_chat(user, "You have recruited [target] as your henchman!") + to_chat(target, "You have decided to enroll as a henchman for [user]. You are now part of the feared 'Greyshirts'.") + to_chat(target, "You must follow the orders of [user], and help him succeed in his dastardly schemes.") + to_chat(target, "You may not harm other Greyshirt or [user]. However, you do not need to obey other Greyshirts.") ticker.mode.greyshirts += target.mind target.set_species("Human") head_organ.h_style = "Bald" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 02013cdc8b5..2aff4a71d85 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,7 +1,14 @@ /mob/living/Destroy() - ..() - return QDEL_HINT_HARDDEL_NOW + if(ranged_ability) + ranged_ability.remove_ranged_ability(src) + return ..() + +/mob/living/ghostize(can_reenter_corpse = 1) + var/prev_client = client + if(..()) + if(ranged_ability && prev_client) + ranged_ability.remove_mousepointer(prev_client) /mob/living/proc/OpenCraftingMenu() return @@ -40,14 +47,14 @@ set category = "Object" if(AM.Adjacent(src)) - src.start_pulling(AM) + start_pulling(AM) return //same as above /mob/living/pointed(atom/A as mob|obj|turf in view()) if(incapacitated()) return 0 - if(src.status_flags & FAKEDEATH) + if(status_flags & FAKEDEATH) return 0 if(!..()) return 0 @@ -70,7 +77,7 @@ to_chat(src, "You have given up life and succumbed to death.") /mob/living/proc/InCritical() - return (src.health < 0 && src.health > -95.0 && stat == UNCONSCIOUS) + return (health < 0 && health > -95.0 && stat == UNCONSCIOUS) /mob/living/ex_act(severity) ..() @@ -106,7 +113,7 @@ if(actual < desired) temperature = desired // if(istype(src, /mob/living/carbon/human)) -// to_chat(world, "[src] ~ [src.bodytemperature] ~ [temperature]") +// to_chat(world, "[src] ~ [bodytemperature] ~ [temperature]") return temperature @@ -220,29 +227,31 @@ else - L += src.contents - for(var/obj/item/weapon/storage/S in src.contents) //Check for storage items + L += contents + for(var/obj/item/weapon/storage/S in contents) //Check for storage items L += get_contents(S) - for(var/obj/item/clothing/suit/storage/S in src.contents)//Check for labcoats and jackets + for(var/obj/item/clothing/suit/storage/S in contents)//Check for labcoats and jackets L += get_contents(S) - for(var/obj/item/clothing/accessory/storage/S in src.contents)//Check for holsters + for(var/obj/item/clothing/accessory/storage/S in contents)//Check for holsters L += get_contents(S) - for(var/obj/item/weapon/gift/G in src.contents) //Check for gift-wrapped items + for(var/obj/item/weapon/implant/storage/I in contents) //Check for storage implants. + L += I.get_contents() + for(var/obj/item/weapon/gift/G in contents) //Check for gift-wrapped items L += G.gift if(istype(G.gift, /obj/item/weapon/storage)) L += get_contents(G.gift) - for(var/obj/item/smallDelivery/D in src.contents) //Check for package wrapped items + for(var/obj/item/smallDelivery/D in contents) //Check for package wrapped items L += D.wrapped if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen L += get_contents(D.wrapped) - for(var/obj/item/weapon/folder/F in src.contents) + for(var/obj/item/weapon/folder/F in contents) L += F.contents //Folders can't store any storage items. return L /mob/living/proc/check_contents_for(A) - var/list/L = src.get_contents() + var/list/L = get_contents() for(var/obj/B in L) if(B.type == A) @@ -265,27 +274,27 @@ /mob/living/proc/heal_organ_damage(var/brute, var/burn) adjustBruteLoss(-brute) adjustFireLoss(-burn) - src.updatehealth() + updatehealth() // damage ONE external organ, organ gets randomly selected from damaged ones. /mob/living/proc/take_organ_damage(var/brute, var/burn) if(status_flags & GODMODE) return 0 //godmode adjustBruteLoss(brute) adjustFireLoss(burn) - src.updatehealth() + updatehealth() // heal MANY external organs, in random order /mob/living/proc/heal_overall_damage(var/brute, var/burn) adjustBruteLoss(-brute) adjustFireLoss(-burn) - src.updatehealth() + updatehealth() // damage MANY external organs, in random order /mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null) if(status_flags & GODMODE) return 0 //godmode adjustBruteLoss(brute) adjustFireLoss(burn) - src.updatehealth() + updatehealth() /mob/living/proc/has_organic_damage() return (maxHealth - health) @@ -337,7 +346,7 @@ SetDruggy(0) SetHallucinate(0) blinded = 0 - nutrition = 400 + nutrition = NUTRITION_LEVEL_FED + 50 bodytemperature = 310 CureBlind() CureNearsighted() @@ -359,7 +368,7 @@ if(buckled) //Unbuckle the mob and clear the alerts. buckled.buckled_mob = null buckled = null - anchored = initial(src.anchored) + anchored = initial(anchored) update_canmove() clear_alert("buckled") post_buckle_mob(src) @@ -642,12 +651,12 @@ who.unEquip(what) if(silent) put_in_hands(what) - add_logs(src, who, "stripped", addition="of [what]") + add_logs(src, who, "stripped", addition="of [what]", print_attack_log = isLivingSSD(who)) // The src mob is trying to place an item on someone // Override if a certain mob should be behave differently when placing items (can't, for example) /mob/living/stripPanelEquip(obj/item/what, mob/who, where, var/silent = 0) - what = src.get_active_hand() + what = get_active_hand() if(what && (what.flags & NODROP)) to_chat(src, "You can't put \the [what.name] on [who], it's stuck to your hand!") return @@ -661,7 +670,7 @@ if(what && Adjacent(who)) unEquip(what) who.equip_to_slot_if_possible(what, where, 0, 1) - add_logs(src, who, "equipped", what) + add_logs(src, who, "equipped", what, print_attack_log = isLivingSSD(who)) /mob/living/singularity_act() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 6b577e17f65..609d166183d 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -49,7 +49,12 @@ if(!P.nodamage) apply_damage(P.damage, P.damage_type, def_zone, armor) + if(P.dismemberment) + check_projectile_dismemberment(P, def_zone) return P.on_hit(src, armor, def_zone) + +/mob/living/proc/check_projectile_dismemberment(obj/item/projectile/P, def_zone) + return 0 /mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0) return 0 //only carbon liveforms have this proc @@ -86,8 +91,8 @@ if(ismob(I.thrower)) var/mob/M = I.thrower if(M) - attack_log += text("\[[time_stamp()]\] Has been hit with a [I], thrown by [key_name(M)]") - M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [I]") + create_attack_log("Has been hit with a [I], thrown by [key_name(M)]") + M.create_attack_log("Hit [key_name(src)] with a thrown [I]") if(!istype(src,/mob/living/simple_animal/mouse)) msg_admin_attack("[key_name_admin(src)] was hit by a [I], thrown by [key_name_admin(M)]") @@ -135,14 +140,14 @@ M.occupant_message("You hit [src].") visible_message("[src] has been hit by [M.name].", \ "[src] has been hit by [M.name].") - attack_log += text("\[[time_stamp()]\] Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])") - M.occupant.attack_log += text("\[[time_stamp()]\] Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") + create_attack_log("Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])") + M.occupant.create_attack_log("Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") msg_admin_attack("[key_name_admin(M.occupant)] attacked [key_name_admin(src)] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])") else step_away(src,M) - add_logs(M.occupant, src, "pushed", object=M, admin=0) + add_logs(M.occupant, src, "pushed", object=M, admin=0, print_attack_log = 0) M.occupant_message("You push [src] out of the way.") visible_message("[M] pushes [src] out of the way.") return diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index c3dab651906..e1488648731 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -32,6 +32,8 @@ var/implanting = 0 //Used for the mind-slave implant var/floating = 0 var/mob_size = MOB_SIZE_HUMAN + var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature.. + var/digestion_ratio = 1 //controls how quickly reagents metabolize; largely governered by species attributes. var/nightvision = 0 var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour @@ -50,3 +52,7 @@ var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them. var/gene_stability = DEFAULT_GENE_STABILITY + + var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override + + var/list/say_log = list() //a log of what we've said, plain text, no spans or junk, essentially just each individual "message" diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index a64126db27a..a2fc8e934cb 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -9,6 +9,10 @@ //Vents if(ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") + + if(ranged_ability) + ranged_ability.add_ranged_ability(src, "You currently have [ranged_ability] active!") + //Should update regardless of if we can ventcrawl, since we can end up in pipes in other ways. update_pipe_vision() diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index 10ba19b4302..6235aecf2c4 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,4 +1,6 @@ /mob/living/Logout() + if(ranged_ability && client) + ranged_ability.remove_mousepointer(client) ..() if(mind) if(!key) //key and mind have become seperated. I believe this is for when a staff member aghosts. diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d5a1580ded9..1e34b43e583 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -14,6 +14,7 @@ var/list/department_radio_keys = list( ":u" = "Supply", "#u" = "Supply", ".u" = "Supply", ":z" = "Service", "#z" = "Service", ".z" = "Service", ":p" = "AI Private", "#p" = "AI Private", ".p" = "AI Private", + ":x" = "cords", "#x" = "cords", ".x" = "cords", ":R" = "right ear", "#R" = "right ear", ".R" = "right ear", ":L" = "left ear", "#L" = "left ear", ".L" = "left ear", @@ -30,7 +31,8 @@ var/list/department_radio_keys = list( ":Z" = "Service", "#Z" = "Service", ".Z" = "Service", ":P" = "AI Private", "#P" = "AI Private", ".P" = "AI Private", ":-" = "Special Ops", "#-" = "Special Ops", ".-" = "Special Ops", - ":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam" + ":_" = "SyndTeam", "#_" = "SyndTeam", "._" = "SyndTeam", + ":X" = "cords", "#X" = "cords", ".X" = "cords" ) @@ -106,13 +108,14 @@ proc/get_radio_key_from_channel(var/channel) return returns -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/alt_name="") +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/alt_name = "", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE) if(client) if(client.prefs.muted & MUTE_IC) to_chat(src, "You cannot speak in IC (Muted).") return - message = trim_strip_html_properly(message) + if(sanitize) + message = trim_strip_html_properly(message) if(stat) if(stat == DEAD) @@ -147,6 +150,15 @@ proc/get_radio_key_from_channel(var/channel) speaking.broadcast(src,trim(message)) return 1 + if(message_mode == "cords") + if(iscarbon(src)) + var/mob/living/carbon/C = src + var/obj/item/organ/internal/vocal_cords/V = C.get_int_organ(/obj/item/organ/internal/vocal_cords) + if(V && V.can_speak_with()) + C.say(V.handle_speech(message), sanitize = FALSE, ignore_speech_problems = TRUE, ignore_atmospherics = TRUE) + V.speak_with(message) //words come before actions + return 1 + verb = say_quote(message, speaking) if(is_muzzled()) @@ -162,7 +174,7 @@ proc/get_radio_key_from_channel(var/channel) message = handle_autohiss(message, speaking) - if(speaking && !(speaking.flags & NO_STUTTER)) + if(!ignore_speech_problems && (speaking && !(speaking.flags & NO_STUTTER))) var/list/handle_s = handle_speech_problems(message, verb) message = handle_s[1] verb = handle_s[2] @@ -217,12 +229,13 @@ proc/get_radio_key_from_channel(var/channel) //make sure the air can transmit speech - speaker's side var/datum/gas_mixture/environment = T.return_air() var/pressure = environment ? environment.return_pressure() : 0 - if(pressure < SOUND_MINIMUM_PRESSURE) - message_range = 1 + if(!ignore_atmospherics) + if(pressure < SOUND_MINIMUM_PRESSURE) + message_range = 1 - if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet - italics = 1 - sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact + if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet + italics = 1 + sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact var/list/hear = hear(message_range, T) var/list/hearturfs = list() @@ -269,6 +282,9 @@ proc/get_radio_key_from_channel(var/channel) if(O) //It's possible that it could be deleted in the meantime. O.hear_talk(src, message, verb, speaking) + //Log of what we've said, plain message, no spans or junk + say_log += message + log_say("[name]/[key] : [message]") return 1 @@ -395,9 +411,22 @@ proc/get_radio_key_from_channel(var/channel) return var/atom/whisper_loc = get_whisper_loc() - var/list/listening = hearers(message_range, whisper_loc) + var/list/listening = hear(message_range, whisper_loc) listening |= src + var/list/hearturfs = list() + + //Pass whispers on to anything inside the immediate listeners. + // This comes before the ghosts do so that ghosts don't act as whisper relays + for(var/atom/L in listening) + if(ismob(L)) + for(var/mob/C in L.contents) + if(isliving(C)) + listening += C + hearturfs += get_turf(L) + if(isobj(L)) + hearturfs += get_turf(L) + //ghosts for(var/mob/M in dead_mob_list) //does this include players who joined as observers as well? if(!M.client) @@ -405,11 +434,14 @@ proc/get_radio_key_from_channel(var/channel) if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS)) listening |= M - //Pass whispers on to anything inside the immediate listeners. - for(var/mob/L in listening) - for(var/mob/C in L.contents) - if(isliving(C)) - listening += C + // This, in tandem with "hearturfs", lets nested mobs hear whispers that are in range + // Grifted from saycode above. + for(var/mob/M in player_list) + if(!M.client || isnewplayer(M)) + continue //skip monkeys and leavers + if(get_turf(M) in hearturfs) + listening |= M + //pass on the message to objects that can hear us. for(var/obj/O in view(message_range, whisper_loc)) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 00a141f60f8..3235c6899c1 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -99,22 +99,24 @@ var/list/ai_verbs_default = list( var/obj/machinery/camera/portable/builtInCamera + var/obj/structure/AIcore/deactivated/linked_core //For exosuit control + var/arrivalmsg = "$name, $rank, has arrived on the station." /mob/living/silicon/ai/proc/add_ai_verbs() - src.verbs |= ai_verbs_default - src.verbs |= silicon_subsystems + verbs |= ai_verbs_default + verbs |= silicon_subsystems /mob/living/silicon/ai/proc/remove_ai_verbs() - src.verbs -= ai_verbs_default - src.verbs -= silicon_subsystems + verbs -= ai_verbs_default + verbs -= silicon_subsystems /mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0) announcement = new() announcement.title = "A.I. Announcement" announcement.announcement_type = "A.I. Announcement" announcement.announcer = name - announcement.newscast = 1 + announcement.newscast = 0 var/list/possibleNames = ai_names @@ -154,7 +156,7 @@ var/list/ai_verbs_default = list( aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src) - if(istype(loc, /turf)) + if(isturf(loc)) add_ai_verbs(src) //Languages @@ -226,7 +228,7 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/rename_character(oldname, newname) if(!..(oldname, newname)) - return 0 + return FALSE if(oldname != real_name) announcement.announcer = name @@ -238,7 +240,7 @@ var/list/ai_verbs_default = list( if(aiPDA) aiPDA.set_name_and_job(newname, "AI") - return 1 + return TRUE /mob/living/silicon/ai/Destroy() ai_list -= src @@ -261,7 +263,7 @@ var/list/ai_verbs_default = list( var/mob/living/silicon/ai/powered_ai = null invisibility = 100 -/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai=null) +/obj/machinery/ai_powersupply/New(mob/living/silicon/ai/ai=null) powered_ai = ai if(isnull(powered_ai)) qdel(src) @@ -307,31 +309,83 @@ var/list/ai_verbs_default = list( //if(icon_state == initial(icon_state)) var/icontype = "" - if(custom_sprite == 1) icontype = ("Custom")//automagically selects custom sprite if one is available - else icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Blue", "Clown", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Red October", "Sparkles", "ANIMA", "President", "NT") + if(custom_sprite == 1) + icontype = ("Custom")//automagically selects custom sprite if one is available + else + icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Blue", "Clown", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Red October", "Sparkles", "ANIMA", "President", "NT", "NT2", "Rainbow", "Angel", "Heartline", "Hades", "Helios", "Syndicat Meow", "Too Deep", "Goon", "Murica", "Fuzzy", "Glitchman", "House", "Database") switch(icontype) - if("Custom") icon_state = "[ckey]-ai" - if("Clown") icon_state = "ai-clown2" - if("Monochrome") icon_state = "ai-mono" - if("Inverted") icon_state = "ai-u" - if("Firewall") icon_state = "ai-magma" - if("Green") icon_state = "ai-wierd" - if("Red") icon_state = "ai-red" - if("Static") icon_state = "ai-static" - if("Text") icon_state = "ai-text" - if("Smiley") icon_state = "ai-smiley" - if("Matrix") icon_state = "ai-matrix" - if("Angry") icon_state = "ai-angryface" - if("Dorf") icon_state = "ai-dorf" - if("Bliss") icon_state = "ai-bliss" - if("Triumvirate") icon_state = "ai-triumvirate" - if("Triumvirate Static") icon_state = "ai-triumvirate-malf" - if("Red October") icon_state = "ai-redoctober" - if("Sparkles") icon_state = "ai-sparkles" - if("ANIMA") icon_state = "ai-anima" - if("President") icon_state = "ai-president" - if("NT") icon_state = "ai-nt" - else icon_state = "ai" + if("Custom") + icon_state = "[ckey]-ai" + if("Clown") + icon_state = "ai-clown" + if("Monochrome") + icon_state = "ai-mono" + if("Inverted") + icon_state = "ai-u" + if("Firewall") + icon_state = "ai-magma" + if("Green") + icon_state = "ai-weird" + if("Red") + icon_state = "ai-red" + if("Static") + icon_state = "ai-static" + if("Text") + icon_state = "ai-text" + if("Smiley") + icon_state = "ai-smiley" + if("Matrix") + icon_state = "ai-matrix" + if("Angry") + icon_state = "ai-angryface" + if("Dorf") + icon_state = "ai-dorf" + if("Bliss") + icon_state = "ai-bliss" + if("Triumvirate") + icon_state = "ai-triumvirate" + if("Triumvirate Static") + icon_state = "ai-triumvirate-malf" + if("Red October") + icon_state = "ai-redoctober" + if("Sparkles") + icon_state = "ai-sparkles" + if("ANIMA") + icon_state = "ai-anima" + if("President") + icon_state = "ai-president" + if("NT") + icon_state = "ai-nt" + if("NT2") + icon_state = "ai-nanotrasen" + if("Rainbow") + icon_state = "ai-rainbow" + if("Angel") + icon_state = "ai-angel" + if("Heartline") + icon_state = "ai-heartline" + if("Hades") + icon_state = "ai-hades" + if("Helios") + icon_state = "ai-helios" + if("Syndicat Meow") + icon_state = "ai-syndicatmeow" + if("Too Deep") + icon_state = "ai-toodeep" + if("Goon") + icon_state = "ai-goon" + if("Murica") + icon_state = "ai-murica" + if("Fuzzy") + icon_state = "ai-fuzz" + if("Glitchman") + icon_state = "ai-glitchman" + if("House") + icon_state = "ai-house" + if("Database") + icon_state = "ai-database" + else + icon_state = "ai" //else // to_chat(usr, "You can only change your display once!") //return @@ -400,7 +454,7 @@ var/list/ai_verbs_default = list( cancel_call_proc(src) /mob/living/silicon/ai/cancel_camera() - src.view_core() + view_core() /mob/living/silicon/ai/verb/toggle_anchor() set category = "AI Commands" @@ -414,7 +468,7 @@ var/list/ai_verbs_default = list( to_chat(src, "[anchored ? "You are now anchored." : "You are now unanchored."]") /mob/living/silicon/ai/update_canmove() - return 0 + return FALSE /mob/living/silicon/ai/proc/announcement() set name = "Announcement" @@ -426,21 +480,21 @@ var/list/ai_verbs_default = list( ai_announcement() -/mob/living/silicon/ai/check_eye(var/mob/user as mob) +/mob/living/silicon/ai/check_eye(mob/user) if(!current) return null user.reset_perspective(current) - return 1 + return TRUE /mob/living/silicon/ai/blob_act() if(stat != 2) adjustBruteLoss(60) updatehealth() - return 1 - return 0 + return TRUE + return FALSE /mob/living/silicon/ai/restrained() - return 0 + return FALSE /mob/living/silicon/ai/emp_act(severity) if(prob(30)) @@ -516,7 +570,7 @@ var/list/ai_verbs_default = list( if(href_list["callbot"]) //Command a bot to move to a selected location. Bot = locate(href_list["callbot"]) in simple_animal_list - if(!Bot || Bot.remote_disabled || src.control_disabled) + if(!Bot || Bot.remote_disabled || control_disabled) return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off. waypoint_mode = 1 to_chat(src, "Set your waypoint by clicking on a valid location free of obstructions.") @@ -524,7 +578,7 @@ var/list/ai_verbs_default = list( if(href_list["interface"]) //Remotely connect to a bot! Bot = locate(href_list["interface"]) in simple_animal_list - if(!Bot || Bot.remote_disabled || src.control_disabled) + if(!Bot || Bot.remote_disabled || control_disabled) return Bot.attack_ai(src) @@ -535,7 +589,16 @@ var/list/ai_verbs_default = list( if(href_list["ai_take_control"]) //Mech domination var/obj/mecha/M = locate(href_list["ai_take_control"]) if(controlled_mech) - to_chat(src, "You are already loaded into an onboard computer!") + to_chat(src, "You are already loaded into an onboard computer!") + return + if(!cameranet.checkCameraVis(M)) + to_chat(src, "Exosuit is no longer near active cameras.") + return + if(lacks_power()) + to_chat(src, "You're depowered!") + return + if(!isturf(loc)) + to_chat(src, "You aren't in your core!") return if(M) M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself. @@ -550,7 +613,7 @@ var/list/ai_verbs_default = list( if(usr.machine == null) usr.machine = usr - while(src.cameraFollow == target) + while(cameraFollow == target) to_chat(usr, "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb).") sleep(40) continue @@ -565,12 +628,12 @@ var/list/ai_verbs_default = list( return 2 -/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M as mob) +/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M) if(!ticker) to_chat(M, "You cannot attack people before the game has started.") return - if(istype(loc, /turf) && istype(loc.loc, /area/start)) + if(isturf(loc) && istype(loc.loc, /area/start)) to_chat(M, "No attacking people at spawn, you jackass.") return @@ -595,7 +658,7 @@ var/list/ai_verbs_default = list( return -/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M as mob) +/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M) if(M.melee_damage_upper == 0) M.custom_emote(1, "[M.friendly] [src]") else @@ -603,7 +666,7 @@ var/list/ai_verbs_default = list( if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) visible_message("[M] [M.attacktext] [src]!") - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) updatehealth() @@ -653,7 +716,7 @@ var/list/ai_verbs_default = list( popup.set_content(d) popup.open() -/mob/living/silicon/ai/proc/set_waypoint(var/atom/A) +/mob/living/silicon/ai/proc/set_waypoint(atom/A) var/turf/turf_check = get_turf(A) //The target must be in view of a camera or near the core. if(turf_check in range(get_turf(src))) @@ -663,7 +726,7 @@ var/list/ai_verbs_default = list( else to_chat(src, "Selected location is not visible.") -/mob/living/silicon/ai/proc/call_bot(var/turf/waypoint) +/mob/living/silicon/ai/proc/call_bot(turf/waypoint) if(!Bot) return @@ -674,22 +737,22 @@ var/list/ai_verbs_default = list( Bot.call_bot(src, waypoint) -/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C) +/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C) if(!tracking) cameraFollow = null if(!C || stat == DEAD) //C.can_use()) - return 0 + return FALSE - if(!src.eyeobj) + if(!eyeobj) view_core() return // ok, we're alive, camera is good and in our network... eyeobj.setLoc(get_turf(C)) //machine = src - return 1 + return TRUE //Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm //Adds in /mob/living/silicon/ai/proc/ai_network_change() instead @@ -920,7 +983,7 @@ var/list/ai_verbs_default = list( set category = "Malfunction" set name = "Return to Main Core" - var/obj/machinery/power/apc/apc = src.loc + var/obj/machinery/power/apc/apc = loc if(!istype(apc)) to_chat(src, "\blue You are already in your Main Core.") return @@ -994,7 +1057,7 @@ var/list/ai_verbs_default = list( lit_cameras |= C -/mob/living/silicon/ai/attackby(obj/item/weapon/W as obj, mob/user as mob, params) +/mob/living/silicon/ai/attackby(obj/item/weapon/W, mob/user, params) if(istype(W, /obj/item/weapon/wrench)) if(anchored) user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...") @@ -1025,14 +1088,15 @@ var/list/ai_verbs_default = list( return to_chat(src, "Accessing Subspace Transceiver control...") - if(src.aiRadio) - src.aiRadio.interact(src) + if(aiRadio) + aiRadio.interact(src) -/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target as mob) - if(!istype(target)) return +/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target) + if(!istype(target)) + return spawn(0) - if(istype(target, /mob/living/carbon/human)) + if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/weapon/card/id/id = H.wear_id if(istype(id) && id.is_untrackable()) @@ -1047,7 +1111,8 @@ var/list/ai_verbs_default = list( var/obj/machinery/door/airlock/tobeopened var/dist = -1 for(var/obj/machinery/door/airlock/D in range(3,target)) - if(!D.density) continue + if(!D.density) + continue if(dist < 0) dist = get_dist(D, target) // to_chat(world, dist) @@ -1073,27 +1138,27 @@ var/list/ai_verbs_default = list( return -/mob/living/silicon/ai/proc/check_unable(var/flags = 0) +/mob/living/silicon/ai/proc/check_unable(flags = 0) if(stat == DEAD) to_chat(usr, "You are dead!") - return 1 + return TRUE if(lacks_power()) to_chat(usr, "Power systems failure!") - return 1 + return TRUE - if((flags & AI_CHECK_WIRELESS) && src.control_disabled) + if((flags & AI_CHECK_WIRELESS) && control_disabled) to_chat(usr, "Wireless control is disabled!") - return 1 - if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi) + return TRUE + if((flags & AI_CHECK_RADIO) && aiRadio.disabledAi) to_chat(src, "System Error - Transceiver Disabled!") - return 1 - return 0 + return TRUE + return FALSE /mob/living/silicon/ai/proc/is_in_chassis() - return istype(loc, /turf) + return isturf(loc) -/mob/living/silicon/ai/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card) +/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) if(!..()) return if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card. @@ -1114,17 +1179,17 @@ var/list/ai_verbs_default = list( set category = "IC" resting = 0 - var/obj/item/weapon/rig/rig = src.get_rig() + var/obj/item/weapon/rig/rig = get_rig() if(rig) rig.force_rest(src) -/mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C) +/mob/living/silicon/ai/switch_to_camera(obj/machinery/camera/C) if(!C.can_use() || !is_in_chassis()) - return 0 + return FALSE eyeobj.setLoc(get_turf(C)) client.eye = eyeobj - return 1 + return TRUE /mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking) if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 1c977296a8a..9947e6faeec 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -1,9 +1,13 @@ /mob/living/silicon/ai/death(gibbed) - if(stat == DEAD) return + if(stat == DEAD) + return stat = DEAD - if(src.custom_sprite == 1)//check for custom AI sprite, defaulting to blue screen if no. - icon_state = "[ckey]-ai-crash" - else icon_state = "ai-crash" + if(custom_sprite == 1)//check for custom AI sprite, defaulting to blue screen if no. + icon_state = "[ckey]-ai_dead" + else if("[icon_state]_dead" in icon_states(icon,1)) + icon_state = "[icon_state]_dead" + else + icon_state = "ai_dead" update_canmove() if(eyeobj) eyeobj.setLoc(get_turf(src)) diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm index 92055b813ab..41d4c67427d 100644 --- a/code/modules/mob/living/silicon/pai/death.dm +++ b/code/modules/mob/living/silicon/pai/death.dm @@ -24,6 +24,5 @@ //Read as: I have no idea what I'm doing but asking for help got me nowhere so this is what you get. - Nodrak if(mind) qdel(mind) living_mob_list -= src - ghostize() if(icon_state != "[chassis]_dead" || cleanWipe) qdel(src) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index d0aeb8b9fa7..a81dae5234a 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -114,6 +114,11 @@ C.toff = 1 ..() +/mob/living/silicon/pai/update_icons() + if(stat == DEAD) + icon_state = "[chassis]_dead" + else + icon_state = resting ? "[chassis]_rest" : "[chassis]" // this function shows the information about being silenced as a pAI in the Status panel /mob/living/silicon/pai/proc/show_silenced() @@ -214,8 +219,8 @@ playsound(loc, M.attack_sound, 50, 1, 1) for(var/mob/O in viewers(src, null)) O.show_message("[M] [M.attacktext] [src]!", 1) - M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") + M.create_attack_log("attacked [src.name] ([src.ckey])") + src.create_attack_log("was attacked by [M.name] ([M.ckey])") var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) adjustBruteLoss(damage) updatehealth() @@ -420,17 +425,17 @@ set category = "IC" // Pass lying down or getting up to our pet human, if we're in a rig. - if(istype(src.loc,/obj/item/device/paicard)) + if(stat == CONSCIOUS && istype(src.loc,/obj/item/device/paicard)) resting = 0 var/obj/item/weapon/rig/rig = src.get_rig() if(istype(rig)) rig.force_rest(src) else resting = !resting - icon_state = resting ? "[chassis]_rest" : "[chassis]" to_chat(src, "You are now [resting ? "resting" : "getting up"]") - canmove = !resting + update_icons() + update_canmove() //Overriding this will stop a number of headaches down the track. /mob/living/silicon/pai/attackby(obj/item/weapon/W as obj, mob/user as mob, params) diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 5bb3cf3b645..ff0bcacd903 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -28,6 +28,9 @@ var/datum/paiController/paiController // Global handler for pAI candidates if("signup" in href_list) var/mob/dead/observer/O = locate(href_list["signup"]) if(!O) return + if(!(O in respawnable_list)) + to_chat(O, "You've given up your ability to respawn!") + return if(!check_recruit(O)) return recruitWindow(O) return @@ -361,6 +364,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates return 0 if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) return 0 + if(!(O in respawnable_list)) + return 0 if(O.client) return 1 return 0 diff --git a/code/modules/mob/living/silicon/pai/say.dm b/code/modules/mob/living/silicon/pai/say.dm index 1acb470773a..722e3b632ea 100644 --- a/code/modules/mob/living/silicon/pai/say.dm +++ b/code/modules/mob/living/silicon/pai/say.dm @@ -6,8 +6,11 @@ /mob/living/silicon/pai/get_whisper_loc() if(loc == card) // currently in its card? - if(istype(card.loc, /mob/living)) - return card.loc // allow a pai being held or in pocket to whisper + var/atom/movable/whisper_loc = card + if(istype(card.loc, /obj/item/device/pda)) // Step up 1 level if in a PDA + whisper_loc = card.loc + if(istype(whisper_loc.loc, /mob/living)) + return whisper_loc.loc // allow a pai being held or in pocket to whisper else - return card // allow a pai in its card to whisper - return ..() \ No newline at end of file + return whisper_loc // allow a pai in its card to whisper + return ..() 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 7a7cfa45efa..3df660dc117 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -51,7 +51,7 @@ /obj/item/weapon/gripper/verb/drop_item() - set name = "Drop Item" + set name = "Drop Gripped Item" set desc = "Release an item from your magnetic gripper." set category = "Drone" diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 4e05ff4a402..cf5a44884d1 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -14,10 +14,6 @@ return 0 O.mouse_opacity = 2 - if(istype(O,/obj/item/borg/sight)) - var/obj/item/borg/sight/S = O - sight_mode &= ~S.sight_mode - update_sight() if(client) client.screen -= O @@ -53,7 +49,6 @@ if((cell.charge * 100 / cell.maxcharge) < B.powerneeded) to_chat(src, "Not enough power to activate [B.name]!") return - var/activated_thingy = null if(!module_state_1) O.mouse_opacity = initial(O.mouse_opacity) module_state_1 = O @@ -61,7 +56,6 @@ O.plane = HUD_PLANE O.screen_loc = inv1.screen_loc contents += O - activated_thingy = O else if(!module_state_2) O.mouse_opacity = initial(O.mouse_opacity) module_state_2 = O @@ -69,7 +63,6 @@ O.plane = HUD_PLANE O.screen_loc = inv2.screen_loc contents += O - activated_thingy = O else if(!module_state_3) O.mouse_opacity = initial(O.mouse_opacity) module_state_3 = O @@ -77,11 +70,8 @@ O.plane = HUD_PLANE O.screen_loc = inv3.screen_loc contents += O - activated_thingy = O else to_chat(src, "You need to disable a module first!") - if(istype(activated_thingy,/obj/item/borg/sight)) - update_sight() update_icons() /mob/living/silicon/robot/proc/uneq_active() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 02d3401c080..2840e7b381c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -86,6 +86,7 @@ var/list/robot_verbs_default = list( var/datum/effect/system/ion_trail_follow/ion_trail // Ionpulse effect. var/datum/action/item_action/toggle_research_scanner/scanner = null + var/list/module_actions = list() /mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0) spark_system = new /datum/effect/system/spark_spread() @@ -371,7 +372,7 @@ var/list/robot_verbs_default = list( //languages module.add_languages(src) //subsystems - module.add_subsystems(src) + module.add_subsystems_and_actions(src) //Custom_sprite check and entry if(custom_sprite == 1) @@ -920,7 +921,7 @@ var/list/robot_verbs_default = list( if(M.attack_sound) playsound(loc, M.attack_sound, 50, 1, 1) visible_message("[M] [M.attacktext] [src]!") - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) switch(M.melee_damage_type) if(BRUTE) @@ -976,21 +977,17 @@ var/list/robot_verbs_default = list( else overlays -= "eyes" - if(opened && custom_sprite == 1) //Custom borgs also have custom panels, heh - if(wiresexposed) - overlays += "[src.ckey]-openpanel +w" - else if(cell) - overlays += "[src.ckey]-openpanel +c" - else - overlays += "[src.ckey]-openpanel -c" - if(opened) + var/panelprefix = "ov" + if(custom_sprite) //Custom borgs also have custom panels, heh + panelprefix = "[ckey]" + if(wiresexposed) - overlays += "ov-openpanel +w" + overlays += "[panelprefix]-openpanel +w" else if(cell) - overlays += "ov-openpanel +c" + overlays += "[panelprefix]-openpanel +c" else - overlays += "ov-openpanel -c" + overlays += "[panelprefix]-openpanel -c" var/combat = list("Combat","Peacekeeper") if(modtype in combat) @@ -1424,7 +1421,7 @@ var/list/robot_verbs_default = list( //languages module.add_languages(src) //subsystems - module.add_subsystems(src) + module.add_subsystems_and_actions(src) status_flags &= ~CANPUSH @@ -1443,7 +1440,7 @@ var/list/robot_verbs_default = list( //languages module.add_languages(src) //subsystems - module.add_subsystems(src) + module.add_subsystems_and_actions(src) status_flags &= ~CANPUSH @@ -1467,4 +1464,4 @@ var/list/robot_verbs_default = list( borked_part.installed = 1 borked_part.wrapped = new borked_part.external_type borked_part.heal_damage(brute,burn) - borked_part.install() \ No newline at end of file + borked_part.install() diff --git a/code/modules/mob/living/silicon/robot/robot_module_actions.dm b/code/modules/mob/living/silicon/robot/robot_module_actions.dm new file mode 100644 index 00000000000..e7ef9961a95 --- /dev/null +++ b/code/modules/mob/living/silicon/robot/robot_module_actions.dm @@ -0,0 +1,37 @@ +/datum/action/innate/robot_sight + var/sight_mode = null + icon_icon = 'icons/obj/decals.dmi' + button_icon_state = "securearea" + +/datum/action/innate/robot_sight/Activate() + var/mob/living/silicon/robot/R = owner + R.sight_mode |= sight_mode + R.update_sight() + active = 1 + +/datum/action/innate/robot_sight/Deactivate() + var/mob/living/silicon/robot/R = owner + R.sight_mode &= ~sight_mode + R.update_sight() + active = 0 + +/datum/action/innate/robot_sight/xray + name = "X-ray Vision" + sight_mode = BORGXRAY + +/datum/action/innate/robot_sight/thermal + name = "Thermal Vision" + sight_mode = BORGTHERM + icon_icon = 'icons/obj/clothing/glasses.dmi' + button_icon_state = "thermal" + +// ayylmao +/datum/action/innate/robot_sight/thermal/alien + icon_icon = 'icons/mob/alien.dmi' + button_icon_state = "borg-extra-vision" + +/datum/action/innate/robot_sight/meson + name = "Meson Vision" + sight_mode = BORGMESON + icon_icon = 'icons/obj/clothing/glasses.dmi' + button_icon_state = "meson" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index d99bad202d7..152ed03fec8 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -9,6 +9,7 @@ var/list/modules = list() var/obj/item/emag = null var/list/subsystems = list() + var/list/module_actions = list() var/module_type = "NoMod" // For icon usage @@ -92,11 +93,19 @@ R.add_language("Orluum", 0) R.add_language("Clownish",0) -/obj/item/weapon/robot_module/proc/add_subsystems(mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/proc/add_subsystems_and_actions(mob/living/silicon/robot/R) R.verbs |= subsystems + for(var/A in module_actions) + var/datum/action/act = new A() + act.Grant(R) + R.module_actions += act -/obj/item/weapon/robot_module/proc/remove_subsystems(mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/proc/remove_subsystems_and_actions(mob/living/silicon/robot/R) R.verbs -= subsystems + for(var/datum/action/A in R.module_actions) + A.Remove(R) + qdel(A) + R.module_actions.Cut() /obj/item/weapon/robot_module/standard name = "standard robot module" @@ -166,6 +175,9 @@ name = "engineering robot module" module_type = "Engineer" subsystems = list(/mob/living/silicon/proc/subsystem_power_monitor) + module_actions = list( + /datum/action/innate/robot_sight/meson, + ) stacktypes = list( /obj/item/stack/sheet/metal/cyborg = 50, @@ -178,7 +190,6 @@ /obj/item/weapon/robot_module/engineering/New() ..() - modules += new /obj/item/borg/sight/meson(src) modules += new /obj/item/weapon/rcd/borg(src) modules += new /obj/item/weapon/extinguisher(src) modules += new /obj/item/weapon/weldingtool/largetank/cyborg(src) @@ -193,7 +204,7 @@ modules += new /obj/item/weapon/gripper(src) modules += new /obj/item/weapon/matter_decompiler(src) modules += new /obj/item/device/floor_painter(src) - + modules += new /obj/item/areaeditor/blueprints/cyborg(src) emag = new /obj/item/borg/stun(src) for(var/G in stacktypes) //Attempt to unify Engi-Borg material stacks into fewer lines. See Line 492 for example. Variables changed out of paranoia. @@ -297,10 +308,12 @@ /obj/item/weapon/robot_module/miner name = "miner robot module" module_type = "Miner" + module_actions = list( + /datum/action/innate/robot_sight/meson, + ) /obj/item/weapon/robot_module/miner/New() ..() - modules += new /obj/item/borg/sight/meson(src) modules += new /obj/item/weapon/storage/bag/ore/cyborg(src) modules += new /obj/item/weapon/pickaxe/drill/cyborg(src) modules += new /obj/item/weapon/shovel(src) @@ -317,10 +330,12 @@ /obj/item/weapon/robot_module/deathsquad name = "NT advanced combat module" module_type = "Malf" + module_actions = list( + /datum/action/innate/robot_sight/thermal, + ) /obj/item/weapon/robot_module/deathsquad/New() ..() - modules += new /obj/item/borg/sight/thermal(src) modules += new /obj/item/weapon/melee/energy/sword/cyborg(src) modules += new /obj/item/weapon/gun/energy/pulse/cyborg(src) modules += new /obj/item/weapon/crowbar(src) @@ -385,11 +400,13 @@ /obj/item/weapon/robot_module/combat name = "combat robot module" module_type = "Malf" + module_actions = list( + /datum/action/innate/robot_sight/thermal, + ) /obj/item/weapon/robot_module/combat/New() ..() modules += new /obj/item/weapon/restraints/handcuffs/cable/zipties/cyborg(src) - modules += new /obj/item/borg/sight/thermal(src) modules += new /obj/item/weapon/gun/energy/gun/cyborg(src) modules += new /obj/item/weapon/pickaxe/drill/jackhammer(src) modules += new /obj/item/borg/combat/shield(src) @@ -418,11 +435,13 @@ /obj/item/weapon/robot_module/alien/hunter name = "alien hunter module" module_type = "Standard" + module_actions = list( + /datum/action/innate/robot_sight/thermal/alien, + ) /obj/item/weapon/robot_module/alien/hunter/New() modules += new /obj/item/weapon/melee/energy/alien/claws(src) modules += new /obj/item/device/flash/cyborg/alien(src) - modules += new /obj/item/borg/sight/thermal/alien(src) var/obj/item/weapon/reagent_containers/spray/alien/stun/S = new /obj/item/weapon/reagent_containers/spray/alien/stun(src) S.reagents.add_reagent("ether",250) //nerfed to sleeptoxin to make it less instant drop. modules += S diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 48f75ede66d..3ac858a8a6c 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -254,7 +254,7 @@ return apply_damage(M.melee_damage_upper, BRUTE) visible_message("[M] has [M.attacktext] [src]!") - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) if(prob(10)) new /obj/effect/decal/cleanable/blood/oil(loc) @@ -788,6 +788,7 @@ Pass a positive integer as an argument to override a bot's default speed. frustration = 0 /mob/living/simple_animal/bot/show_inv() + return /mob/living/simple_animal/bot/proc/show_controls(mob/M) users |= M @@ -1010,4 +1011,4 @@ Pass a positive integer as an argument to override a bot's default speed. throw_alert("temp", /obj/screen/alert/cold/robot, 2) /mob/living/simple_animal/bot/is_mechanical() - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index fb128acdbfe..3f60793de02 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -143,7 +143,7 @@ target_types += /obj/effect/decal/cleanable/blood/gibs/robot target_types += /obj/effect/decal/cleanable/crayon target_types += /obj/effect/decal/cleanable/liquid_fuel - target_types += /obj/effect/decal/cleanable/molten_item + target_types += /obj/effect/decal/cleanable/molten_object target_types += /obj/effect/decal/cleanable/tomato_smudge target_types += /obj/effect/decal/cleanable/egg_smudge target_types += /obj/effect/decal/cleanable/pie_smudge diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 5f1418fcae5..fd1b35efeca 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -29,10 +29,17 @@ /mob/living/simple_animal/hostile/construct/New() ..() - name = "[ticker.mode.cultdat.get_name(const_type)] ([rand(1, 1000)])" - real_name = ticker.mode.cultdat.get_name(const_type) - icon_living = ticker.mode.cultdat.get_icon(const_type) - icon_state = ticker.mode.cultdat.get_icon(const_type) + if(!ticker.mode)//work around for maps with runes and cultdat is not loaded all the way + name = "[const_type] ([rand(1, 1000)])" + real_name = const_type + icon_living = const_type + icon_state = const_type + else + name = "[ticker.mode.cultdat.get_name(const_type)] ([rand(1, 1000)])" + real_name = ticker.mode.cultdat.get_name(const_type) + icon_living = ticker.mode.cultdat.get_icon(const_type) + icon_state = ticker.mode.cultdat.get_icon(const_type) + for(var/spell in construct_spells) AddSpell(new spell(null)) diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm new file mode 100644 index 00000000000..c0f7efca2c6 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm @@ -0,0 +1,51 @@ +/mob/living/simple_animal/cockroach + name = "cockroach" + desc = "This station is just crawling with bugs." + icon_state = "cockroach" + icon_dead = "cockroach" + health = 1 + maxHealth = 1 + turns_per_move = 5 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 270 + maxbodytemp = INFINITY + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + mob_size = MOB_SIZE_TINY + response_help = "pokes" + response_disarm = "shoos" + response_harm = "splats" + density = 0 + ventcrawler = 2 + gold_core_spawnable = 2 + var/squish_chance = 50 + loot = list(/obj/effect/decal/cleanable/deadcockroach) + del_on_death = 1 + +/mob/living/simple_animal/cockroach/death(gibbed) + if(ticker.cinematic) //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes. + return + ..() + +/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM) + if(isliving(AM)) + var/mob/living/A = AM + if(A.mob_size > MOB_SIZE_SMALL) + if(prob(squish_chance)) + A.visible_message("\The [A] squashed \the [name].", "You squashed \the [name].") + death() + else + visible_message("\The [name] avoids getting crushed.") + else if(istype(AM, /obj/structure)) + visible_message("As \the [AM] moved over \the [name], it was crushed.") + death() + +/mob/living/simple_animal/cockroach/ex_act() //Explosions are a terrible way to handle a cockroach. + return + +/obj/effect/decal/cleanable/deadcockroach + name = "cockroach guts" + desc = "One bug squashed. Four more will rise in its place." + icon = 'icons/effects/blood.dmi' + icon_state = "xfloor1" + random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") + anchored = 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 2f45d3e802e..dfc0bce32a3 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -58,7 +58,7 @@ dat += "
Back:[(inventory_back && !(inventory_back.flags&ABSTRACT)) ? inventory_back : "Empty"]
 
Collar:[(collar && !(collar.flags&ABSTRACT)) ? collar : "Empty"]
Collar:[(collar && !(collar.flags&ABSTRACT)) ? collar : "Empty"]
Close diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index 3161399a66e..e6e9d2f93f1 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -47,17 +47,17 @@ real_name = name add_language("Rootspeak") - src.verbs += /mob/living/simple_animal/diona/proc/merge + verbs += /mob/living/simple_animal/diona/proc/merge -/mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M as mob) +/mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M) //Let people pick the little buggers up. if(M.a_intent == I_HELP) if(M.species && M.species.name == "Diona") to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.") to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.") - src.verbs += /mob/living/simple_animal/diona/proc/split - src.verbs -= /mob/living/simple_animal/diona/proc/merge - src.forceMove(M) + verbs += /mob/living/simple_animal/diona/proc/split + verbs -= /mob/living/simple_animal/diona/proc/merge + forceMove(M) else get_scooped(M) @@ -68,32 +68,34 @@ set name = "Merge with gestalt" set desc = "Merge with another diona." - if(istype(src.loc,/mob/living/carbon)) - src.verbs -= /mob/living/simple_animal/diona/proc/merge + if(iscarbon(loc)) + verbs -= /mob/living/simple_animal/diona/proc/merge return var/list/choices = list() for(var/mob/living/carbon/C in view(1,src)) - if(!(src.Adjacent(C)) || !(C.client)) continue + if(!(Adjacent(C)) || !(C.client)) + continue - if(istype(C,/mob/living/carbon/human)) + if(ishuman(C)) var/mob/living/carbon/human/D = C if(D.species && D.species.name == "Diona") choices += C var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices - if(!M || !src || !(src.Adjacent(M))) return + if(!M || !src || !(Adjacent(M))) + return - if(istype(M,/mob/living/carbon/human)) + if(ishuman(M)) to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.") M.status_flags |= PASSEMOTES to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.") - src.loc = M - src.verbs += /mob/living/simple_animal/diona/proc/split - src.verbs -= /mob/living/simple_animal/diona/proc/merge + forceMove(M) + verbs += /mob/living/simple_animal/diona/proc/split + verbs -= /mob/living/simple_animal/diona/proc/merge else return @@ -102,61 +104,25 @@ set name = "Split from gestalt" set desc = "Split away from your gestalt as a lone nymph." - if(!(istype(src.loc,/mob/living/carbon))) - src.verbs -= /mob/living/simple_animal/diona/proc/split + if(!(iscarbon(loc))) + verbs -= /mob/living/simple_animal/diona/proc/split return - to_chat(src.loc, "You feel a pang of loss as [src] splits away from your biomass.") - to_chat(src, "You wiggle out of the depths of [src.loc]'s biomass and plop to the ground.") + to_chat(loc, "You feel a pang of loss as [src] splits away from your biomass.") + to_chat(src, "You wiggle out of the depths of [loc]'s biomass and plop to the ground.") - var/mob/living/M = src.loc + var/mob/living/M = loc - src.loc = get_turf(src) - src.verbs -= /mob/living/simple_animal/diona/proc/split - src.verbs += /mob/living/simple_animal/diona/proc/merge + forceMove(get_turf(src)) + verbs -= /mob/living/simple_animal/diona/proc/split + verbs += /mob/living/simple_animal/diona/proc/merge if(istype(M)) for(var/atom/A in M.contents) - if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder)) + if(istype(A, /mob/living/simple_animal/borer) || istype(A, /obj/item/weapon/holder)) return M.status_flags &= ~PASSEMOTES -/mob/living/simple_animal/diona/verb/fertilize_plant() - set category = "Diona" - set name = "Fertilize plant" - set desc = "Turn your food into nutrients for plants." - - var/list/trays = list() - for(var/obj/machinery/portable_atmospherics/hydroponics/tray in range(1)) - if(tray.nutrilevel < 10) - trays += tray - - var/obj/machinery/portable_atmospherics/hydroponics/target = input("Select a tray:") as null|anything in trays - - if(!src || !target || target.nutrilevel == 10) return //Sanity check. - - src.nutrition -= ((10-target.nutrilevel)*5) - target.nutrilevel = 10 - src.visible_message("[src] secretes a trickle of green liquid from its tail, refilling [target]'s nutrient tray.","\red You secrete a trickle of green liquid from your tail, refilling [target]'s nutrient tray.") - -/mob/living/simple_animal/diona/verb/eat_weeds() - set category = "Diona" - set name = "Eat Weeds" - set desc = "Clean the weeds out of soil or a hydroponics tray." - - var/list/trays = list() - for(var/obj/machinery/portable_atmospherics/hydroponics/tray in range(1)) - if(tray.weedlevel > 0) - trays += tray - - var/obj/machinery/portable_atmospherics/hydroponics/target = input("Select a tray:") as null|anything in trays - - if(!src || !target || target.weedlevel == 0) return //Sanity check. - - src.nutrition += target.weedlevel * 15 - target.weedlevel = 0 - src.visible_message("[src] begins rooting through [target], ripping out weeds and eating them noisily.","You begin rooting through [target], ripping out weeds and eating them noisily.") - /mob/living/simple_animal/diona/verb/evolve() set category = "Diona" set name = "Evolve" @@ -170,15 +136,15 @@ to_chat(src, "You need to binge on weeds in order to have the energy to grow...") return - src.split() - src.visible_message("[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.") + split() + visible_message("[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.","You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.") - var/mob/living/carbon/human/diona/adult = new(get_turf(src.loc)) + var/mob/living/carbon/human/diona/adult = new(get_turf(loc)) adult.set_species("Diona") - if(istype(loc,/obj/item/weapon/holder/diona)) + if(istype(loc, /obj/item/weapon/holder/diona)) var/obj/item/weapon/holder/diona/L = loc - src.loc = L.loc + forceMove(L.loc) qdel(L) for(var/datum/language/L in languages) @@ -187,12 +153,12 @@ adult.name = "diona ([rand(100,999)])" adult.real_name = adult.name - adult.ckey = src.ckey + adult.ckey = ckey adult.real_name = pick(diona_names) //I hate this being here of all places but unfortunately dna is based on real_name! adult.rename_self("diona") - for(var/obj/item/W in src.contents) - src.unEquip(W) + for(var/obj/item/W in contents) + unEquip(W) qdel(src) @@ -207,7 +173,8 @@ var/mob/living/carbon/human/M = input(src,"Who do you wish to take a sample from?") in null|choices - if(!M || !src) return + if(!M || !src) + return if(M.species.flags & NO_BLOOD) to_chat(src, "That donor has no blood to take.") @@ -217,7 +184,7 @@ to_chat(src, "That donor offers you nothing new.") return - src.visible_message("[src] flicks out a feeler and neatly steals a sample of [M]'s blood.","You flick out a feeler and neatly steal a sample of [M]'s blood.") + visible_message("[src] flicks out a feeler and neatly steals a sample of [M]'s blood.","You flick out a feeler and neatly steal a sample of [M]'s blood.") donors += M.real_name for(var/datum/language/L in M.languages) if(!(L.flags & HIVEMIND)) @@ -241,7 +208,7 @@ /mob/living/simple_animal/diona/put_in_hands(obj/item/W) - W.loc = get_turf(src) + W.forceMove(get_turf(src)) W.layer = initial(W.layer) W.plane = initial(W.plane) W.dropped() @@ -250,7 +217,7 @@ to_chat(src, "You don't have any hands!") return -/mob/living/simple_animal/diona/emote(var/act, var/m_type=1, var/message = null) +/mob/living/simple_animal/diona/emote(act, m_type=1, message = null) if(stat) return diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 04506c819c8..b1b31461b77 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -34,7 +34,7 @@ for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) var/step = get_step(src, direction) if(step) - if(locate(/obj/effect/plant) in step) + if(locate(/obj/effect/spacevine) in step) Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/handle_automated_action() @@ -47,11 +47,9 @@ LoseTarget() src.visible_message("\blue [src] calms down.") - if(locate(/obj/effect/plant) in loc) - var/obj/effect/plant/SV = locate(/obj/effect/plant) in loc - qdel(SV) - if(prob(10)) - say("Nom") + var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc + if(SV) + SV.eat(src) /mob/living/simple_animal/hostile/retaliate/goat/Life() . = ..() @@ -66,11 +64,9 @@ /mob/living/simple_animal/hostile/retaliate/goat/Move() ..() if(!stat) - if(locate(/obj/effect/plant) in loc) - var/obj/effect/plant/SV = locate(/obj/effect/plant) in loc - qdel(SV) - if(prob(10)) - say("Nom") + var/obj/effect/spacevine/SV = locate(/obj/effect/spacevine) in loc + if(SV) + SV.eat(src) /mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob, params) if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass)) @@ -162,6 +158,7 @@ icon_living = "chick" icon_dead = "chick_dead" icon_gib = "chick_gib" + gender = FEMALE speak = list("Cherp.","Cherp?","Chirrup.","Cheep!") speak_emote = list("cheeps") emote_hear = list("cheeps") @@ -205,9 +202,10 @@ var/global/chicken_count = 0 /mob/living/simple_animal/chicken name = "\improper chicken" desc = "Hopefully the eggs are good this season." - icon_state = "chicken" - icon_living = "chicken" - icon_dead = "chicken_dead" + gender = FEMALE + icon_state = "chicken_brown" + icon_living = "chicken_brown" + icon_dead = "chicken_brown_dead" speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.") speak_emote = list("clucks","croons") emote_hear = list("clucks") @@ -216,62 +214,68 @@ var/global/chicken_count = 0 speak_chance = 2 turns_per_move = 3 butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat = 2) + var/egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg + var/food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat response_help = "pets the" response_disarm = "gently pushes aside the" response_harm = "kicks the" attacktext = "kicks" - health = 10 - maxHealth = 10 + health = 15 + maxHealth = 15 + ventcrawler = 2 var/eggsleft = 0 - var/chicken_color + var/eggsFertile = TRUE + var/body_color + var/icon_prefix = "chicken" pass_flags = PASSTABLE | PASSMOB mob_size = MOB_SIZE_SMALL can_hide = 1 can_collar = 1 + var/list/feedMessages = list("It clucks happily.","It clucks happily.") + var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") + var/list/validColors = list("brown","black","white") gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY /mob/living/simple_animal/chicken/New() ..() - if(!chicken_color) - chicken_color = pick( list("brown","black","white") ) - icon_state = "chicken_[chicken_color]" - icon_living = "chicken_[chicken_color]" - icon_dead = "chicken_[chicken_color]_dead" + if(!body_color) + body_color = pick(validColors) + icon_state = "[icon_prefix]_[body_color]" + icon_living = "[icon_prefix]_[body_color]" + icon_dead = "[icon_prefix]_[body_color]_dead" pixel_x = rand(-6, 6) pixel_y = rand(0, 10) chicken_count += 1 /mob/living/simple_animal/chicken/death(gibbed) - ..() + ..(gibbed) chicken_count -= 1 -/mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O - if(G.seed.kitchen_tag == "wheat") - if(!stat && eggsleft < 8) - user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.") - user.drop_item() - qdel(O) - eggsleft += rand(1, 4) -// to_chat(world, eggsleft) - else - to_chat(user, "\blue [name] doesn't seem hungry!") +/mob/living/simple_animal/chicken/attackby(obj/item/O, mob/user, params) + if(istype(O, food_type)) //feedin' dem chickens + if(!stat && eggsleft < 8) + var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]" + user.visible_message(feedmsg) + user.drop_item() + qdel(O) + eggsleft += rand(1, 4) + //world << eggsleft else - to_chat(user, "\blue [name] doesn't seem interested in [O]!") + to_chat(user, "[name] doesn't seem hungry!") else ..() /mob/living/simple_animal/chicken/Life() . = ..() - if(. && prob(3) && eggsleft > 0) - visible_message("[src] [pick("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")]") + if((. && prob(3) && eggsleft > 0) && egg_type) + visible_message("[src] [pick(layMessage)]") eggsleft-- - var/obj/item/weapon/reagent_containers/food/snacks/egg/E = new(get_turf(src)) + var/obj/item/E = new egg_type(get_turf(src)) E.pixel_x = rand(-6,6) E.pixel_y = rand(-6,6) - if(chicken_count < MAX_CHICKENS && prob(10)) - processing_objects.Add(E) + if(eggsFertile) + if(chicken_count < MAX_CHICKENS && prob(25)) + processing_objects.Add(E) /obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0 /obj/item/weapon/reagent_containers/food/snacks/egg/process() diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm index bebe9be7628..a831c830459 100644 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ b/code/modules/mob/living/simple_animal/friendly/slime.dm @@ -15,67 +15,13 @@ var/colour = "grey" pass_flags = PASSTABLE -/mob/living/simple_animal/slime/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(70)) - to_chat(src, "You fail to push [tmob]'s fat ass out of the way.") - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if(!( istype(AM, /atom/movable) )) - return - if(!( now_pushing )) - now_pushing = 1 - if(!( AM.anchored )) - var/t = get_dir(src, AM) - if(istype(AM, /obj/structure/window/full)) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return - -/mob/living/simple_animal/adultslime - name = "pet slime" - desc = "A lovable, domesticated slime." - icon = 'icons/mob/slimes.dmi' +/mob/living/simple_animal/slime/adult health = 200 maxHealth = 200 icon_state = "grey adult slime" icon_living = "grey adult slime" icon_dead = "grey baby slime dead" - response_help = "pets" - response_disarm = "shoos" - response_harm = "stomps on" - emote_see = list("jiggles", "bounces in place") - var/colour = "grey" - del_on_death = 1 -/mob/living/simple_animal/adultslime/New() +/mob/living/simple_animal/slime/New() ..() overlays += "aslime-:33" - - -/mob/living/simple_animal/slime/adult/death(gibbed) - for(var/i in 1 to 2) - var/mob/living/simple_animal/slime/S = new /mob/living/simple_animal/slime (src.loc) - S.icon_state = "[colour] baby slime" - S.icon_living = "[colour] baby slime" - S.icon_dead = "[colour] baby slime dead" - S.colour = "[colour]" - ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 8c927eaefbd..538ce8450c7 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -5,9 +5,9 @@ #define BEE_TRAY_RECENT_VISIT 200 //How long in deciseconds until a tray can be visited by a bee again #define BEE_DEFAULT_COLOUR "#e5e500" //the colour we make the stripes of the bee if our reagent has no colour (or we have no reagent) -#define BEE_POLLINATE_YIELD_CHANCE 10 +#define BEE_POLLINATE_YIELD_CHANCE 33 #define BEE_POLLINATE_PEST_CHANCE 33 -#define BEE_POLLINATE_POTENTCY_CHANCE 50 +#define BEE_POLLINATE_POTENCY_CHANCE 50 /mob/living/simple_animal/hostile/poison/bees name = "bee" @@ -15,6 +15,7 @@ icon_state = "" icon_living = "" icon = 'icons/mob/bees.dmi' + gender = FEMALE speak_emote = list("buzzes") emote_hear = list("buzzes") turns_per_move = 0 @@ -142,7 +143,7 @@ if(beehome.bees) beehome.bees.Remove(src) beehome = null - ..() + return ..() /mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed) if(beehome) @@ -158,10 +159,10 @@ to_chat(user, "This bee is homeless!") /mob/living/simple_animal/hostile/poison/bees/worker/Found(atom/A) - if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/Hydro = A - if(Hydro.seed && !Hydro.dead && !Hydro.recent_bee_visit && !Hydro.closed_system) - wanted_objects |= /obj/machinery/portable_atmospherics/hydroponics //so we only hunt them while they're alive/seeded/not visisted and uncovered + if(istype(A, /obj/machinery/hydroponics)) + var/obj/machinery/hydroponics/Hydro = A + if(Hydro.myseed && !Hydro.dead && !Hydro.recent_bee_visit) + wanted_objects |= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted return 1 ..() @@ -175,24 +176,24 @@ /mob/living/simple_animal/hostile/poison/bees/worker/AttackingTarget() //Pollinate - if(istype(target, /obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/Hydro = target + if(istype(target, /obj/machinery/hydroponics)) + var/obj/machinery/hydroponics/Hydro = target pollinate(Hydro) else if(target == beehome) var/obj/structure/beebox/BB = target forceMove(BB) target = null - wanted_objects.Remove(/obj/structure/beebox) //so we don't attack beeboxes when not going home + wanted_objects -= /obj/structure/beebox //so we don't attack beeboxes when not going home else ..() -/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/portable_atmospherics/hydroponics/Hydro) - if(!istype(Hydro) || !Hydro.seed || Hydro.dead || Hydro.recent_bee_visit || Hydro.closed_system) +/mob/living/simple_animal/hostile/poison/bees/worker/proc/pollinate(obj/machinery/hydroponics/Hydro) + if(!istype(Hydro) || !Hydro.myseed || Hydro.dead || Hydro.recent_bee_visit) target = null return target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity - wanted_objects.Remove(/obj/machinery/portable_atmospherics/hydroponics) //so we only hunt them while they're alive/seeded/not visisted + wanted_objects -= /obj/machinery/hydroponics //so we only hunt them while they're alive/seeded/not visisted Hydro.recent_bee_visit = TRUE spawn(BEE_TRAY_RECENT_VISIT) if(Hydro) @@ -200,23 +201,14 @@ var/growth = health //Health also means how many bees are in the swarm, roughly. //better healthier plants! - Hydro.health += round(growth*0.5) + Hydro.adjustHealth(growth*0.5) if(prob(BEE_POLLINATE_PEST_CHANCE)) - Hydro.pestlevel = max(0, --Hydro.pestlevel) - if(prob(BEE_POLLINATE_YIELD_CHANCE)) //Yield mod is HELLA powerful, but quite rare - if(!isnull(plant_controller.seeds[Hydro.seed.name])) - Hydro.seed = Hydro.seed.diverge() - else - Hydro.seed.update_name_prefixes() - var/seed_yield = Hydro.seed.get_trait(TRAIT_YIELD) - Hydro.seed.set_trait(TRAIT_YIELD, seed_yield + 1, 10, 0) - if(prob(BEE_POLLINATE_POTENTCY_CHANCE)) - if(!isnull(plant_controller.seeds[Hydro.seed.name])) - Hydro.seed = Hydro.seed.diverge() - else - Hydro.seed.update_name_prefixes() - var/seed_potency = Hydro.seed.get_trait(TRAIT_POTENCY) - Hydro.seed.set_trait(TRAIT_POTENCY, seed_potency + 1, 200, 0) + Hydro.adjustPests(-10) + if(prob(BEE_POLLINATE_YIELD_CHANCE)) + Hydro.myseed.adjust_yield(1) + Hydro.yieldmod = 2 + if(prob(BEE_POLLINATE_POTENCY_CHANCE)) + Hydro.myseed.adjust_potency(1) if(beehome) beehome.bee_resources = min(beehome.bee_resources + growth, 100) @@ -234,7 +226,7 @@ idle = max(0, --idle) if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME)) if(!FindTarget()) - wanted_objects.Add(/obj/structure/beebox) //so we don't attack beeboxes when not going home + wanted_objects += /obj/structure/beebox //so we don't attack beeboxes when not going home target = beehome if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home for(var/obj/structure/beebox/BB in view(vision_range, src)) @@ -304,6 +296,7 @@ /obj/item/queen_bee/Destroy() qdel(queen) + queen = null return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index a3739dfe088..1df7348a839 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -1,6 +1,5 @@ /mob/living/simple_animal/hostile faction = list("hostile") - mouse_opacity = 2 //This makes it easier to hit hostile mobs, you only need to click on their tile, and is set back to 1 when they die stop_automated_movement_when_pulled = 0 environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls var/atom/target @@ -13,7 +12,8 @@ var/list/friends = list() var/ranged_message = "fires" //Fluff text for ranged mobs var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks - var/ranged_cooldown_cap = 3 //What ranged attacks, after being used are set to, to go back on cooldown, defaults to 3 life() ticks + var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is + var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat. var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance @@ -30,11 +30,33 @@ var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) + + //typecache of things this mob will attack in DestroySurroundings() if it has environment_smash + var/list/environment_target_typecache = list( + /obj/machinery/door/window, + /obj/structure/window, + /obj/structure/closet, + /obj/structure/table, + /obj/structure/grille, + /obj/structure/girder, + /obj/structure/rack, + /obj/structure/barricade) //turned into a typecache in New() + var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such + var/list/emote_taunt = list() + var/taunt_chance = 0 + +/mob/living/simple_animal/hostile/New() + ..() + if(!targets_from) + targets_from = src + environment_target_typecache = typecacheof(environment_target_typecache) + +/mob/living/simple_animal/hostile/Destroy() + targets_from = null + return ..() /mob/living/simple_animal/hostile/Life() . = ..() - if(ranged) - ranged_cooldown-- if(!.) walk(src, 0) return 0 @@ -58,76 +80,89 @@ if(AIShouldSleep(possible_targets)) // we try to acquire a new one AIStatus = AI_IDLE // otherwise we go idle return 1 + +/mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user) + if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user) + FindTarget(list(user), 1) + return ..() + +/mob/living/simple_animal/hostile/bullet_act(obj/item/projectile/P) + if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client) + if(P.firer && get_dist(src, P.firer) <= aggro_vision_range) + FindTarget(list(P.firer), 1) + Goto(P.starting, move_to_delay, 3) + return ..() + //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// /mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see - var/list/L = list() + . = list() if(!search_objects) - var/list/Mobs = hearers(vision_range, src) - src //Remove self, so we don't suicide - L += Mobs - for(var/obj/mecha/M in mechas_list) - if(get_dist(M, src) <= vision_range && can_see(src, M, vision_range)) - L += M - for(var/obj/spacepod/S in spacepods_list) - if(get_dist(S, src) <= vision_range && can_see(src, S, vision_range)) - L += S + var/list/Mobs = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide + . += Mobs + + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/spacepod)) + + for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines)) + if(can_see(targets_from, HM, vision_range)) + . += HM else - var/list/Objects = oview(vision_range, src) - L += Objects - return L + var/list/Objects = oview(vision_range, targets_from) + . += Objects /mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about - var/list/Targets = list() + . = list() if(!HasTargetsList) possible_targets = ListTargets() - for(var/atom/A in possible_targets) + for(var/pos_targ in possible_targets) + var/atom/A = pos_targ if(Found(A))//Just in case people want to override targetting - Targets = list(A) + . = list(A) break if(CanAttack(A))//Can we attack it? - Targets += A + . += A continue - var/Target = PickTarget(Targets) + var/Target = PickTarget(.) GiveTarget(Target) return Target //We now have a target + +/mob/living/simple_animal/hostile/proc/PossibleThreats() + . = list() + for(var/pos_targ in ListTargets()) + var/atom/A = pos_targ + if(Found(A)) + . = list(A) + break + if(CanAttack(A)) + . += A + continue /mob/living/simple_animal/hostile/proc/Found(var/atom/A)//This is here as a potential override to pick a specific target if available return -/mob/living/simple_animal/hostile/proc/PickTarget(var/list/Targets)//Step 3, pick amongst the possible, attackable targets - if(!Targets.len)//We didnt find nothin! - return +/mob/living/simple_animal/hostile/proc/PickTarget(list/Targets)//Step 3, pick amongst the possible, attackable targets if(target != null)//If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets - for(var/atom/A in Targets) - var/target_dist = get_dist(src, target) - var/possible_target_distance = get_dist(src, A) + for(var/pos_targ in Targets) + var/atom/A = pos_targ + var/target_dist = get_dist(targets_from, target) + var/possible_target_distance = get_dist(targets_from, A) if(target_dist < possible_target_distance) Targets -= A - var/chosen_target = safepick(Targets)//Pick the remaining targets (if any) at random + if(!Targets.len)//We didnt find nothin! + return + var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random return chosen_target /mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)//Can we actually attack a possible target? + if(!the_target) + return 0 if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it return 0 if(search_objects < 2) - if(istype(the_target, /obj/mecha)) - var/obj/mecha/M = the_target - if(M.occupant)//Just so we don't attack empty mechs - if(CanAttack(M.occupant)) - return 1 - if(istype(the_target, /obj/spacepod)) - var/obj/spacepod/S = the_target - if(S.pilot) //Just so we don't attack empty pods - if(CanAttack(S.pilot)) - return 1 if(isliving(the_target)) var/mob/living/L = the_target - var/faction_check = 0 - for(var/F in faction) - if(F in L.faction) - faction_check = 1 - break + var/faction_check = faction_check(L) if(robust_searching) if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1) return 0 @@ -141,14 +176,42 @@ if(faction_check && !attack_same) return 0 return 1 + + if(ishuman(the_target)) + var/mob/living/carbon/human/H = the_target + if(is_type_in_list(src, H.species.ignored_by)) + return 0 + + if(istype(the_target, /obj/mecha)) + var/obj/mecha/M = the_target + if(M.occupant)//Just so we don't attack empty mechs + if(CanAttack(M.occupant)) + return 1 + + if(istype(the_target, /obj/spacepod)) + var/obj/spacepod/S = the_target + if(S.pilot) //Just so we don't attack empty pods + if(CanAttack(S.pilot)) + return 1 + + if(istype(the_target, /obj/machinery/porta_turret)) + var/obj/machinery/porta_turret/P = the_target + if(P.faction in faction) + return 0 + if(!P.raised) //Don't attack invincible turrets + return 0 + if(P.stat & BROKEN) //Or turrets that are already broken + return 0 + return 1 if(isobj(the_target)) if(is_type_in_list(the_target, wanted_objects)) return 1 return 0 -/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target +/mob/living/simple_animal/hostile/proc/GiveTarget(new_target)//Step 4, give us our selected target target = new_target if(target != null) + Aggro() return 1 /mob/living/simple_animal/hostile/proc/MoveToTarget(var/list/possible_targets)//Step 5, handle movement between us and our target @@ -157,38 +220,45 @@ LoseTarget() return 0 if(target in possible_targets) - var/target_distance = get_dist(src,target) - if(ranged)//We ranged? Shoot at em - if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown + if(target.z != z) + LoseTarget() + return 0 + var/target_distance = get_dist(targets_from,target) + if(ranged) //We ranged? Shoot at em + if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown OpenFire(target) - if(retreat_distance != null)//If we have a retreat distance, check if we need to run from our target - if(target_distance <= retreat_distance)//If target's closer than our retreat distance, run + if(retreat_distance != null) //If we have a retreat distance, check if we need to run from our target + if(target_distance <= retreat_distance) //If target's closer than our retreat distance, run walk_away(src,target,retreat_distance,move_to_delay) else - Goto(target,move_to_delay,minimum_distance)//Otherwise, get to our minimum distance so we chase them + Goto(target,move_to_delay,minimum_distance) //Otherwise, get to our minimum distance so we chase them else Goto(target,move_to_delay,minimum_distance) - if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack - AttackingTarget() - return 1 + if(target) + if(targets_from && isturf(targets_from.loc) && target.Adjacent(targets_from)) //If they're next to us, attack + AttackingTarget() + return 1 + return 0 if(environment_smash) - if(target.loc != null && get_dist(src, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still - if(environment_smash >= 2)//If we're capable of smashing through walls, forget about vision completely after finding our target + if(target.loc != null && get_dist(targets_from, target.loc) <= vision_range) //We can't see our target, but he's in our vision range still + if(ranged_ignores_vision && ranged_cooldown <= world.time) //we can't see our target... but we can fire at them! + OpenFire(target) + if(environment_smash >= 2) //If we're capable of smashing through walls, forget about vision completely after finding our target Goto(target,move_to_delay,minimum_distance) FindHidden() return 1 else if(FindHidden()) return 1 - LostTarget() + LoseTarget() return 0 -/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance) +/mob/living/simple_animal/hostile/proc/Goto(target, delay, minimum_distance) walk_to(src, target, minimum_distance, delay) /mob/living/simple_animal/hostile/adjustHealth(damage) - ..(damage) - if(!stat && search_objects < 3)//Not unconscious, and we don't ignore mobs + . = ..() + if(!ckey && !stat && search_objects < 3 && damage > 0)//Not unconscious, and we don't ignore mobs if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight search_objects = 0 target = null @@ -203,101 +273,102 @@ /mob/living/simple_animal/hostile/proc/Aggro() vision_range = aggro_vision_range + if(target && emote_taunt.len && prob(taunt_chance)) + emote("me", 1, "[pick(emote_taunt)] at [target].") + taunt_chance = max(taunt_chance-7,2) /mob/living/simple_animal/hostile/proc/LoseAggro() stop_automated_movement = 0 vision_range = idle_vision_range + taunt_chance = initial(taunt_chance) /mob/living/simple_animal/hostile/proc/LoseTarget() target = null walk(src, 0) LoseAggro() -/mob/living/simple_animal/hostile/proc/LostTarget() - walk(src, 0) - LoseAggro() - //////////////END HOSTILE MOB TARGETTING AND AGGRESSION//////////// /mob/living/simple_animal/hostile/death(gibbed) - LoseAggro() - mouse_opacity = 1 - ..() - walk(src, 0) + LoseTarget() + ..(gibbed) + +/mob/living/simple_animal/hostile/proc/summon_backup(distance) + do_alert_animation(src) + playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1) + for(var/mob/living/simple_animal/hostile/M in oview(distance, targets_from)) + var/list/L = M.faction&faction + if(L.len) + if(M.AIStatus == AI_OFF) + return + else + M.Goto(src,M.move_to_delay,M.minimum_distance) -/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target) - var/target = the_target +/mob/living/simple_animal/hostile/proc/OpenFire(atom/A) if(check_friendly_fire) - for(var/turf/T in getline(src, target)) // Not 100% reliable but this is faster than simulating actual trajectory + for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory for(var/mob/living/L in T) - if(L == src || L == target) + if(L == src || L == A) continue if(faction_check(L) && !attack_same) return - visible_message("[src] [ranged_message] at [target]!") + visible_message("[src] [ranged_message] at [A]!") if(rapid) spawn(1) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) + Shoot(A) spawn(4) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) + Shoot(A) spawn(6) - Shoot(target, src.loc, src) - if(casingtype) - new casingtype(get_turf(src)) + Shoot(A) else - Shoot(target, src.loc, src) - if(casingtype) - new casingtype - ranged_cooldown = ranged_cooldown_cap - return + Shoot(A) + ranged_cooldown = world.time + ranged_cooldown_time -/mob/living/simple_animal/hostile/proc/Shoot(var/target, var/start, var/user, var/bullet = 0) - if(target == start) +/mob/living/simple_animal/hostile/proc/Shoot(atom/targeted_atom) + if(targeted_atom == targets_from.loc || targeted_atom == targets_from) return + var/turf/startloc = get_turf(targets_from) if(casingtype) - var/obj/item/ammo_casing/casing = new casingtype + var/obj/item/ammo_casing/casing = new casingtype(startloc) playsound(src, projectilesound, 100, 1) - casing.fire(target, src, zone_override = ran_zone()) - casing.loc = loc - else - var/obj/item/projectile/A = new projectiletype(loc) - playsound(user, projectilesound, 100, 1) - A.current = target - A.firer = src - A.yo = target:y - start:y - A.xo = target:x - start:x - if(AIStatus == AI_OFF)//Don't want mindless mobs to have their movement screwed up firing in space - newtonian_move(get_dir(target, user)) - A.original = target - A.fire() - return A + casing.fire(targeted_atom, src, zone_override = ran_zone()) + else if(projectiletype) + var/obj/item/projectile/P = new projectiletype(startloc) + playsound(src, projectilesound, 100, 1) + P.current = startloc + P.starting = startloc + P.firer = src + P.yo = targeted_atom.y - startloc.y + P.xo = targeted_atom.x - startloc.x + if(AIStatus != AI_ON)//Don't want mindless mobs to have their movement screwed up firing in space + newtonian_move(get_dir(targeted_atom, targets_from)) + P.original = targeted_atom + P.fire() + return P /mob/living/simple_animal/hostile/proc/DestroySurroundings() if(environment_smash) EscapeConfinement() for(var/dir in cardinal) - var/turf/T = get_step(src, dir) - if(istype(T, /turf/simulated/wall) || istype(T, /turf/simulated/mineral)) - if(T.Adjacent(src)) + var/turf/T = get_step(targets_from, dir) + if(iswallturf(T) || ismineralturf(T)) + if(T.Adjacent(targets_from)) T.attack_animal(src) - for(var/atom/A in T) - if(!A.Adjacent(src)) + for(var/a in T) + var/atom/A = a + if(!A.Adjacent(targets_from)) continue - if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/rack)) + if(is_type_in_typecache(A, environment_target_typecache)) A.attack_animal(src) return /mob/living/simple_animal/hostile/proc/EscapeConfinement() if(buckled) buckled.attack_animal(src) - if(!isturf(src.loc) && src.loc != null)//Did someone put us in something? - var/atom/A = src.loc + if(!isturf(targets_from.loc) && targets_from.loc != null)//Did someone put us in something? + var/atom/A = get_turf(targets_from) A.attack_animal(src)//Bang on it till we get out return @@ -305,12 +376,12 @@ if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper) || istype(target.loc, /obj/machinery/bodyscanner) || istype(target.loc, /obj/machinery/recharge_station)) var/atom/A = target.loc Goto(A,move_to_delay,minimum_distance) - if(A.Adjacent(src)) + if(A.Adjacent(targets_from)) A.attack_animal(src) return 1 -/mob/living/simple_animal/hostile/RangedAttack(var/atom/A, var/params) //Player firing - if(ranged && ranged_cooldown <= 0) +/mob/living/simple_animal/hostile/RangedAttack(atom/A, params) //Player firing + if(ranged && ranged_cooldown <= world.time) target = A OpenFire(A) ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm new file mode 100644 index 00000000000..85a351606f6 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -0,0 +1,393 @@ +#define MEDAL_PREFIX "Bubblegum" + +/* + +BUBBLEGUM + +Bubblegum spawns randomly wherever a lavaland creature is able to spawn. It is the most powerful slaughter demon in existence. +Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size. + +It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage. + +It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target. +If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it. +If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood. +At half health, it will either charge three times or warp, then charge, instead of doing a single charge. + +When Bubblegum dies, it leaves behind a chest that can contain three things: + 1. A bottle that, when activated, drives everyone nearby into a frenzy + 2. A contract that marks for death the chosen target + 3. A spellblade that can slice off limbs at range + +Difficulty: Hard + +*/ + +/mob/living/simple_animal/hostile/megafauna/bubblegum + name = "bubblegum" + desc = "In what passes for a heirarchy among slaughter demons, this one is king." + health = 2500 + maxHealth = 2500 + attacktext = "rends" + attack_sound = 'sound/misc/demon_attack1.ogg' + icon_state = "bubblegum" + icon_living = "bubblegum" + icon_dead = "" + friendly = "stares down" + icon = 'icons/mob/lavaland/96x96megafauna.dmi' + speak_emote = list("gurgles") + armour_penetration = 40 + melee_damage_lower = 40 + melee_damage_upper = 40 + speed = 1 + move_to_delay = 10 + ranged = 1 + pixel_x = -32 + del_on_death = 1 + loot = list(/obj/structure/closet/crate/necropolis/bubblegum) + var/charging = 0 + medal_type = MEDAL_PREFIX + score_type = BUBBLEGUM_SCORE + deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... " + death_sound = 'sound/misc/enter_blood.ogg' + +/obj/item/device/gps/internal/bubblegum + icon_state = null + gpstag = "Bloody Signal" + desc = "You're not quite sure how a signal can be bloody." + invisibility = 100 + +/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount) + if(amount > 0 && prob(25)) + var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc) + if(prob(40)) + step(B, pick(cardinal)) + else + B.dir = pick(cardinal) + . = ..() + +/obj/effect/decal/cleanable/blood/gibs/bubblegum + name = "thick blood" + desc = "Thick, splattered blood." + random_icon_states = list("gib3", "gib5", "gib6") + amount = 20 + +/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in() + return TRUE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Life() + ..() + move_to_delay = Clamp((health/maxHealth) * 10, 5, 10) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() + anger_modifier = Clamp(((maxHealth - health)/60),0,20) + if(charging) + return + ranged_cooldown = world.time + ranged_cooldown_time + + var/warped = FALSE + if(!try_bloodattack()) + spawn(0) + blood_spray() + warped = blood_warp() + if(warped && prob(100 - anger_modifier)) + return + + if(prob(90 - anger_modifier) || slaughterlings()) + if(health > maxHealth * 0.5) + spawn(0) + charge() + else + if(prob(70) || warped) + spawn(0) + triple_charge() + else + spawn(0) + warp_charge() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/New() + ..() + for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in mob_list) + if(B != src) + qdel(src) //There can be only one + break + var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new + AddSpell(bloodspell) + if(istype(loc, /obj/effect/dummy/slaughter)) + bloodspell.phased = 1 + internal_gps = new/obj/item/device/gps/internal/bubblegum(src) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon) + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget() + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Move() + if(charging) + new /obj/effect/overlay/temp/decoy/fading(loc, src) + DestroySurroundings() + . = ..() + if(!stat && .) + playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1) + if(charging) + DestroySurroundings() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge() + blood_warp() + charge() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge() + charge() + charge() + charge() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge() + var/turf/T = get_turf(target) + if(!T || T == loc) + return + new /obj/effect/overlay/temp/dragon_swoop(T) + charging = 1 + DestroySurroundings() + walk(src, 0) + dir = get_dir(src, T) + var/obj/effect/overlay/temp/decoy/D = new /obj/effect/overlay/temp/decoy(loc, src) + animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5) + sleep(5) + throw_at(T, get_dist(src, T), 1, src, 0) + charging = 0 + try_bloodattack() + if(target) + Goto(target, move_to_delay, minimum_distance) + + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A) + if(charging) + if(isturf(A) || isobj(A) && A.density) + A.ex_act(2) + DestroySurroundings() + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/A) + if(!charging) + return ..() + + else if(isliving(A)) + var/mob/living/L = A + L.visible_message("[src] slams into [L]!", "[src] slams into you!") + L.apply_damage(40, BRUTE) + playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1) + shake_camera(L, 4, 3) + shake_camera(src, 2, 3) + var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src))) + L.throw_at_fast(throwtarget, 3) + + charging = 0 + + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood() + var/list/targets = ListTargets() + . = list() + for(var/mob/living/L in targets) + var/list/bloodpool = get_pools(get_turf(L), 0) + if(bloodpool.len && (!faction_check(L) || L.stat == DEAD)) + . += L + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack() + var/list/targets = get_mobs_on_blood() + if(targets.len) + spawn(0) + bloodattack(targets, prob(50)) + + return TRUE + return FALSE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets, handedness) + var/mob/living/target_one = pick_n_take(targets) + var/turf/target_one_turf = get_turf(target_one) + var/mob/living/target_two + if(targets.len) + target_two = pick_n_take(targets) + var/turf/target_two_turf = get_turf(target_two) + if(target_two.stat != CONSCIOUS || prob(10)) + bloodgrab(target_two_turf, handedness) + else + bloodsmack(target_two_turf, handedness) + + if(target_one) + var/list/pools = get_pools(get_turf(target_one), 0) + if(pools.len) + target_one_turf = get_turf(target_one) + if(target_one_turf) + if(target_one.stat != CONSCIOUS || prob(10)) + bloodgrab(target_one_turf, !handedness) + else + bloodsmack(target_one_turf, !handedness) + + if(!target_two && target_one) + var/list/poolstwo = get_pools(get_turf(target_one), 0) + if(poolstwo.len) + target_one_turf = get_turf(target_one) + if(target_one_turf) + if(target_one.stat != CONSCIOUS || prob(10)) + bloodgrab(target_one_turf, handedness) + else + bloodsmack(target_one_turf, handedness) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T, handedness) + if(handedness) + new /obj/effect/overlay/temp/bubblegum_hands/rightsmack(T) + else + new /obj/effect/overlay/temp/bubblegum_hands/leftsmack(T) + sleep(2.5) + for(var/mob/living/L in T) + if(!faction_check(L)) + to_chat(L, "[src] rends you!") + playsound(T, attack_sound, 100, 1, -1) + var/limb_to_hit = pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") + L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration)) + sleep(3) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness) + if(handedness) + new /obj/effect/overlay/temp/bubblegum_hands/rightpaw(T) + new /obj/effect/overlay/temp/bubblegum_hands/rightthumb(T) + else + new /obj/effect/overlay/temp/bubblegum_hands/leftpaw(T) + new /obj/effect/overlay/temp/bubblegum_hands/leftthumb(T) + sleep(6) + for(var/mob/living/L in T) + if(!faction_check(L)) + to_chat(L, "[src] drags you through the blood!") + playsound(T, 'sound/misc/enter_blood.ogg', 100, 1, -1) + var/turf/targetturf = get_step(src, dir) + L.forceMove(targetturf) + playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, 1, -1) + if(L.stat != CONSCIOUS) + spawn(2) + devour(L) + sleep(1) + +/obj/effect/overlay/temp/bubblegum_hands + icon = 'icons/effects/bubblegum.dmi' + duration = 9 + +/obj/effect/overlay/temp/bubblegum_hands/rightthumb + icon_state = "rightthumbgrab" + +/obj/effect/overlay/temp/bubblegum_hands/leftthumb + icon_state = "leftthumbgrab" + +/obj/effect/overlay/temp/bubblegum_hands/rightpaw + icon_state = "rightpawgrab" + layer = MOB_LAYER - 0.1 + +/obj/effect/overlay/temp/bubblegum_hands/leftpaw + icon_state = "leftpawgrab" + layer = MOB_LAYER - 0.1 + +/obj/effect/overlay/temp/bubblegum_hands/rightsmack + icon_state = "rightsmack" + +/obj/effect/overlay/temp/bubblegum_hands/leftsmack + icon_state = "leftsmack" + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp() + if(Adjacent(target)) + return FALSE + var/list/can_jaunt = get_pools(get_turf(src), 1) + if(!can_jaunt.len) + return FALSE + + var/list/pools = get_pools(get_turf(target), 2) + var/list/pools_to_remove = get_pools(get_turf(target), 1) + pools -= pools_to_remove + if(!pools.len) + return FALSE + + var/obj/effect/overlay/temp/decoy/DA = new /obj/effect/overlay/temp/decoy(loc, src) + DA.color = "#FF0000" + var/oldtransform = DA.transform + DA.transform = matrix()*2 + animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 5) + sleep(5) + qdel(DA) + + var/obj/effect/decal/cleanable/blood/found_bloodpool + pools = get_pools(get_turf(target), 2) + pools_to_remove = get_pools(get_turf(target), 1) + pools -= pools_to_remove + if(pools.len) + shuffle(pools) + found_bloodpool = pick(pools) + if(found_bloodpool) + visible_message("[src] sinks into the blood...") + playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1) + forceMove(get_turf(found_bloodpool)) + playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1) + visible_message("And springs back out!") + return TRUE + return FALSE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range) + . = list() + for(var/obj/effect/decal/cleanable/nearby in view(T, range)) + if(nearby.can_bloodcrawl_in()) + . += nearby + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray() + visible_message("[src] sprays a stream of gore!") + var/range = 6 + round(anger_modifier * 0.4) + var/turf/previousturf = get_turf(src) + var/turf/J = previousturf + var/targetdir = get_dir(src, target) + if(target.loc == loc) + targetdir = dir + face_atom(target) + new /obj/effect/decal/cleanable/blood/bubblegum(J) + for(var/i in 1 to range) + J = get_step(previousturf, targetdir) + new /obj/effect/overlay/temp/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J)) + playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1) + if(!J || !previousturf.CanAtmosPass(J)) + break + new /obj/effect/decal/cleanable/blood/bubblegum(J) + previousturf = J + sleep(1) + +/obj/effect/decal/cleanable/blood/bubblegum + amount = 0 + +/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in() + return TRUE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings() + visible_message("[src] summons a shoal of slaughterlings!") + var/max_amount = 6 + for(var/H in get_pools(get_turf(src), 1)) + if(!max_amount) + break + max_amount-- + var/obj/effect/decal/cleanable/blood/B = H + new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(B.loc) + return max_amount + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter + name = "slaughterling" + desc = "Though not yet strong enough to create a true physical form, it's nonetheless determined to murder you." + density = 0 + faction = list("mining", "boss") + weather_immunities = list("lava","ash") + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter/CanPass(atom/movable/mover, turf/target, height = 0) + if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) + return 1 + return 0 + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm new file mode 100644 index 00000000000..b40e64c6a31 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -0,0 +1,266 @@ + +#define MEDAL_PREFIX "Colossus" +/* + +COLOSSUS + +The colossus spawns randomly wherever a lavaland creature is able to spawn. It is powerful, ancient, and extremely deadly. +The colossus has a degree of sentience, proving this in speech during its attacks. + +It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage. + +The colossus' true danger lies in its ranged capabilities. It fires immensely damaging death bolts that penetrate all armor in a variety of ways: + 1. The colossus fires death bolts in alternating patterns: the cardinal directions and the diagonal directions. + 2. The colossus fires death bolts in a shotgun-like pattern, instantly downing anything unfortunate enough to be hit by all of them. + 3. The colossus fires a spiral of death bolts. +At 33% health, the colossus gains an additional attack: + 4. The colossus fires two spirals of death bolts, spinning in opposite directions. + +When a colossus dies, it leaves behind a chunk of glowing crystal known as a black box. Anything placed inside will carry over into future rounds. +For instance, you could place a bag of holding into the black box, and then kill another colossus next round and retrieve the bag of holding from inside. + +Difficulty: Very Hard + +*/ + +/mob/living/simple_animal/hostile/megafauna/colossus + name = "colossus" + desc = "A monstrous creature protected by heavy shielding." + health = 2500 + maxHealth = 2500 + attacktext = "judges" + attack_sound = 'sound/magic/ratvar_attack.ogg' + icon_state = "eva" + icon_living = "eva" + icon_dead = "dragon_dead" + friendly = "stares down" + icon = 'icons/mob/lavaland/96x96megafauna.dmi' + speak_emote = list("roars") + armour_penetration = 40 + melee_damage_lower = 40 + melee_damage_upper = 40 + speed = 1 + move_to_delay = 10 + ranged = 1 + pixel_x = -32 + del_on_death = 1 + medal_type = MEDAL_PREFIX + score_type = COLOSSUS_SCORE + loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/internal/vocal_cords/colossus) + butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) + deathmessage = "disintegrates, leaving a glowing core in its wake." + death_sound = 'sound/misc/demon_dies.ogg' + +/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/L) + visible_message("[src] disintegrates [L]!") + L.dust() + +/mob/living/simple_animal/hostile/megafauna/colossus/OpenFire() + anger_modifier = Clamp(((maxHealth - health)/50),0,20) + ranged_cooldown = world.time + 120 + + if(enrage(target)) + if(move_to_delay == initial(move_to_delay)) + visible_message("\"You can't dodge.\"") + ranged_cooldown = world.time + 30 + telegraph() + dir_shots(alldirs) + move_to_delay = 3 + return + else + move_to_delay = initial(move_to_delay) + + if(prob(20+anger_modifier)) //Major attack + telegraph() + + if(health < maxHealth/3) + double_spiral() + else + visible_message("\"Judgement.\"") + spawn(0) + spiral_shoot(rand(0, 1)) + + else if(prob(20)) + ranged_cooldown = world.time + 30 + random_shots() + else + if(prob(70)) + ranged_cooldown = world.time + 20 + blast() + else + ranged_cooldown = world.time + 40 + spawn(0) + alternating_dir_shots() + + +/mob/living/simple_animal/hostile/megafauna/colossus/New() + ..() + internal_gps = new/obj/item/device/gps/internal/colossus(src) + +/obj/effect/overlay/temp/at_shield + name = "anti-toolbox field" + desc = "A shimmering forcefield protecting the colossus." + icon = 'icons/effects/effects.dmi' + icon_state = "at_shield2" + layer = FLY_LAYER + luminosity = 2 + duration = 8 + var/target + +/obj/effect/overlay/temp/at_shield/New(new_loc, new_target) + ..() + target = new_target + spawn(0) + orbit(target, 0, FALSE, 0, 0, FALSE, TRUE) + +/mob/living/simple_animal/hostile/megafauna/colossus/bullet_act(obj/item/projectile/P) + if(!stat) + var/obj/effect/overlay/temp/at_shield/AT = new /obj/effect/overlay/temp/at_shield(loc, src) + var/random_x = rand(-32, 32) + AT.pixel_x += random_x + + var/random_y = rand(0, 72) + AT.pixel_y += random_y + ..() + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.martial_art && prob(H.martial_art.deflection_chance)) + . = TRUE + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() + dir_shots(diagonals) + sleep(10) + dir_shots(cardinal) + sleep(10) + dir_shots(diagonals) + sleep(10) + dir_shots(cardinal) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/double_spiral() + visible_message("\"Die.\"") + + sleep(10) + spawn(0) + spiral_shoot() + spawn(0) + spiral_shoot(1) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/spiral_shoot(negative = 0, counter_start = 1) + var/counter = counter_start + var/turf/marker + for(var/i in 1 to 80) + switch(counter) + if(1) + marker = locate(x, y - 2, z) + if(2) + marker = locate(x - 1, y - 2, z) + if(3) + marker = locate(x - 2, y - 2, z) + if(4) + marker = locate(x - 2, y - 1, z) + if(5) + marker = locate(x - 2, y, z) + if(6) + marker = locate(x - 2, y + 1, z) + if(7) + marker = locate(x - 2, y + 2, z) + if(8) + marker = locate(x - 1, y + 2, z) + if(9) + marker = locate(x, y + 2, z) + if(10) + marker = locate(x + 1, y + 2, z) + if(11) + marker = locate(x + 2, y + 2, z) + if(12) + marker = locate(x + 2, y + 1, z) + if(13) + marker = locate(x + 2, y, z) + if(14) + marker = locate(x + 2, y - 1, z) + if(15) + marker = locate(x + 2, y - 2, z) + if(16) + marker = locate(x + 1, y - 2, z) + + if(negative) + counter-- + else + counter++ + if(counter > 16) + counter = 1 + if(counter < 1) + counter = 16 + shoot_projectile(marker) + playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 20, 1) + sleep(1) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/shoot_projectile(turf/marker) + if(!marker || marker == loc) + return + var/turf/startloc = get_turf(src) + var/obj/item/projectile/P = new /obj/item/projectile/colossus(startloc) + P.current = startloc + P.starting = startloc + P.firer = src + P.yo = marker.y - startloc.y + P.xo = marker.x - startloc.x + if(target) + P.original = target + else + P.original = marker + P.fire() + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/random_shots() + var/turf/U = get_turf(src) + playsound(U, 'sound/magic/invoke_general.ogg', 300, 1, 5) + for(var/T in RANGE_TURFS(12, U) - U) + if(prob(5)) + shoot_projectile(T) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast() + playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2) + var/turf/T = get_turf(target) + newtonian_move(get_dir(T, targets_from)) + for(var/turf/turf in range(1, T)) + shoot_projectile(turf) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/dir_shots(list/dirs) + if(!islist(dirs)) + dirs = alldirs.Copy() + playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2) + for(var/d in dirs) + var/turf/E = get_step(src, d) + shoot_projectile(E) + +/mob/living/simple_animal/hostile/megafauna/colossus/proc/telegraph() + for(var/mob/M in range(10,src)) + if(M.client) + flash_color(M.client, rgb(200, 0, 0), 1) + shake_camera(M, 4, 3) + playsound(get_turf(src),'sound/magic/narsie_attack.ogg', 200, 1) + +/obj/item/projectile/colossus + name ="death bolt" + icon_state= "chronobolt" + damage = 25 + armour_penetration = 100 + speed = 2 + eyeblur = 0 + damage_type = BRUTE + pass_flags = PASSTABLE + +/obj/item/projectile/colossus/on_hit(atom/target, blocked = 0) + . = ..() + if(isturf(target) || isobj(target)) + target.ex_act(2) + +/obj/item/device/gps/internal/colossus + icon_state = null + gpstag = "Angelic Signal" + desc = "Get in the fucking robot." + invisibility = 100 + +#undef MEDAL_PREFIX diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm new file mode 100644 index 00000000000..5afa7613c78 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -0,0 +1,278 @@ +#define MEDAL_PREFIX "Drake" +/* + +ASH DRAKE + +Ash drakes spawn randomly wherever a lavaland creature is able to spawn. They are the draconic guardians of the Necropolis. + +It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage. + +Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast. +It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs. +The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage. + - Sometimes it will chain these swooping attacks over and over, making swiftness a necessity. + +When an ash drake dies, it leaves behind a chest that can contain four things: + 1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power + 2. A lava staff that allows its wielder to create lava + 3. A spellbook and wand of fireballs + 4. A bottle of dragon's blood with several effects, including turning its imbiber into a drake themselves. + +When butchered, they leave behind diamonds, sinew, bone, and ash drake hide. Ash drake hide can be used to create a hooded cloak that protects its wearer from ash storms. + +Difficulty: Medium + +*/ + +/mob/living/simple_animal/hostile/megafauna/dragon + name = "ash drake" + desc = "Guardians of the necropolis." + health = 2500 + maxHealth = 2500 + attacktext = "chomps" + attack_sound = 'sound/misc/demon_attack1.ogg' + icon_state = "dragon" + icon_living = "dragon" + icon_dead = "dragon_dead" + friendly = "stares down" + icon = 'icons/mob/lavaland/dragon.dmi' + speak_emote = list("roars") + armour_penetration = 40 + melee_damage_lower = 40 + melee_damage_upper = 40 + speed = 1 + move_to_delay = 10 + ranged = 1 + pixel_x = -16 + loot = list(/obj/structure/closet/crate/necropolis/dragon) + butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) + var/swooping = 0 + var/swoop_cooldown = 0 + medal_type = MEDAL_PREFIX + score_type = DRAKE_SCORE + deathmessage = "collapses into a pile of bones, its flesh sloughing away." + death_sound = 'sound/misc/demon_dies.ogg' + +/mob/living/simple_animal/hostile/megafauna/dragon/New() + ..() + internal_gps = new/obj/item/device/gps/internal/dragon(src) + +/mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target) + if(severity == 3) + return + ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount) + if(swooping) + return 0 + return ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget() + if(!swooping) + ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/DestroySurroundings() + if(!swooping) + ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/Move() + if(!swooping) + ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/Goto(target, delay, minimum_distance) + if(!swooping) + ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/Process_Spacemove(movement_dir = 0) + return 1 + +/obj/effect/overlay/temp/fireball + icon = 'icons/obj/wizard.dmi' + icon_state = "fireball" + name = "fireball" + desc = "Get out of the way!" + layer = 6 + randomdir = 0 + duration = 12 + pixel_z = 500 + +/obj/effect/overlay/temp/fireball/New(loc) + ..() + animate(src, pixel_z = 0, time = 12) + +/obj/effect/overlay/temp/target + icon = 'icons/mob/actions.dmi' + icon_state = "sniper_zoom" + layer = MOB_LAYER - 0.1 + luminosity = 2 + duration = 12 + +/obj/effect/overlay/temp/dragon_swoop + name = "certain death" + desc = "Don't just stand there, move!" + icon = 'icons/effects/96x96.dmi' + icon_state = "landing" + layer = MOB_LAYER - 0.1 + pixel_x = -32 + pixel_y = -32 + color = "#FF0000" + duration = 10 + +/obj/effect/overlay/temp/target/ex_act() + return + +/obj/effect/overlay/temp/target/New(loc) + ..() + spawn(0) + fall() + +/obj/effect/overlay/temp/target/proc/fall() + var/turf/T = get_turf(src) + playsound(T,'sound/magic/Fireball.ogg', 200, 1) + new /obj/effect/overlay/temp/fireball(T) + sleep(12) + explosion(T, 0, 0, 1, 0, 0, 0, 1) + +/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() + anger_modifier = Clamp(((maxHealth - health)/50),0,20) + ranged_cooldown = world.time + ranged_cooldown_time + if(swooping) + fire_rain() + return + + if(prob(15 + anger_modifier) && !client) + if(health < maxHealth/2) + spawn(0) + swoop_attack(1) + else + fire_rain() + + else if(prob(10+anger_modifier) && !client) + if(health > maxHealth/2) + spawn(0) + swoop_attack(0) + else + spawn(0) + triple_swoop(0) + else + fire_walls() + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain() + visible_message("Fire rains from the sky!") + for(var/turf/turf in range(12,get_turf(src))) + if(prob(10)) + new /obj/effect/overlay/temp/target(turf) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls() + playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1) + + for(var/d in cardinal) + spawn(0) + fire_wall(d) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir) + var/list/hit_things = list(src) + var/turf/E = get_edge_target_turf(src, dir) + var/range = 10 + var/turf/previousturf = get_turf(src) + for(var/turf/J in getline(src,E)) + if(!range || !previousturf.CanAtmosPass(J)) + break + range-- + new /obj/effect/hotspot(J) + J.hotspot_expose(700,50,1) + for(var/mob/living/L in J.contents - hit_things) + L.adjustFireLoss(20) + to_chat(L, "You're hit by the drake's fire breath!") + hit_things += L + previousturf = J + sleep(1) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop() + swoop_attack() + swoop_attack() + swoop_attack() + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target) + if(stat || swooping) + return + swoop_cooldown = world.time + 200 + var/atom/swoop_target + if(manual_target) + swoop_target = manual_target + else + swoop_target = target + stop_automated_movement = TRUE + swooping = 1 + density = 0 + icon_state = "swoop" + visible_message("[src] swoops up high!") + if(prob(50)) + animate(src, pixel_x = 500, pixel_z = 500, time = 10) + else + animate(src, pixel_x = -500, pixel_z = 500, time = 10) + sleep(30) + + var/turf/tturf + if(fire_rain) + fire_rain() + + icon_state = "dragon" + if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z) + tturf = get_turf(swoop_target) + else + tturf = get_turf(src) + forceMove(tturf) + new /obj/effect/overlay/temp/dragon_swoop(tturf) + animate(src, pixel_x = initial(pixel_x), pixel_z = 0, time = 10) + sleep(10) + playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1) + for(var/mob/living/L in orange(1, src)) + if(L.stat) + visible_message("[src] slams down on [L], crushing them!") + L.gib() + else + L.adjustBruteLoss(75) + if(L && !qdeleted(L)) // Some mobs are deleted on death + var/throw_dir = get_dir(src, L) + if(L.loc == loc) + throw_dir = pick(alldirs) + var/throwtarget = get_edge_target_turf(src, throw_dir) + L.throw_at_fast(throwtarget, 3) + visible_message("[L] is thrown clear of [src]!") + + for(var/mob/M in range(7, src)) + shake_camera(M, 15, 1) + + stop_automated_movement = FALSE + swooping = 0 + density = 1 + +/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A) + if(!istype(A)) + return + if(swoop_cooldown >= world.time) + to_chat(src, "You need to wait 20 seconds between swoop attacks!") + return + swoop_attack(1, A) + +/obj/item/device/gps/internal/dragon + icon_state = null + gpstag = "Fiery Signal" + desc = "Here there be dragons." + invisibility = 100 + +/mob/living/simple_animal/hostile/megafauna/dragon/lesser + name = "lesser ash drake" + maxHealth = 200 + health = 200 + faction = list("neutral") + melee_damage_upper = 30 + melee_damage_lower = 30 + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + loot = list() + +/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype) + return + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm new file mode 100644 index 00000000000..dfb9948a1e3 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -0,0 +1,611 @@ +#define MEDAL_PREFIX "Hierophant" +/* + +The Hierophant + +The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be. + +The text this boss speaks is ROT4, use ROT22 to decode + +The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health; +- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time. + INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target. + INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health. +- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts. + INTENSITY EFFECT: Creates a second, slower chaser. +- Creates an expanding AoE burst. +- INTENSE ATTACKS: + If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points. + As above, but does so multiple times if below half health. + Rapidly creates Cross Blasts under a target. + If chasers are off cooldown, creates four high-speed chasers. +- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target. + +Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed. + +When The Hierophant dies, it leaves behind its staff, which, while much weaker than when wielded by The Hierophant itself, is still quite effective. +- The staff can place a teleport rune, allowing the user to teleport themself and their allies to the rune. + +Difficulty: Hard + +*/ + +/mob/living/simple_animal/hostile/megafauna/hierophant + name = "Hierophant" + desc = "An ancient, powerful priest-like being wielding a mighty staff." + health = 2500 + maxHealth = 2500 + attacktext = "clubs" + //attack_sound = 'sound/weapons/sonic_jackhammer.ogg' + attack_sound = "swing_hit" + icon_state = "hierophant" + icon_living = "hierophant" + friendly = "stares down" + icon = 'icons/mob/lavaland/hierophant.dmi' + faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house + speak_emote = list("preaches") + armour_penetration = 50 + melee_damage_lower = 10 + melee_damage_upper = 10 + speed = 1 + move_to_delay = 10 + ranged = 1 + pixel_x = -16 + ranged_cooldown_time = 40 + aggro_vision_range = 23 + loot = list(/obj/item/weapon/hierophant_staff) + wander = FALSE + var/burst_range = 3 //range on burst aoe + var/beam_range = 5 //range on cross blast beams + var/chaser_speed = 3 //how fast chasers are currently + var/chaser_cooldown = 101 //base cooldown/cooldown var between spawning chasers + var/major_attack_cooldown = 60 //base cooldown for major attacks + var/blinking = FALSE //if we're doing something that requires us to stand still and not attack + var/obj/effect/hierophant/spawned_rune //the rune we teleport back to + var/timeout_time = 15 //after this many Life() ticks with no target, we return to our rune + var/did_reset = TRUE //if we timed out, returned to our rune, and healed some + //var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...") + //var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.") + medal_type = MEDAL_PREFIX + score_type = BIRD_SCORE + del_on_death = TRUE + death_sound = 'sound/magic/Repulse.ogg' + +/mob/living/simple_animal/hostile/megafauna/hierophant/New() + ..() + internal_gps = new/obj/item/device/gps/internal/hierophant(src) + spawned_rune = new(loc) + +/mob/living/simple_animal/hostile/megafauna/hierophant/Life() + . = ..() + if(. && spawned_rune && !client) + if(target || loc == spawned_rune.loc) + timeout_time = initial(timeout_time) + else + timeout_time-- + if(timeout_time <= 0 && !did_reset) + did_reset = TRUE + //visible_message("\"Vixyvrmrk xs fewi...\"") + blink(spawned_rune) + adjustHealth(min((health - maxHealth) * 0.5, -50)) //heal for 50% of our missing health + wander = FALSE + /*if(health > maxHealth * 0.9) + visible_message("\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"") + else + visible_message("\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"")*/ + +/mob/living/simple_animal/hostile/megafauna/hierophant/death() + if(health > 0 || stat == DEAD) + return + else + stat = DEAD + blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff. + animate(src, alpha = 0, color = "660099", time = 20, easing = EASE_OUT) + burst_range = 10 + //visible_message("\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"") + visible_message("[src] disappears in a massive burst of magic, leaving only its staff.") + burst(get_turf(src)) + ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy() + qdel(spawned_rune) + . = ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L) + for(var/obj/item/W in L) + if(!L.unEquip(W)) + qdel(W) + /*visible_message( + "\"[pick(kill_phrases)]\"\n[src] annihilates [L]!", + "You annihilate [L], restoring your health!")*/ + visible_message( + "\"Caw.\"\n[src] annihilates [L]!", + "You annihilate [L], restoring your health!") + adjustHealth(-L.maxHealth*0.5) + L.dust() + +/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target) + var/targets_the_same = (new_target == target) + . = ..() + if(. && target && !targets_the_same) + visible_message("\"[pick(target_phrases)]\"")*/ + +/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount) + . = ..() + if(src && amount > 0 && !blinking) + wander = TRUE + did_reset = FALSE + +/mob/living/simple_animal/hostile/megafauna/hierophant/AttackingTarget() + if(!blinking) + if(target && isliving(target)) + spawn(0) + melee_blast(get_turf(target)) //melee attacks on living mobs produce a 3x3 blast + ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings() + if(!blinking) + ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/Move() + if(!blinking) + /*if(!stat) + playsound(loc, 'sound/mecha/mechmove04.ogg', 150, 1, -4)*/ + ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance) + wander = TRUE + if(!blinking) + ..() + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall + did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall + anger_modifier = Clamp(((maxHealth - health) / 42),0,50) + burst_range = initial(burst_range) + round(anger_modifier * 0.08) + beam_range = initial(beam_range) + round(anger_modifier * 0.12) + +/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire() + calculate_rage() + var/target_is_slow = FALSE + if(isliving(target)) + var/mob/living/L = target + if(!blinking && L.stat == DEAD && get_dist(src, L) > 2) + blink(L) + return + if(L.movement_delay() > 1.5) + target_is_slow = TRUE + chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5) + if(blinking) + return + ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger. + + if(prob(anger_modifier * 0.75)) //major ranged attack + var/list/possibilities = list() + var/cross_counter = 1 + round(anger_modifier * 0.12) + if(cross_counter > 1) + possibilities += "cross_blast_spam" + if(get_dist(src, target) > 2) + possibilities += "blink_spam" + if(chaser_cooldown < world.time) + if(prob(anger_modifier * 2)) + possibilities = list("chaser_swarm") + else + possibilities += "chaser_swarm" + if(possibilities.len) + ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) //we didn't cancel out of an attack, use the higher cooldown + var/blink_counter = 1 + round(anger_modifier * 0.08) + switch(pick(possibilities)) + if("blink_spam") //blink either once or multiple times. + if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1) + //visible_message("\"Mx ampp rsx iwgeti.\"") + animate(src, color = "#660099", time = 6) + while(health && target && blink_counter) + if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now + break + blink_counter-- + blinking = FALSE + blink(target) + blinking = TRUE + sleep(5) + animate(src, color = initial(color), time = 8) + sleep(8) + blinking = FALSE + else + blink(target) + if("cross_blast_spam") //fire a lot of cross blasts at a target. + //visible_message("\"Piezi mx rsalivi xs vyr.\"") + blinking = TRUE + animate(src, color = "#660099", time = 6) + while(health && target && cross_counter) + cross_counter-- + var/delay = 6 + if(prob(60)) + spawn(0) + cardinal_blasts(target) + else + spawn(0) + diagonal_blasts(target) + delay = 5 //this one isn't so mean, so do the next one faster(if there is one) + sleep(delay) + animate(src, color = initial(color), time = 8) + sleep(8) + blinking = FALSE + if("chaser_swarm") //fire four fucking chasers at a target and their friends. + //visible_message("\"Mx gerrsx lmhi.\"") + blinking = TRUE + animate(src, color = "#660099", time = 10) + var/list/targets = ListTargets() + var/list/cardinal_copy = cardinal.Copy() + while(health && targets.len && cardinal_copy.len) + var/mob/living/pickedtarget = pick(targets) + if(targets.len > 4) + pickedtarget = pick_n_take(targets) + if(pickedtarget.stat == DEAD) + pickedtarget = target + var/obj/effect/overlay/temp/hierophant/chaser/C = new /obj/effect/overlay/temp/hierophant/chaser(loc, src, pickedtarget, chaser_speed, FALSE) + C.moving = 3 + C.moving_dir = pick_n_take(cardinal_copy) + sleep(10) + chaser_cooldown = world.time + initial(chaser_cooldown) + animate(src, color = initial(color), time = 8) + sleep(8) + blinking = FALSE + return + + if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2) + blink(target) + + else if(prob(70 - anger_modifier)) //a cross blast of some type + if(prob(anger_modifier)) //at us? + if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs + spawn(0) + alldir_blasts(src) + else if(prob(60)) + spawn(0) + cardinal_blasts(src) + else + spawn(0) + diagonal_blasts(src) + else //at them? + if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs + spawn(0) + alldir_blasts(target) + else if(prob(60)) + spawn(0) + cardinal_blasts(target) + else + spawn(0) + diagonal_blasts(target) + else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some! + var/obj/effect/overlay/temp/hierophant/chaser/C = new /obj/effect/overlay/temp/hierophant/chaser(loc, src, target, chaser_speed, FALSE) + chaser_cooldown = world.time + initial(chaser_cooldown) + if((prob(anger_modifier) || target.Adjacent(src)) && target != src) + var/obj/effect/overlay/temp/hierophant/chaser/OC = new /obj/effect/overlay/temp/hierophant/chaser(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE) + OC.moving = 4 + OC.moving_dir = pick(cardinal - C.moving_dir) + else //just release a burst of power + spawn(0) + burst(get_turf(src)) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay + var/turf/T = get_turf(victim) + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph/diagonal(T, src) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + new /obj/effect/overlay/temp/hierophant/blast(T, src, FALSE) + for(var/d in diagonals) + spawn(0) + blast_wall(T, d) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay + var/turf/T = get_turf(victim) + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph/cardinal(T, src) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + new /obj/effect/overlay/temp/hierophant/blast(T, src, FALSE) + for(var/d in cardinal) + spawn(0) + blast_wall(T, d) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay + var/turf/T = get_turf(victim) + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph(T, src) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + new /obj/effect/overlay/temp/hierophant/blast(T, src, FALSE) + for(var/d in alldirs) + spawn(0) + blast_wall(T, d) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, dir) //make a wall of blasts beam_range tiles long + var/range = beam_range + var/turf/previousturf = T + var/turf/J = get_step(previousturf, dir) + for(var/i in 1 to range) + new /obj/effect/overlay/temp/hierophant/blast(J, src, FALSE) + previousturf = J + J = get_step(previousturf, dir) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink(mob/victim) //blink to a target + if(blinking || !victim) + return + var/turf/T = get_turf(victim) + var/turf/source = get_turf(src) + new /obj/effect/overlay/temp/hierophant/telegraph(T, src) + new /obj/effect/overlay/temp/hierophant/telegraph(source, src) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1) + playsound(source,'sound/magic/blink.ogg', 200, 1) + //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1) + blinking = TRUE + sleep(2) //short delay before we start... + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, src) + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(source, src) + for(var/t in RANGE_TURFS(1, T)) + var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, src, FALSE) + B.damage = 30 + for(var/t in RANGE_TURFS(1, source)) + var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, src, FALSE) + B.damage = 30 + animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out + sleep(1) + visible_message("[src] fades out!") + density = FALSE + sleep(2) + forceMove(T) + sleep(1) + animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN + sleep(1) + density = TRUE + visible_message("[src] fades in!") + sleep(1) //at this point the blasts we made detonate + blinking = FALSE + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/melee_blast(mob/victim) //make a 3x3 blast around a target + if(!victim) + return + var/turf/T = get_turf(victim) + if(!T) + return + new /obj/effect/overlay/temp/hierophant/telegraph(T, src) + playsound(T,'sound/magic/blink.ogg', 200, 1) + //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + sleep(2) + for(var/t in RANGE_TURFS(1, T)) + new /obj/effect/overlay/temp/hierophant/blast(t, src, FALSE) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts + playsound(original,'sound/magic/blink.ogg', 200, 1) + //playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1) + var/last_dist = 0 + for(var/t in spiral_range_turfs(burst_range, original)) + var/turf/T = t + if(!T) + continue + var/dist = get_dist(original, T) + if(dist > last_dist) + last_dist = dist + sleep(1 + (burst_range - last_dist) * 0.5) //gets faster as it gets further out + new /obj/effect/overlay/temp/hierophant/blast(T, src, FALSE) + +/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck) + if(!istype(A) || get_dist(A, src) <= 2) + return + blink(A) + +//Hierophant overlays +/obj/effect/overlay/temp/hierophant + layer = MOB_LAYER - 0.1 + var/mob/living/caster //who made this, anyway + +/obj/effect/overlay/temp/hierophant/New(loc, new_caster) + ..() + if(new_caster) + caster = new_caster + +/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds. + duration = 98 + var/mob/living/target //what it's following + var/turf/targetturf //what turf the target is actually on + var/moving_dir //what dir it's moving in + var/previous_moving_dir //what dir it was moving in before that + var/more_previouser_moving_dir //what dir it was moving in before THAT + var/moving = 0 //how many steps to move before recalculating + var/standard_moving_before_recalc = 4 //how many times we step before recalculating normally + var/tiles_per_step = 1 //how many tiles we move each step + var/speed = 3 //how many deciseconds between each step + var/currently_seeking = FALSE + var/friendly_fire_check = FALSE //if blasts produced apply friendly fire + +/obj/effect/overlay/temp/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire) + ..() + target = new_target + friendly_fire_check = is_friendly_fire + if(new_speed) + speed = new_speed + spawn(0) + seek_target() + +/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir() + . = get_cardinal_dir(src, targetturf) + if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate + var/list/cardinal_copy = cardinal.Copy() + cardinal_copy -= more_previouser_moving_dir + . = pick(cardinal_copy) + +/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target() + if(!currently_seeking) + currently_seeking = TRUE + targetturf = get_turf(target) + while(target && src && !qdeleted(src) && currently_seeking && x && y && targetturf) //can this target actually be sook out + if(!moving) //we're out of tiles to move, find more and where the target is! + more_previouser_moving_dir = previous_moving_dir + previous_moving_dir = moving_dir + moving_dir = get_target_dir() + var/standard_target_dir = get_cardinal_dir(src, targetturf) + if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0) + moving = 1 //we would be repeating, only move a tile before checking + else + moving = standard_moving_before_recalc + if(moving) //move in the dir we're moving in right now + var/turf/T = get_turf(src) + for(var/i in 1 to tiles_per_step) + var/maybe_new_turf = get_step(T, moving_dir) + if(maybe_new_turf) + T = maybe_new_turf + else + break + forceMove(T) + make_blast() //make a blast, too + moving-- + sleep(speed) + targetturf = get_turf(target) + +/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast() + new /obj/effect/overlay/temp/hierophant/blast(loc, caster, friendly_fire_check) + +/obj/effect/overlay/temp/hierophant/telegraph + icon = 'icons/effects/96x96.dmi' + icon_state = "hierophant_telegraph" + pixel_x = -32 + pixel_y = -32 + duration = 3 + +/obj/effect/overlay/temp/hierophant/telegraph/diagonal + icon_state = "hierophant_telegraph_diagonal" + +/obj/effect/overlay/temp/hierophant/telegraph/cardinal + icon_state = "hierophant_telegraph_cardinal" + +/obj/effect/overlay/temp/hierophant/telegraph/teleport + icon_state = "hierophant_telegraph_teleport" + duration = 9 + +/obj/effect/overlay/temp/hierophant/blast + icon = 'icons/effects/effects.dmi' + icon_state = "hierophant_blast" + name = "vortex blast" + luminosity = 1 + desc = "Get out of the way!" + duration = 9 + var/damage = 10 //how much damage do we do? + var/list/hit_things = list() //we hit these already, ignore them + var/friendly_fire_check = FALSE + var/bursting = FALSE //if we're bursting and need to hit anyone crossing us + +/obj/effect/overlay/temp/hierophant/blast/New(loc, new_caster, friendly_fire) + ..() + friendly_fire_check = friendly_fire + if(new_caster) + hit_things += new_caster + if(ismineralturf(loc)) //drill mineral turfs + var/turf/simulated/mineral/M = loc + M.gets_drilled(caster) + spawn(0) + blast() + +/obj/effect/overlay/temp/hierophant/blast/proc/blast() + var/turf/T = get_turf(src) + if(!T) + return + playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound + sleep(6) //wait a little + bursting = TRUE + do_damage(T) //do damage and mark us as bursting + sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds + bursting = FALSE //we no longer damage crossers + +/obj/effect/overlay/temp/hierophant/blast/Crossed(atom/movable/AM) + ..() + if(bursting) + do_damage(get_turf(src)) + +/obj/effect/overlay/temp/hierophant/blast/proc/do_damage(turf/T) + for(var/mob/living/L in T.contents - hit_things) //find and damage mobs... + hit_things += L + if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD) + continue + if(L.client) + flash_color(L.client, "#660099", 1) + playsound(L,'sound/weapons/sear.ogg', 50, 1, -4) + to_chat(L, "You're struck by a [name]!") + var/limb_to_hit = pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") + var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") + L.apply_damage(damage, BURN, limb_to_hit, armor) + if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid)) + L.adjustBruteLoss(damage) + add_logs(caster, L, "struck with a [name]") + for(var/obj/mecha/M in T.contents - hit_things) //and mechs. + hit_things += M + if(M.occupant) + if(friendly_fire_check && caster && caster.faction_check(M.occupant)) + continue + to_chat(M.occupant, "Your [M.name] is struck by a [name]!") + playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) + M.take_damage(damage, BURN, 0, 0) + +/obj/effect/hierophant + name = "hierophant rune" + desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will." + icon = 'icons/obj/rune.dmi' + icon_state = "hierophant" + layer = 2.5 + anchored = TRUE + color = "#CC00FF" + +/obj/effect/hierophant/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/hierophant_staff)) + var/obj/item/weapon/hierophant_staff/H = I + if(H.rune == src) + to_chat(user, "You start removing your hierophant rune...") + H.timer = world.time + 51 + if(do_after(user, 50, target = src)) + playsound(src,'sound/magic/Blind.ogg', 200, 1, -4) + new /obj/effect/overlay/temp/hierophant/telegraph/teleport(get_turf(src), user) + to_chat(user, "You touch the rune with the staff, dispelling it!") + H.rune = null + user.update_action_buttons_icon() + qdel(src) + else + H.timer = world.time + else + to_chat(user, "You touch the rune with the staff, but nothing happens.") + + else + ..() + +/obj/item/device/gps/internal/hierophant + icon_state = null + gpstag = "Zealous Signal" + desc = "Heed its words." + invisibility = 100 + +/turf/simulated/indestructible/hierophant + icon_state = "hierophant1" + oxygen = 14 + nitrogen = 23 + temperature = 300 + desc = "A floor with a square pattern. It's faintly cool to the touch." + +/turf/simulated/indestructible/hierophant/New() + ..() + if(prob(50)) + icon_state = "hierophant2" + +/turf/simulated/indestructible/riveted/hierophant + name = "wall" + desc = "A wall made out of smooth, cold stone." + icon = 'icons/turf/walls/hierophant_wall.dmi' + icon_state = "hierophant" + smooth = SMOOTH_TRUE + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm new file mode 100644 index 00000000000..89119952f60 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -0,0 +1,142 @@ +#define MEDAL_PREFIX "Legion" +/* + +LEGION + +Legion spawns from the necropolis gate in the far north of lavaland. It is the guardian of the Necropolis and emerges from within whenever an intruder tries to enter through its gate. +Whenever Legion emerges, everything in lavaland will receive a notice via color, audio, and text. This is because Legion is powerful enough to slaughter the entirety of lavaland with little effort. + +It has two attack modes that it constantly rotates between. + +In ranged mode, it will behave like a normal legion - retreating when possible and firing legion skulls at the target. +In charge mode, it will spin and rush its target, attacking with melee whenever possible. + +When Legion dies, it drops a staff of storms, which allows its wielder to call and disperse ash storms at will and functions as a powerful melee weapon. + +Difficulty: Medium + +*/ + +/mob/living/simple_animal/hostile/megafauna/legion + name = "Legion" + health = 800 + maxHealth = 800 + icon_state = "legion" + icon_living = "legion" + desc = "One of many." + icon = 'icons/mob/lavaland/legion.dmi' + attacktext = "chomps" + attack_sound = 'sound/misc/demon_attack1.ogg' + speak_emote = list("echoes") + armour_penetration = 50 + melee_damage_lower = 25 + melee_damage_upper = 25 + speed = 2 + ranged = 1 + del_on_death = 1 + retreat_distance = 5 + minimum_distance = 5 + ranged_cooldown_time = 20 + var/size = 5 + var/charging = 0 + medal_type = MEDAL_PREFIX + score_type = LEGION_SCORE + pixel_y = -90 + pixel_x = -75 + loot = list(/obj/item/stack/sheet/bone = 3) + vision_range = 13 + elimination = 1 + idle_vision_range = 13 + appearance_flags = 0 + mouse_opacity = 1 + stat_attack = 1 // Overriden from /tg/ - otherwise Legion starts chasing its minions + +/mob/living/simple_animal/hostile/megafauna/legion/New() + ..() + internal_gps = new/obj/item/device/gps/internal/legion(src) + +/mob/living/simple_animal/hostile/megafauna/legion/AttackingTarget() + ..() + if(ishuman(target)) + var/mob/living/L = target + if(L.stat == UNCONSCIOUS) + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc) + A.infest(L) + +/mob/living/simple_animal/hostile/megafauna/legion/OpenFire(the_target) + if(world.time >= ranged_cooldown && !charging) + if(prob(75)) + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/A = new(loc) + A.GiveTarget(target) + A.friends = friends + A.faction = faction + ranged_cooldown = world.time + ranged_cooldown_time + else + visible_message("[src] charges!") + SpinAnimation(speed = 20, loops = 5) + ranged = 0 + retreat_distance = 0 + minimum_distance = 0 + speed = 0 + charging = 1 + spawn(50) + reset_charge() + +/mob/living/simple_animal/hostile/megafauna/legion/proc/reset_charge() + ranged = 1 + retreat_distance = 5 + minimum_distance = 5 + speed = 2 + charging = 0 + +/mob/living/simple_animal/hostile/megafauna/legion/death() + if(health > 0) + return + if(size > 1) + adjustHealth(-maxHealth) //heal ourself to full in prep for splitting + var/mob/living/simple_animal/hostile/megafauna/legion/L = new(loc) + + L.maxHealth = maxHealth * 0.6 + maxHealth = L.maxHealth + + L.health = L.maxHealth + health = maxHealth + + size-- + L.size = size + + L.resize = L.size * 0.2 + transform = initial(transform) + resize = size * 0.2 + + L.update_transform() + update_transform() + + L.faction = faction.Copy() + + L.GiveTarget(target) + + visible_message("[src] splits in twain!") + else + var/last_legion = TRUE + for(var/mob/living/simple_animal/hostile/megafauna/legion/other in mob_list) + if(other != src) + last_legion = FALSE + break + if(last_legion) + loot = list(/obj/item/weapon/staff/storm) + elimination = 0 + else if(prob(5)) + loot = list(/obj/structure/closet/crate/necropolis/tendril) + ..() + +/mob/living/simple_animal/hostile/megafauna/legion/Process_Spacemove(movement_dir = 0) + return 1 + +/obj/item/device/gps/internal/legion + icon_state = null + gpstag = "Echoing Signal" + desc = "The message repeats." + invisibility = 100 + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm new file mode 100644 index 00000000000..bd916532519 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -0,0 +1,231 @@ +#define MEDAL_PREFIX "Boss" + +/mob/living/simple_animal/hostile/megafauna + name = "megafauna" + desc = "Attack the weak point for massive damage." + health = 1000 + maxHealth = 1000 + a_intent = "harm" + sentience_type = SENTIENCE_BOSS + environment_smash = 3 + luminosity = 3 + faction = list("mining", "boss") + weather_immunities = list("lava","ash") + flying = 1 + robust_searching = 1 + ranged_ignores_vision = TRUE + stat_attack = 2 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + damage_coeff = list(BRUTE = 1, BURN = 0.5, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + minbodytemp = 0 + maxbodytemp = INFINITY + aggro_vision_range = 18 + idle_vision_range = 5 + environment_target_typecache = list( + /obj/machinery/door/window, + /obj/structure/window, + /obj/structure/closet, + /obj/structure/table, + /obj/structure/grille, + /obj/structure/girder, + /obj/structure/rack, + /obj/structure/barricade, + /obj/machinery/field, + /obj/machinery/power/emitter) + var/medal_type = MEDAL_PREFIX + var/score_type = BOSS_SCORE + var/elimination = 0 + var/anger_modifier = 0 + var/obj/item/device/gps/internal_gps + anchored = TRUE + mob_size = MOB_SIZE_LARGE + layer = MOB_LAYER + 0.5 //Looks weird with them slipping under mineral walls and cameras and shit otherwise + mouse_opacity = 2 // Easier to click on in melee, they're giant targets anyway + +/mob/living/simple_animal/hostile/megafauna/Destroy() + qdel(internal_gps) + . = ..() + +/mob/living/simple_animal/hostile/megafauna/death(gibbed) + if(health > 0) + return + else + if(!admin_spawned) + feedback_set_details("megafauna_kills","[initial(name)]") + if(!elimination) //used so the achievment only occurs for the last legion to die. + grant_achievement(medal_type,score_type) + ..() + +/mob/living/simple_animal/hostile/megafauna/gib() + if(health > 0) + return + else + ..() + +/mob/living/simple_animal/hostile/megafauna/dust() + if(health > 0) + return + else + ..() + +/mob/living/simple_animal/hostile/megafauna/AttackingTarget() + ..() + if(isliving(target)) + var/mob/living/L = target + if(L.stat != DEAD) + if(!client && ranged && ranged_cooldown <= world.time) + OpenFire() + else + devour(L) + +/mob/living/simple_animal/hostile/megafauna/onShuttleMove() + var/turf/oldloc = loc + . = ..() + if(!.) + return + var/turf/newloc = loc + message_admins("Megafauna [src] \ + (FLW) \ + moved via shuttle from ([oldloc.x], [oldloc.y], [oldloc.z]) to \ + ([newloc.x], [newloc.y], [newloc.z])") + +/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L) + if(!L) + return + visible_message( + "[src] devours [L]!", + "You feast on [L], restoring your health!") + if(!is_station_level(z) && !client) //NPC monsters won't heal while on station + adjustBruteLoss(-L.maxHealth/2) + L.gib() + +/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target) + switch(severity) + if(1) + adjustBruteLoss(250) + + if(2) + adjustBruteLoss(100) + + if(3) + adjustBruteLoss(50) + +/mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype,scoretype) + + if(medal_type == "Boss") //Don't award medals if the medal type isn't set + return + + if(admin_spawned) + return + + if(global.medal_hub && global.medal_pass && global.medals_enabled) + for(var/mob/living/L in view(7,src)) + if(L.stat) + continue + if(L.client) + var/client/C = L.client + var/suffixm = BOSS_KILL_MEDAL + UnlockMedal("Boss [suffixm]",C) + UnlockMedal("[medaltype] [suffixm]",C) + SetScore(BOSS_SCORE,C,1) + SetScore(score_type,C,1) + +/proc/UnlockMedal(medal,client/player) + + if(!player || !medal) + return + if(global.medal_hub && global.medal_pass && global.medals_enabled) + spawn() + var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass) + if(isnull(result)) + global.medals_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]") + message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!") + else if(result) + to_chat(player.mob, "Achievement unlocked: [medal]!") + + +/proc/SetScore(score,client/player,increment,force) + + if(!score || !player) + return + if(global.medal_hub && global.medal_pass && global.medals_enabled) + spawn() + var/list/oldscore = GetScore(score,player,1) + + if(increment) + if(!oldscore[score]) + oldscore[score] = 1 + else + oldscore[score] = (text2num(oldscore[score]) + 1) + else + oldscore[score] = force + + var/newscoreparam = list2params(oldscore) + + var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass) + + if(isnull(result)) + global.medals_enabled = FALSE + log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]") + message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!") + + +/proc/GetScore(score,client/player,returnlist) + + if(!score || !player) + return + if(global.medal_hub && global.medal_pass && global.medals_enabled) + + var/scoreget = world.GetScores(player.ckey, score, global.medal_hub, global.medal_pass) + if(isnull(scoreget)) + global.medals_enabled = FALSE + log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]") + message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!") + return + + var/list/scoregetlist = params2list(scoreget) + + if(returnlist) + return scoregetlist + else + return scoregetlist[score] + + +/proc/CheckMedal(medal,client/player) + + if(!player || !medal) + return + if(global.medal_hub && global.medal_pass && global.medals_enabled) + + var/result = world.GetMedal(medal, player, global.medal_hub, global.medal_pass) + + if(isnull(result)) + global.medals_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]") + message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!") + else if(result) + to_chat(player.mob, "[medal] is unlocked") + +/proc/LockMedal(medal,client/player) + + if(!player || !medal) + return + if(global.medal_hub && global.medal_pass && global.medals_enabled) + + var/result = world.ClearMedal(medal, player, global.medal_hub, global.medal_pass) + + if(isnull(result)) + global.medals_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]") + message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!") + else if(result) + message_admins("Medal: [medal] removed for [player.ckey]") + else + message_admins("Medal: [medal] was not found for [player.ckey]. Unable to clear.") + + +/proc/ClearScore(client/player) + world.SetScores(player.ckey, "", global.medal_hub, global.medal_pass) + +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index ac9b8562681..87754e1428a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -91,10 +91,6 @@ ..() icon_state = initial(icon_state) -/mob/living/simple_animal/hostile/mimic/crate/LostTarget() - ..() - icon_state = initial(icon_state) - /mob/living/simple_animal/hostile/mimic/crate/death(gibbed) var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate diff --git a/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm new file mode 100644 index 00000000000..3e6d98afd95 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/mining/goldgrub.dm @@ -0,0 +1,78 @@ +/mob/living/simple_animal/hostile/asteroid/goldgrub + name = "goldgrub" + desc = "A worm that grows fat from eating everything in its sight. Seems to enjoy precious metals and other shiny things, hence the name." + icon = 'icons/mob/animal.dmi' + icon_state = "Goldgrub" + icon_living = "Goldgrub" + icon_aggro = "Goldgrub_alert" + icon_dead = "Goldgrub_dead" + icon_gib = "syndicate_gib" + vision_range = 2 + aggro_vision_range = 9 + idle_vision_range = 2 + move_to_delay = 5 + friendly = "harmlessly rolls into" + maxHealth = 45 + health = 45 + harm_intent_damage = 5 + melee_damage_lower = 0 + melee_damage_upper = 0 + attacktext = "barrels into" + attack_sound = 'sound/weapons/punch1.ogg' + a_intent = I_HELP + speak_emote = list("screeches") + throw_message = "sinks in slowly, before being pushed out of " + status_flags = CANPUSH + search_objects = 1 + wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, + /obj/item/weapon/ore/uranium) + + var/chase_time = 100 + var/will_burrow = TRUE + +/mob/living/simple_animal/hostile/asteroid/goldgrub/New() + ..() + var/i = rand(1,3) + while(i) + loot += pick(/obj/item/weapon/ore/silver, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/diamond) + i-- + +/mob/living/simple_animal/hostile/asteroid/goldgrub/GiveTarget(new_target) + target = new_target + if(target != null) + if(istype(target, /obj/item/weapon/ore) && loot.len < 10) + visible_message("The [src.name] looks at [target.name] with hungry eyes.") + else if(isliving(target)) + Aggro() + visible_message("The [src.name] tries to flee from [target.name]!") + retreat_distance = 10 + minimum_distance = 10 + if(will_burrow) + spawn(chase_time) + Burrow() + +/mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget() + if(istype(target, /obj/item/weapon/ore)) + EatOre(target) + return + ..() + +/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/EatOre(var/atom/targeted_ore) + for(var/obj/item/weapon/ore/O in targeted_ore.loc) + if(loot.len < 10) + loot += O.type + qdel(O) + visible_message("The ore was swallowed whole!") + +/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time + if(!stat) + visible_message("The [src.name] buries into the ground, vanishing from sight!") + qdel(src) + +/mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(obj/item/projectile/P) + visible_message("The [P.name] was repelled by [src.name]'s girth!") + return + +/mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(damage) + idle_vision_range = 9 + . = ..() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm new file mode 100644 index 00000000000..517b71a3a6d --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm @@ -0,0 +1,320 @@ +/mob/living/simple_animal/hostile/asteroid/hivelord + name = "hivelord" + desc = "A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "Hivelord" + icon_living = "Hivelord" + icon_aggro = "Hivelord_alert" + icon_dead = "Hivelord_dead" + icon_gib = "syndicate_gib" + mouse_opacity = 2 + move_to_delay = 14 + ranged = 1 + vision_range = 5 + aggro_vision_range = 9 + idle_vision_range = 5 + speed = 3 + maxHealth = 75 + health = 75 + harm_intent_damage = 5 + melee_damage_lower = 0 + melee_damage_upper = 0 + attacktext = "lashes out at" + speak_emote = list("telepathically cries") + attack_sound = 'sound/weapons/pierce.ogg' + throw_message = "falls right through the strange body of the" + ranged_cooldown = 0 + ranged_cooldown_time = 20 + environment_smash = 0 + retreat_distance = 3 + minimum_distance = 3 + pass_flags = PASSTABLE + loot = list(/obj/item/organ/internal/hivelord_core) + var/brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood + +/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(the_target) + if(world.time >= ranged_cooldown) + var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/A = new brood_type(src.loc) + A.admin_spawned = admin_spawned + A.GiveTarget(target) + A.friends = friends + A.faction = faction.Copy() + ranged_cooldown = world.time + ranged_cooldown_time + +/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() + OpenFire() + +/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed) + mouse_opacity = 1 + ..(gibbed) + +/obj/item/organ/internal/hivelord_core + name = "hivelord remains" + desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly." + icon_state = "roro core 2" + flags = NOBLUDGEON + slot = "hivecore" + force = 0 + actions_types = list(/datum/action/item_action/organ_action/use) + var/inert = 0 + var/preserved = 0 + +/obj/item/organ/internal/hivelord_core/New() + ..() + addtimer(src, "inert_check", 2400) + +/obj/item/organ/internal/hivelord_core/proc/inert_check() + if(!owner && !preserved) + go_inert() + else + preserved(implanted = 1) + +/obj/item/organ/internal/hivelord_core/proc/preserved(implanted = 0) + inert = FALSE + preserved = TRUE + update_icon() + + if(implanted) + feedback_add_details("hivelord_core", "[type]|implanted") + else + feedback_add_details("hivelord_core", "[type]|stabilizer") + + +/obj/item/organ/internal/hivelord_core/proc/go_inert() + inert = TRUE + desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested." + feedback_add_details("hivelord_core", "[src.type]|inert") + update_icon() + +/obj/item/organ/internal/hivelord_core/ui_action_click() + owner.revive() + qdel(src) + +/obj/item/organ/internal/hivelord_core/on_life() + ..() + if(owner.health < config.health_threshold_crit) + ui_action_click() + +/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag && ishuman(target)) + var/mob/living/carbon/human/H = target + if(inert) + to_chat(user, "[src] has become inert, its healing properties are no more.") + return + else + if(H.stat == DEAD) + to_chat(user, "[src] are useless on the dead.") + return + if(H != user) + H.visible_message("[user] forces [H] to apply [src]... They quickly regenerate all injuries!") + feedback_add_details("hivelord_core","[src.type]|used|other") + else + to_chat(user, "You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.") + feedback_add_details("hivelord_core","[src.type]|used|self") + playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) + H.revive() + user.drop_item() + qdel(src) + ..() + +/obj/item/organ/internal/hivelord_core/prepare_eat() + return null + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood + name = "hivelord brood" + desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "Hivelordbrood" + icon_living = "Hivelordbrood" + icon_aggro = "Hivelordbrood" + icon_dead = "Hivelordbrood" + icon_gib = "syndicate_gib" + mouse_opacity = 2 + move_to_delay = 1 + friendly = "buzzes near" + vision_range = 10 + speed = 3 + maxHealth = 1 + health = 1 + flying = 1 + harm_intent_damage = 5 + melee_damage_lower = 2 + melee_damage_upper = 2 + attacktext = "slashes" + speak_emote = list("telepathically cries") + attack_sound = 'sound/weapons/pierce.ogg' + throw_message = "falls right through the strange body of the" + environment_smash = 0 + pass_flags = PASSTABLE + del_on_death = 1 + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/New() + ..() + addtimer(src, "death", 100) + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood + name = "blood brood" + desc = "A living string of blood and alien materials." + icon_state = "bloodbrood" + icon_living = "bloodbrood" + icon_aggro = "bloodbrood" + attacktext = "pierces" + color = "#C80000" + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/death() + if(loc) // Splash the turf we are on with blood + reagents.reaction(get_turf(src)) + ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/New() + create_reagents(30) + ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/AttackingTarget() + ..() + if(iscarbon(target)) + transfer_reagents(target, 1) + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/attack_hand(mob/living/carbon/human/M) + if("\ref[M]" in faction) + reabsorb_host(M) + else + return ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/attack_alien(mob/living/carbon/alien/humanoid/M) + if("\ref[M]" in faction) + reabsorb_host(M) + else + return ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/reabsorb_host(mob/living/carbon/C) + C.visible_message("[src] is reabsorbed by [C]'s body.", \ + "[src] is reabsorbed by your body.") + transfer_reagents(C) + death() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/transfer_reagents(mob/living/carbon/C, volume = 30) + if(!reagents.total_volume) + return + + volume = min(volume, reagents.total_volume) + + var/fraction = min(volume/reagents.total_volume, 1) + reagents.reaction(C, INGEST, fraction) + reagents.trans_to(C, volume) + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/proc/link_host(mob/living/carbon/human/H) + faction = list("\ref[src]", "\ref[H]") // Hostile to everyone except the host. + H.vessel.trans_to(src, 30) + color = mix_color_from_reagents(reagents.reagent_list) + +// Legion +/mob/living/simple_animal/hostile/asteroid/hivelord/legion + name = "legion" + desc = "You can still see what was once a human under the shifting mass of corruption." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "legion" + icon_living = "legion" + icon_aggro = "legion" + icon_dead = "legion" + icon_gib = "syndicate_gib" + melee_damage_lower = 15 + melee_damage_upper = 15 + attacktext = "lashes out at" + speak_emote = list("echoes") + attack_sound = 'sound/weapons/pierce.ogg' + throw_message = "bounces harmlessly off of" + loot = list(/obj/item/organ/internal/hivelord_core/legion) + brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion + del_on_death = 1 + stat_attack = 1 + robust_searching = 1 + var/mob/living/carbon/human/stored_mob + +/mob/living/simple_animal/hostile/asteroid/hivelord/legion/death(gibbed) + visible_message("The skulls on [src] wail in anger as they flee from their dying host!") + var/turf/T = get_turf(src) + if(T) + if(stored_mob) + stored_mob.forceMove(get_turf(src)) + stored_mob = null + else + new /obj/effect/landmark/corpse/damaged(T) + ..(gibbed) + + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion + name = "legion" + desc = "One of many." + icon = 'icons/mob/lavaland/lavaland_monsters.dmi' + icon_state = "legion_head" + icon_living = "legion_head" + icon_aggro = "legion_head" + icon_dead = "legion_head" + icon_gib = "syndicate_gib" + friendly = "buzzes near" + vision_range = 10 + maxHealth = 1 + health = 5 + harm_intent_damage = 5 + melee_damage_lower = 12 + melee_damage_upper = 12 + attacktext = "bites" + speak_emote = list("echoes") + attack_sound = 'sound/weapons/pierce.ogg' + throw_message = "is shrugged off by" + pass_flags = PASSTABLE + del_on_death = 1 + stat_attack = 1 + robust_searching = 1 + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life() + if(isturf(loc)) + for(var/mob/living/carbon/human/H in view(src,1)) //Only for corpse right next to/on same tile + if(H.stat == UNCONSCIOUS) + infest(H) + ..() + +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/proc/infest(mob/living/carbon/human/H) + visible_message("[name] burrows into the flesh of [H]!") + var/mob/living/simple_animal/hostile/asteroid/hivelord/legion/L = new(H.loc) + visible_message("[L] staggers to their feet!") + H.death() + H.adjustBruteLoss(1000) + L.stored_mob = H + H.forceMove(L) + qdel(src) + +/obj/item/organ/internal/hivelord_core/legion + name = "legion's soul" + desc = "A strange rock that still crackles with power... its \ + healing properties will soon become inert if not used quickly." + icon_state = "legion_soul" + +/obj/item/organ/internal/hivelord_core/legion/New() + ..() + update_icon() + +/obj/item/organ/internal/hivelord_core/legion/update_icon() + icon_state = inert ? "legion_soul_inert" : "legion_soul" + overlays.Cut() + if(!inert && !preserved) + overlays += image(icon, "legion_soul_crackle") + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/organ/internal/hivelord_core/legion/go_inert() + . = ..() + desc = "[src] has become inert, it crackles no more and is useless for \ + healing injuries." + +/obj/item/organ/internal/hivelord_core/legion/preserved(implanted = 0) + ..() + desc = "[src] has been stabilized. It no longer crackles with power, but it's healing properties are preserved indefinitely." + +/obj/item/weapon/legion_skull + name = "legion's head" + desc = "The once living, now empty eyes of the former human's skull cut deep into your soul." + icon = 'icons/obj/mining.dmi' + icon_state = "skull" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 47c243e970e..f3ed8a34f51 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -58,7 +58,7 @@ projectilesound = 'sound/weapons/pierce.ogg' ranged = 1 ranged_message = "stares" - ranged_cooldown_cap = 20 + ranged_cooldown_time = 30 throw_message = "does nothing against the hard shell of" vision_range = 2 speed = 3 @@ -71,7 +71,6 @@ a_intent = I_HARM speak_emote = list("chitters") attack_sound = 'sound/weapons/bladeslice.ogg' - ranged_cooldown_cap = 4 aggro_vision_range = 9 idle_vision_range = 2 turns_per_move = 5 @@ -104,232 +103,6 @@ if(3.0) adjustBruteLoss(110) -/mob/living/simple_animal/hostile/asteroid/goldgrub - name = "goldgrub" - desc = "A worm that grows fat from eating everything in its sight. Seems to enjoy precious metals and other shiny things, hence the name." - icon = 'icons/mob/animal.dmi' - icon_state = "Goldgrub" - icon_living = "Goldgrub" - icon_aggro = "Goldgrub_alert" - icon_dead = "Goldgrub_dead" - icon_gib = "syndicate_gib" - vision_range = 2 - aggro_vision_range = 9 - idle_vision_range = 2 - move_to_delay = 5 - friendly = "harmlessly rolls into" - maxHealth = 45 - health = 45 - harm_intent_damage = 5 - melee_damage_lower = 0 - melee_damage_upper = 0 - attacktext = "barrels into" - attack_sound = 'sound/weapons/punch1.ogg' - a_intent = I_HELP - speak_emote = list("screeches") - throw_message = "sinks in slowly, before being pushed out of " - status_flags = CANPUSH - search_objects = 1 - wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, - /obj/item/weapon/ore/uranium) - - var/list/ore_types_eaten = list() - var/alerted = 0 - var/ore_eaten = 1 - var/chase_time = 100 - var/will_burrow = 1 - -/mob/living/simple_animal/hostile/asteroid/goldgrub/New() - ..() - ore_types_eaten += pick(/obj/item/weapon/ore/silver, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/uranium, /obj/item/weapon/ore/diamond) - ore_eaten = rand(1,3) - -/mob/living/simple_animal/hostile/asteroid/goldgrub/GiveTarget(var/new_target) - target = new_target - if(target != null) - if(istype(target, /obj/item/weapon/ore)) - visible_message("The [src.name] looks at [target.name] with hungry eyes.") - else if(isliving(target)) - Aggro() - visible_message("The [src.name] tries to flee from [target.name]!") - retreat_distance = 10 - minimum_distance = 10 - Burrow() - -/mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget() - if(istype(target, /obj/item/weapon/ore)) - EatOre(target) - return - ..() - -/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/EatOre(var/atom/targeted_ore) - for(var/obj/item/weapon/ore/O in targeted_ore.loc) - ore_eaten++ - if(!(O.type in ore_types_eaten)) - ore_types_eaten += O.type - qdel(O) - if(ore_eaten > 10)//Limit the scope of the reward you can get, or else things might get silly - ore_eaten = 10 - visible_message("The ore was swallowed whole!") - -/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time - if(!alerted && will_burrow) - alerted = 1 - spawn(chase_time) - if(alerted) - visible_message("The [src.name] buries into the ground, vanishing from sight!") - qdel(src) - -/mob/living/simple_animal/hostile/asteroid/goldgrub/proc/Reward() - if(!ore_eaten || ore_types_eaten.len == 0) - return - visible_message("[src] spits up the contents of its stomach before dying!") - var/counter - for(var/R in ore_types_eaten) - for(counter=0, counter < ore_eaten, counter++) - new R(src.loc) - ore_types_eaten.Cut() - ore_eaten = 0 - - -/mob/living/simple_animal/hostile/asteroid/goldgrub/bullet_act(var/obj/item/projectile/P) - visible_message("The [P.name] was repelled by [src.name]'s girth!") - return - -/mob/living/simple_animal/hostile/asteroid/goldgrub/death(gibbed) - alerted = 0 - Reward() - ..() - -/mob/living/simple_animal/hostile/asteroid/goldgrub/adjustHealth(damage) - idle_vision_range = 9 - ..() - -/mob/living/simple_animal/hostile/asteroid/hivelord - name = "hivelord" - desc = "A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original." - icon = 'icons/mob/animal.dmi' - icon_state = "Hivelord" - icon_living = "Hivelord" - icon_aggro = "Hivelord_alert" - icon_dead = "Hivelord_dead" - icon_gib = "syndicate_gib" - mouse_opacity = 2 - move_to_delay = 14 - ranged = 1 - vision_range = 5 - aggro_vision_range = 9 - idle_vision_range = 5 - speed = 3 - maxHealth = 75 - health = 75 - harm_intent_damage = 5 - melee_damage_lower = 0 - melee_damage_upper = 0 - attacktext = "lashes out at" - speak_emote = list("telepathically cries") - attack_sound = 'sound/weapons/pierce.ogg' - throw_message = "falls right through the strange body of the" - ranged_cooldown = 0 - ranged_cooldown_cap = 0 - environment_smash = 0 - retreat_distance = 3 - minimum_distance = 3 - pass_flags = PASSTABLE - loot = list(/obj/item/organ/internal/hivelord_core) - -/mob/living/simple_animal/hostile/asteroid/hivelord/OpenFire(var/the_target) - var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/A = new /mob/living/simple_animal/hostile/asteroid/hivelordbrood(src.loc) - A.GiveTarget(target) - A.friends = friends - A.faction = faction - return - -/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget() - OpenFire() - -/obj/item/organ/internal/hivelord_core - name = "hivelord remains" - desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly. Try not to think about what you're eating." - icon = 'icons/obj/food/food.dmi' - icon_state = "boiledrorocore" - slot = "hivecore" - var/inert = 0 - var/preserved = 0 - -/obj/item/organ/internal/hivelord_core/New() - spawn(2400) - if(!preserved) - inert = 1 - desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested." - -/obj/item/organ/internal/hivelord_core/on_life() - ..() - if(owner) - owner.adjustBruteLoss(-1) - owner.adjustFireLoss(-1) - owner.adjustOxyLoss(-2) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - var/datum/reagent/blood/B = locate() in H.vessel.reagent_list //Grab some blood - var/blood_volume = round(H.vessel.get_reagent_amount("blood")) - if(B && blood_volume < H.max_blood && blood_volume) - B.volume += 2 // Fast blood regen - -/obj/item/organ/internal/hivelord_core/attack(mob/living/M as mob, mob/living/user as mob) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(inert) - to_chat(user, "[src] have become inert, its healing properties are no more.") - return - else - if(H.stat == DEAD) - to_chat(user, "[src] are useless on the dead.") - return - if(H != user) - H.visible_message("[user] forces [H] to eat [src]... they quickly regenerate all injuries!") - else - to_chat(user, "You chomp into [src], barely managing to hold it down, but feel amazingly refreshed in mere moments.") - playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1) - H.revive() - qdel(src) - ..() - -/obj/item/organ/internal/hivelord_core/prepare_eat() - return null - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood - name = "hivelord brood" - desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..." - icon = 'icons/mob/animal.dmi' - icon_state = "Hivelordbrood" - icon_living = "Hivelordbrood" - icon_aggro = "Hivelordbrood" - icon_dead = "Hivelordbrood" - icon_gib = "syndicate_gib" - mouse_opacity = 2 - move_to_delay = 1 - friendly = "buzzes near" - vision_range = 10 - speed = 3 - maxHealth = 1 - health = 1 - harm_intent_damage = 5 - melee_damage_lower = 2 - melee_damage_upper = 2 - attacktext = "slashes" - speak_emote = list("telepathically cries") - attack_sound = 'sound/weapons/pierce.ogg' - throw_message = "falls right through the strange body of the" - environment_smash = 0 - pass_flags = PASSTABLE - del_on_death = 1 - -/mob/living/simple_animal/hostile/asteroid/hivelordbrood/New() - ..() - spawn(100) - death() - /mob/living/simple_animal/hostile/asteroid/goliath name = "goliath" desc = "A massive beast that uses long tentacles to ensare its prey, threatening them is not advised under any conditions." @@ -344,7 +117,7 @@ move_to_delay = 40 ranged = 1 ranged_cooldown = 2 //By default, start the Goliath with his cooldown off so that people can run away quickly on first sight - ranged_cooldown_cap = 8 + ranged_cooldown_time = 120 friendly = "wails at" speak_emote = list("bellows") vision_range = 4 @@ -368,7 +141,7 @@ handle_preattack() /mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack() - if(ranged_cooldown <= 2 && !pre_attack) + if(ranged_cooldown <= world.time + ranged_cooldown_time * 0.25 && !pre_attack) pre_attack++ if(!pre_attack || stat || AIStatus == AI_IDLE) return @@ -383,7 +156,7 @@ if(get_dist(src, target) <= 7)//Screen range check, so you can't get tentacle'd offscreen visible_message("The [src.name] digs its tentacles under [target.name]!") new /obj/effect/goliath_tentacle/original(tturf) - ranged_cooldown = ranged_cooldown_cap + ranged_cooldown = world.time + ranged_cooldown_time icon_state = icon_aggro pre_attack = 0 return diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index 99e6f61431c..d7984031052 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -156,7 +156,7 @@ var/counter for(counter=0, counter<=powerlevel, counter++) var/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice/S = new /obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice(src.loc) - S.reagents.add_reagent("mushroomhallucinogen", powerlevel) + S.reagents.add_reagent("psilocybin", powerlevel) S.reagents.add_reagent("omnizine", powerlevel) S.reagents.add_reagent("synaptizine", powerlevel) qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index d749db16bf5..41ca671bc56 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -163,7 +163,7 @@ clothes_req = 0 range = 14 -/obj/effect/proc_holder/spell/aoe_turf/flicker_lights/cast(list/targets) +/obj/effect/proc_holder/spell/aoe_turf/flicker_lights/cast(list/targets, mob/user = usr) for(var/turf/T in targets) for(var/obj/machinery/light/L in T) L.flicker() @@ -179,9 +179,9 @@ clothes_req = 0 range = 10 -/obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets) +/obj/effect/proc_holder/spell/aoe_turf/blindness/cast(list/targets, mob/user = usr) for(var/mob/living/L in living_mob_list) - if(L == usr) + if(L == user) continue var/turf/T = get_turf(L.loc) if(T && T in targets) @@ -200,7 +200,7 @@ range = -1 include_user = 1 -/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets) +/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets, mob/user = usr) for(var/mob/living/target in targets) if(target.see_invisible == SEE_INVISIBLE_LIVING) diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index 10e4405998e..e6b2c27c164 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -142,7 +142,7 @@ var/global/list/ts_spiderling_list = list() else if(istype(target, /obj/machinery/door/firedoor)) var/obj/machinery/door/firedoor/F = target if(F.density) - if(F.blocked) + if(F.welded) to_chat(src, "The fire door is welded shut.") else visible_message("\The [src] pries open the firedoor!") @@ -162,7 +162,7 @@ var/global/list/ts_spiderling_list = list() var/can_poison = 1 if(ishuman(G)) var/mob/living/carbon/human/H = G - if(!(H.species.reagent_tag & PROCESS_ORG) || (H.species.flags & NO_POISON)) + if(!(H.species.reagent_tag & PROCESS_ORG) || (!H.species.tox_mod)) can_poison = 0 spider_specialattack(G,can_poison) else @@ -248,7 +248,7 @@ var/global/list/ts_spiderling_list = list() notify_ghosts("[src] has appeared in [get_area(src)]. (already player-controlled)", source = src, alert_overlay = alert_overlay) else if(ai_playercontrol_allowtype) var/image/alert_overlay = image('icons/mob/terrorspider.dmi', icon_state) - notify_ghosts("[src] has appeared in [get_area(src)].", enter_link = "(Click to control)", source = src, alert_overlay = alert_overlay, attack_not_jump = 1) + notify_ghosts("[src] has appeared in [get_area(src)].", enter_link = "(Click to control)", source = src, alert_overlay = alert_overlay, action = NOTIFY_ATTACK) /mob/living/simple_animal/hostile/poison/terror_spider/Destroy() ts_spiderlist -= src @@ -307,7 +307,7 @@ var/global/list/ts_spiderling_list = list() try_open_airlock(L) if(istype(A, /obj/machinery/door/firedoor)) var/obj/machinery/door/firedoor/F = A - if(F.density && !F.blocked) + if(F.density && !F.welded) F.open() ..() diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm new file mode 100644 index 00000000000..b4ac6212220 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -0,0 +1,116 @@ + + +/obj/structure/alien/resin/flower_bud_enemy //inheriting basic attack/damage stuff from alien structures + name = "flower bud" + desc = "A large pulsating plant..." + icon = 'icons/effects/spacevines.dmi' + icon_state = "flower_bud" + layer = MOB_LAYER + 0.9 + opacity = 0 + canSmoothWith = list() + smooth = SMOOTH_FALSE + var/growth_time = 1200 + +/obj/structure/alien/resin/flower_bud_enemy/New() + ..() + var/list/anchors = list() + anchors += locate(x-2,y+2,z) + anchors += locate(x+2,y+2,z) + anchors += locate(x-2,y-2,z) + anchors += locate(x+2,y-2,z) + + for(var/turf/T in anchors) + var/datum/beam/B = Beam(T, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine) + B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow) + addtimer(src, "bear_fruit", growth_time) + +/obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit() + visible_message("the plant has borne fruit!") + new /mob/living/simple_animal/hostile/venus_human_trap(get_turf(src)) + qdel(src) + + +/obj/effect/ebeam/vine + name = "thick vine" + mouse_opacity = 1 + desc = "A thick vine, painful to the touch." + + +/obj/effect/ebeam/vine/Crossed(atom/movable/AM) + if(isliving(AM)) + var/mob/living/L = AM + if(!("vines" in L.faction)) + L.adjustBruteLoss(5) + to_chat(L, "You cut yourself on the thorny vines.") + + + +/mob/living/simple_animal/hostile/venus_human_trap + name = "venus human trap" + desc = "Now you know how the fly feels." + icon_state = "venus_human_trap" + layer = MOB_LAYER + 0.9 + health = 50 + maxHealth = 50 + ranged = 1 + harm_intent_damage = 5 + melee_damage_lower = 25 + melee_damage_upper = 25 + a_intent = I_HARM + attack_sound = 'sound/weapons/bladeslice.ogg' + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + unsuitable_atmos_damage = 0 + faction = list("hostile","vines","plants") + var/list/grasping = list() + var/max_grasps = 4 + var/grasp_chance = 20 + var/grasp_pull_chance = 85 + var/grasp_range = 4 + del_on_death = 1 + +/mob/living/simple_animal/hostile/venus_human_trap/handle_automated_action() + if(..()) + for(var/mob/living/L in grasping) + if(L.stat == DEAD) + var/datum/beam/B = grasping[L] + if(B) + B.End() + grasping -= L + + //Can attack+pull multiple times per cycle + if(L.Adjacent(src)) + L.attack_animal(src) + else + if(prob(grasp_pull_chance)) + dir = get_dir(src,L) //staaaare + step(L,get_dir(L,src)) //reel them in + L.Weaken(3) //you can't get away now~ + + if(grasping.len < max_grasps) + grasping: + for(var/mob/living/L in view(grasp_range, src)) + if(L == src || faction_check(L) || (L in grasping) || L == target) + continue + for(var/t in getline(src,L)) + for(var/a in t) + var/atom/A = a + if(A.density && A != L) + continue grasping + if(prob(grasp_chance)) + to_chat(L, "\The [src] has you entangled!") + grasping[L] = Beam(L, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine) + + break //only take 1 new victim per cycle + + +/mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target) + var/dist = get_dist(src,the_target) + Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine) + the_target.attack_animal(src) + + +/mob/living/simple_animal/hostile/venus_human_trap/CanAttack(atom/the_target) + . = ..() + if(.) + if(the_target in grasping) + return 0 diff --git a/code/modules/mob/living/simple_animal/posessed_object.dm b/code/modules/mob/living/simple_animal/posessed_object.dm index 70ea452381d..1473bd5990a 100644 --- a/code/modules/mob/living/simple_animal/posessed_object.dm +++ b/code/modules/mob/living/simple_animal/posessed_object.dm @@ -103,7 +103,7 @@ dir = possessed_item.dir color = possessed_item.color overlays = possessed_item.overlays - opacity = possessed_item.opacity + set_opacity(possessed_item.opacity) visible_message("[src] rises into the air and begins to float!") // Inform those around us that shit's gettin' spooky. animate_ghostly_presence(src, -1, 20, 1) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 24ad47a16cb..9669c90b3ec 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -297,10 +297,13 @@ playsound(loc, M.attack_sound, 50, 1, 1) visible_message("\The [M] [M.attacktext] [src]!", \ "\The [M] [M.attacktext] [src]!") - add_logs(M, src, "attacked", admin=0) + add_logs(M, src, "attacked", admin=0, print_attack_log = 0) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) attack_threshold_check(damage,M.melee_damage_type) +/mob/living/simple_animal/proc/attacked_by(obj/item/I, mob/living/user) // Handled in _onclick/click.dm + return + /mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj) if(!Proj) return @@ -579,21 +582,7 @@ density = initial(density) update_canmove() -/mob/living/simple_animal/show_inv(mob/user as mob) - user.set_machine(src) - var/dat = {" - - - "} - if(can_collar) - dat += "" - dat += {"
Left Hand:[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Empty"]
Right Hand:[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Empty"]
 
Collar:[(collar && !(collar.flags&ABSTRACT)) ? collar : "Empty"]
- Close - "} - var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 250) - popup.set_content(dat) - popup.open() /mob/living/simple_animal/proc/make_babies() // <3 <3 <3 if(gender != FEMALE || stat || !scan_ready || !childtype || !simplespecies) @@ -652,57 +641,74 @@ if(changed) animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT) -/mob/living/simple_animal/Topic(href, href_list) - if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr)) - if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || isrobot(usr) || isalienadult(usr))) - return - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("collar") - if(!can_collar) - return - if(collar) - if(collar.flags & NODROP) - to_chat(usr, "\The [collar] is stuck too hard to [src] for you to remove!") - return - collar.dropped(src) - collar.forceMove(src.loc) - collar = null - regenerate_icons() - else - to_chat(usr, "There is nothing to remove from its [remove_from].") - return - show_inv(usr) - else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || isrobot(usr) || isalienadult(usr))) - return +/* Inventory */ - var/add_to = href_list["add_inv"] - switch(add_to) - if("collar") - if(!can_collar || collar) - return - var/obj/item/clothing/accessory/petcollar/C = usr.get_active_hand() - if(!istype(C)) - usr.visible_message("[usr] rubs [src]'s neck.","You rub [src]'s neck for a moment.") - return - usr.drop_item() - C.forceMove(src) - collar = C - collar.equipped(src) - regenerate_icons() - to_chat(usr, "You put \the [C] around \the [src]'s neck.") - if(C.tagname) - name = C.tagname - real_name = C.tagname - show_inv(usr) +/mob/living/simple_animal/show_inv(mob/user as mob) + if(!can_collar) + return + + user.set_machine(src) + var/dat = "
Collar:[(collar && !(collar.flags&ABSTRACT)) ? collar : "Empty"]
" + dat += "Close" + + var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 250) + popup.set_content(dat) + popup.open() + +/mob/living/simple_animal/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_collar) + return collar + . = ..() + +/mob/living/simple_animal/can_equip(obj/item/I, slot, disable_warning = 0) + // . = ..() // Do not call parent. We do not want animals using their hand slots. + switch(slot) + if(slot_collar) + if(collar) + return 0 + if(!can_collar) + return 0 + if(!istype(I, /obj/item/clothing/accessory/petcollar)) + return 0 + return 1 + +/mob/living/simple_animal/equip_to_slot(obj/item/W, slot) + if(!istype(W)) + return 0 + + if(!slot) + return 0 + + W.forceMove(src) + W.equipped(src, slot) + W.layer = 20 + W.plane = HUD_PLANE + + switch(slot) + if(slot_collar) + collar = W + if(collar.tagname) + name = collar.tagname + real_name = collar.tagname + regenerate_icons() + +/mob/living/simple_animal/unEquip(obj/item/I, force) + . = ..() + if(!. || !I) + return + + if(I == collar) + collar = null + regenerate_icons() /mob/living/simple_animal/get_access() . = ..() if(collar) . |= collar.GetAccess() +/* End Inventory */ + /mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion return diff --git a/code/modules/mob/living/simple_animal/spawner.dm b/code/modules/mob/living/simple_animal/spawner.dm index 0cbf24cf6e2..46a05daba98 100644 --- a/code/modules/mob/living/simple_animal/spawner.dm +++ b/code/modules/mob/living/simple_animal/spawner.dm @@ -40,6 +40,7 @@ return 0 spawn_delay = world.time + spawn_time var/mob/living/simple_animal/L = new mob_type(src.loc) + L.admin_spawned = admin_spawned //If we were admin spawned, lets have our children count as that as well. spawned_mobs += L L.nest = src L.faction = src.faction diff --git a/code/modules/mob/living/stat_states.dm b/code/modules/mob/living/stat_states.dm index f04196f9fc9..58c4221504d 100644 --- a/code/modules/mob/living/stat_states.dm +++ b/code/modules/mob/living/stat_states.dm @@ -6,7 +6,7 @@ return 0 else if(stat == UNCONSCIOUS) return 0 - add_logs(src, null, "fallen unconscious at [atom_loc_line(get_turf(src))]", admin=0) + add_logs(src, null, "fallen unconscious at [atom_loc_line(get_turf(src))]", admin=0, print_attack_log = 0) stat = UNCONSCIOUS if(updating) // update_blind_effects() @@ -19,7 +19,7 @@ return 0 else if(stat == CONSCIOUS) return 0 - add_logs(src, null, "woken up at [atom_loc_line(get_turf(src))]", admin=0) + add_logs(src, null, "woken up at [atom_loc_line(get_turf(src))]", admin=0, print_attack_log = 0) stat = CONSCIOUS if(updating) // update_blind_effects() @@ -40,7 +40,7 @@ return if(!can_be_revived()) return - add_logs(src, null, "came back to life at [atom_loc_line(get_turf(src))]", admin=0) + add_logs(src, null, "came back to life at [atom_loc_line(get_turf(src))]", admin=0, print_attack_log = 0) stat = CONSCIOUS dead_mob_list -= src living_mob_list += src diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index f817b03482e..59b7077e79e 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -95,3 +95,29 @@ /mob/living/proc/update_stamina() return + +/mob/living/on_varedit(modified_var) + switch(modified_var) + if("weakened") + SetWeakened(weakened) + if("stunned") + SetStunned(stunned) + if("paralysis") + SetParalysis(paralysis) + if("sleeping") + SetSleeping(sleeping) + if("eye_blind") + SetEyeBlind(eye_blind) + if("eye_blurry") + SetEyeBlurry(eye_blurry) + if("ear_deaf") + SetEarDeaf(ear_deaf) + if("ear_damage") + SetEarDamage(ear_damage) + if("druggy") + SetDruggy(druggy) + if("maxHealth") + updatehealth() + if("resize") + update_transform() + ..() \ No newline at end of file diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 8cc51882ebf..27197474c00 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -72,6 +72,8 @@ for(var/datum/alternate_appearance/AA in viewing_alternate_appearances) AA.display_to(list(src)) + update_client_colour(0) + callHook("mob_login", list("client" = client, "mob" = src)) // Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget(). diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 44ba3cb99c3..3f3792fd1b7 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -19,7 +19,8 @@ for(var/datum/alternate_appearance/AA in viewing_alternate_appearances) AA.viewers -= src viewing_alternate_appearances = null - return ..() + ..() + return QDEL_HINT_HARDDEL_NOW /mob/New() mob_list += src @@ -946,8 +947,7 @@ var/list/slot_equipment_priority = list( \ add_spell_to_statpanel(S) - if(client && client.holder) - + if(is_admin(src)) if(statpanel("DI")) //not looking at that panel stat("Loc", "([x], [y], [z]) [loc]") stat("CPU", "[world.cpu]") @@ -1223,9 +1223,11 @@ mob/proc/yank_out_object() if(mind) return mind.grab_ghost(force = force) -/mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null) +/mob/proc/notify_ghost_cloning(message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", sound = 'sound/effects/genetics.ogg', atom/source = null, flashwindow = TRUE) var/mob/dead/observer/ghost = get_ghost() if(ghost) + if(flashwindow) + window_flash(ghost.client) ghost.notify_cloning(message, sound, source) return ghost @@ -1264,7 +1266,7 @@ mob/proc/yank_out_object() return // Only living mobs can ventcrawl //You can buckle on mobs if you're next to them since most are dense -/mob/buckle_mob(mob/living/M) +/mob/buckle_mob(mob/living/M, force = 0) if(M.buckled) return 0 var/turf/T = get_turf(src) @@ -1310,3 +1312,39 @@ mob/proc/yank_out_object() if(F in target.faction) return 1 return 0 + +/mob/proc/create_attack_log(var/text, var/collapse = 1)//forgive me code gods for this shitcode proc + //this proc enables lovely stuff like an attack log that looks like this: "[18:20:29-18:20:45]21x John Smith attacked Andrew Jackson with a crowbar." + //That makes the logs easier to read, but because all of this is stored in strings, weird things have to be used to get it all out. + var/new_log = "\[[time_stamp()]] [text]" + + if(length(attack_log) > 0)//if there are other logs already present + var/previous_log = attack_log[length(attack_log)]//get the latest log + var/last_log_is_range = (copytext(previous_log, 10, 11) == "-") //whether the last log is a time range or not. The "-" will be an indicator that it is. + var/x_sign_position = findtext(previous_log, "x") + + if(world.timeofday - last_log > 100)//if more than 10 seconds from last log + collapse = 0//don't collapse anyway + + //the following checks if the last log has the same contents as the new one + if(last_log_is_range) + if(!(copytext(previous_log, x_sign_position + 13) == text))//the 13 is there because of span classes; you won't see those normally in-game + collapse = 0 + else + if(!(copytext(previous_log, 12) == text)) + collapse = 0 + + + if(collapse == 1) + var/rep = 0 + var/old_timestamp = copytext(previous_log, 2, 10)//copy the first time value. This one doesn't move when it's a timespan, so no biggie + //An attack log entry can either be a time range with multiple occurences of an action or a single one, with just one time stamp + if(last_log_is_range) + + rep = text2num(copytext(previous_log, 44, x_sign_position))//get whatever number is right before the 'x' + + new_log = "\[[old_timestamp]-[time_stamp()]][rep?rep+1:2]x [text]" + attack_log -= attack_log[length(attack_log)]//remove the last log + + attack_log += new_log + last_log = world.timeofday diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 6cb582e94c1..962987dcc3f 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -30,6 +30,7 @@ var/lastattacker = null var/lastattacked = null var/attack_log = list( ) + var/last_log = 0 var/obj/machinery/machine = null var/other_mobs = null var/memory = "" @@ -67,7 +68,9 @@ var/bodytemperature = 310.055 //98.7 F var/flying = 0 var/charges = 0.0 - var/nutrition = 400.0//Carbon + var/nutrition = NUTRITION_LEVEL_FED + 50 //Carbon + var/satiety = 0 //Carbon + var/hunger_drain = HUNGER_FACTOR // how quickly the mob gets hungry; largely utilized by species. var/overeatduration = 0 // How long this guy is overeating //Carbon var/intent = null//Living diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index a22d9bf3c6b..446ec797a76 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -194,7 +194,7 @@ animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING) return //KJK /* if(force_down) //THIS GOES ABOVE THE RETURN LABELED KJK - affecting.set_dir(SOUTH)*///This shows how you can apply special directions based on a variable. //face up + affecting.setDir(SOUTH)*///This shows how you can apply special directions based on a variable. //face up var/shift = 0 var/adir = get_dir(assailant, affecting) @@ -204,18 +204,18 @@ shift = 8 if(dancing) //look at partner shift = 10 - assailant.set_dir(get_dir(assailant, affecting)) + assailant.setDir(get_dir(assailant, affecting)) if(GRAB_AGGRESSIVE) shift = 12 if(GRAB_NECK, GRAB_UPGRADING) shift = -10 adir = assailant.dir - affecting.set_dir(assailant.dir) + affecting.setDir(assailant.dir) affecting.loc = assailant.loc if(GRAB_KILL) shift = 0 adir = 1 - affecting.set_dir(SOUTH)//face up + affecting.setDir(SOUTH)//face up affecting.loc = assailant.loc switch(adir) @@ -254,8 +254,8 @@ force_down = 1 affecting.Weaken(3) step_to(assailant, affecting) - assailant.set_dir(EAST) //face the victim - affecting.set_dir(SOUTH) //face up //This is an example of a new feature based on the context of the location of the victim. + assailant.setDir(EAST) //face the victim + affecting.setDir(SOUTH) //face up //This is an example of a new feature based on the context of the location of the victim. */ //It means that upgrading while someone is lying on the ground would cause you to go into pin mode. state = GRAB_AGGRESSIVE icon_state = "grabbed1" @@ -268,9 +268,9 @@ assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!") state = GRAB_NECK icon_state = "grabbed+1" - assailant.set_dir(get_dir(assailant, affecting)) - affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" - assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" + assailant.setDir(get_dir(assailant, affecting)) + affecting.create_attack_log("Has had their neck grabbed by [assailant.name] ([assailant.ckey])") + assailant.create_attack_log("Grabbed the neck of [affecting.name] ([affecting.ckey])") log_attack("[assailant.name] ([assailant.ckey]) grabbed the neck of [affecting.name] ([affecting.ckey])") if(!iscarbon(assailant)) affecting.LAssailant = null @@ -285,13 +285,13 @@ state = GRAB_KILL assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") - affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])" - assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" + affecting.create_attack_log("Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])") + assailant.create_attack_log("Strangled (kill intent) [affecting.name] ([affecting.ckey])") msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") assailant.next_move = world.time + 10 affecting.AdjustLoseBreath(1) - affecting.set_dir(WEST) + affecting.setDir(WEST) adjust_position() //This is used to make sure the victim hasn't managed to yackety sax away before using the grab. @@ -338,8 +338,8 @@ damage += hat.force * 3 affecting.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", affected.run_armor_check(affecting, "melee")) playsound(assailant.loc, "swing_hit", 25, 1, -1) - assailant.attack_log += text("\[[time_stamp()]\] Headbutted [affecting.name] ([affecting.ckey])") - affecting.attack_log += text("\[[time_stamp()]\] Headbutted by [assailant.name] ([assailant.ckey])") + assailant.create_attack_log("Headbutted [affecting.name] ([affecting.ckey])") + affecting.create_attack_log("Headbutted by [assailant.name] ([assailant.ckey])") msg_admin_attack("[key_name(assailant)] has headbutted [key_name(affecting)]") return @@ -357,8 +357,8 @@ return assailant.visible_message("[assailant] presses \his fingers into [affecting]'s eyes!") to_chat(affecting, "You feel immense pain as digits are being pressed into your eyes!") - assailant.attack_log += text("\[[time_stamp()]\] Pressed fingers into the eyes of [affecting.name] ([affecting.ckey])") - affecting.attack_log += text("\[[time_stamp()]\] Had fingers pressed into their eyes by [assailant.name] ([assailant.ckey])") + assailant.create_attack_log("Pressed fingers into the eyes of [affecting.name] ([affecting.ckey])") + affecting.create_attack_log("Had fingers pressed into their eyes by [assailant.name] ([assailant.ckey])") msg_admin_attack("[key_name(assailant)] has pressed his fingers into [key_name(affecting)]'s eyes.") var/obj/item/organ/internal/eyes/eyes = affected.get_int_organ(/obj/item/organ/internal/eyes) eyes.damage += rand(3,4) @@ -378,8 +378,8 @@ affecting.Weaken(3) affecting.lying = 1 step_to(assailant, affecting) - assailant.set_dir(EAST) //face the victim - affecting.set_dir(SOUTH) //face up + assailant.setDir(EAST) //face the victim + affecting.setDir(SOUTH) //face up return else to_chat(assailant, "You are already pinning [affecting] to the ground.") @@ -396,8 +396,8 @@ user.visible_message("[user] devours \the [affecting]!") if(affecting.mind) - affecting.attack_log += "\[[time_stamp()]\] Has been devoured by [attacker.name] ([attacker.ckey])" - attacker.attack_log += "\[[time_stamp()]\] Devoured [affecting.name] ([affecting.ckey])" + affecting.create_attack_log("Has been devoured by [attacker.name] ([attacker.ckey])") + attacker.create_attack_log("Devoured [affecting.name] ([affecting.ckey])") msg_admin_attack("[key_name(attacker)] devoured [key_name(affecting)]") affecting.loc = user diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 1610999f5ed..9922fed8789 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -22,6 +22,25 @@ return 0 return 1 +/mob/proc/get_screen_colour() + +/mob/proc/update_client_colour(var/time = 10) //Update the mob's client.color with an animation the specified time in length. + if(!client) //No client_colour without client. If the player logs back in they'll be back through here anyway. + return + client.colour_transition(get_screen_colour(), time = time) //Get the colour matrix we're going to transition to depending on relevance (magic glasses first, eyes second). + +/mob/living/carbon/human/get_screen_colour() //Fetch the colour matrix from wherever (e.g. eyes) so it can be compared to client.color. + . = ..() + if(.) + return . + + var/obj/item/clothing/glasses/worn_glasses = glasses + var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) + if(istype(worn_glasses) && worn_glasses.color_view) //Check to see if they got those magic glasses and they're augmenting the colour of what the wearer sees. If they're not, color_view should be null. + return worn_glasses.color_view + else if(eyes) //If they're not, check to see if their eyes got one of them there colour matrices. Will be null if eyes are robotic/the mob isn't colourblind and they have no default colour matrix. + return eyes.get_colourmatrix() + /proc/isloyal(A) //Checks to see if the person contains a mindshield implant, then checks that the implant is actually inside of them for(var/obj/item/weapon/implant/loyalty/L in A) if(L && L.implanted) @@ -291,10 +310,10 @@ proc/muffledspeech(phrase) /mob/proc/abiotic(var/full_body = 0) - if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask))) + if(full_body && ((l_hand && !(l_hand.flags & ABSTRACT)) || (r_hand && !(r_hand.flags & ABSTRACT)) || (back || wear_mask))) return 1 - if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT))) + if((l_hand && !(l_hand.flags & ABSTRACT)) || (r_hand && !(r_hand.flags & ABSTRACT))) return 1 return 0 @@ -434,20 +453,22 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HARM) lname = "[lname] " to_chat(M, "[lname][follow][message]") -/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/image/alert_overlay = null, var/attack_not_jump = 0) //Easy notification of ghosts. +/proc/notify_ghosts(message, ghost_sound = null, enter_link = null, atom/source = null, image/alert_overlay = null, flashwindow = TRUE, var/action = NOTIFY_JUMP) //Easy notification of ghosts. for(var/mob/dead/observer/O in player_list) if(O.client) to_chat(O, "[message][(enter_link) ? " [enter_link]" : ""]") if(ghost_sound) O << sound(ghost_sound) + if(flashwindow) + window_flash(O.client) if(source) - var/obj/screen/alert/notify_jump/A = O.throw_alert("\ref[source]_notify_jump", /obj/screen/alert/notify_jump) + var/obj/screen/alert/notify_action/A = O.throw_alert("\ref[source]_notify_action", /obj/screen/alert/notify_action) if(A) if(O.client.prefs && O.client.prefs.UI_style) A.icon = ui_style2icon(O.client.prefs.UI_style) A.desc = message - A.attack_not_jump = attack_not_jump - A.jump_target = source + A.action = action + A.target = source if(!alert_overlay) var/old_layer = source.layer var/old_plane = source.plane diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 74c9528071c..8b8fafd32b7 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -276,7 +276,7 @@ for(var/obj/item/weapon/grab/G in mob) if(G.state == GRAB_NECK) - mob.set_dir(reverse_dir[direct]) + mob.setDir(reverse_dir[direct]) G.adjust_position() for(var/obj/item/weapon/grab/G in mob.grabbed_by) G.adjust_position() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 3c5e3ac0130..bccd7990de9 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -25,6 +25,8 @@ /mob/new_player/proc/new_player_panel_proc() var/real_name = client.prefs.real_name + if(client.prefs.randomslot) + real_name = "Random Character Slot" var/output = "

Setup Character
[real_name]

" if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) @@ -169,6 +171,9 @@ to_chat(usr, "\blue There is an administrative lock on entering the game!") return + if(client.prefs.randomslot) + client.prefs.load_random_character_slot(client) + if(client.prefs.species in whitelisted_species) if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist) to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species].")) @@ -494,6 +499,9 @@ if(mind.assigned_role == "Clown") //give them a clownname if they are a clown new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name! new_character.rename_self("clown") + else if(mind.assigned_role == "Mime") + new_character.real_name = pick(mime_names) + new_character.rename_self("mime") else if(new_character.species == "Diona") new_character.real_name = pick(diona_names) //I hate this being here of all places but unfortunately dna is based on real_name! new_character.rename_self("diona") diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 8adc505102b..f7fb545d495 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -1,7 +1,7 @@ /mob/living/carbon/human/proc/monkeyize() var/mob/H = src H.dna.SetSEState(MONKEYBLOCK,1) - domutcheck(H, null) + genemutcheck(H,MONKEYBLOCK,null,MUTCHK_FORCED) /mob/new_player/AIize() spawning = 1 diff --git a/code/modules/nano/interaction/default.dm b/code/modules/nano/interaction/default.dm index cb00e6a12b3..3f9155ed162 100644 --- a/code/modules/nano/interaction/default.dm +++ b/code/modules/nano/interaction/default.dm @@ -15,7 +15,7 @@ return STATUS_UPDATE // Ghosts can view updates /mob/living/silicon/pai/default_can_use_topic(var/src_object) - if(src_object == src && !stat) + if((src_object == src || src_object == radio) && stat == CONSCIOUS) return STATUS_INTERACTIVE else return ..() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 9de96b73129..7e5f847419f 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -701,7 +701,7 @@ to_chat(H, "You feel surrounded by sadness. Sadness... and HONKS!") H.makeCluwne() else if(myeffect == "Demotion Notice") - command_announcement.Announce("[mytarget] is hereby demoted to the rank of Civilian. Process this demotion immediately. Failure to comply with these orders is grounds for termination.","CC Demotion Order") + event_announcement.Announce("[mytarget] is hereby demoted to the rank of Civilian. Process this demotion immediately. Failure to comply with these orders is grounds for termination.","CC Demotion Order") else message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.") used = 1 diff --git a/code/modules/pooling/pool.dm b/code/modules/pooling/pool.dm deleted file mode 100644 index 2d769a020cb..00000000000 --- a/code/modules/pooling/pool.dm +++ /dev/null @@ -1,125 +0,0 @@ - -/* -/tg/station13 /datum Pool: ---------------------------------- -By RemieRichards - -Creation/Deletion is laggy, so let's reduce reuse and recycle! - -Usage: - -To get a object, just call - - PoolOrNew(type, arg) if you only want to pass one argument to New(), usually loc - - PoolOrNew(type, list) if you want to pass multiple arguments to New() - -To put a object back in the pool, call PlaceInPool(object) -This will call destroy on the object, set its loc to null, -and reset all of its vars to their default - -You can override your object's destroy to return QDEL_HINT_PUTINPOOL -to ensure its always placed in this pool (this will only be acted on if qdel calls destroy, and destroy will not get called twice) - -For almost all pooling purposes, it is better to use the QDEL hint than to pool it directly with PlaceInPool - -*/ - -var/global/list/GlobalPool = list() - -//You'll be using this proc 90% of the time. -//It grabs a type from the pool if it can -//And if it can't, it creates one -//The pool is flexible and will expand to fit -//The new created atom when it eventually -//Goes into the pool - -//Second argument can be a single arg -//Or a list of arguments -//Either way it gets passed to new - -/proc/PoolOrNew(get_type,second_arg) - if(!get_type) - return - - . = GetFromPool(get_type,second_arg) - - if(!.) - if(ispath(get_type)) - if(islist(second_arg)) - . = new get_type (arglist(second_arg)) - else - . = new get_type (second_arg) - - -/proc/GetFromPool(get_type,second_arg) - if(!get_type) - return - - if(isnull(GlobalPool[get_type])) - return - - if(length(GlobalPool[get_type]) == 0) - return - - var/datum/pooled = pop(GlobalPool[get_type]) - if(pooled) - var/atom/movable/AM - if(istype(pooled, /atom/movable)) - AM = pooled - - if(islist(second_arg)) - if(AM) - AM.loc = second_arg[1] //we need to do loc setting explicetly before even calling New() to replicate new()'s behavior - pooled.New(arglist(second_arg)) - - else - if(AM) - AM.loc = second_arg - pooled.New(second_arg) - - return pooled - - -/proc/PlaceInPool(datum/diver, destroy = 1) - if(!istype(diver)) - return - - if(diver in GlobalPool[diver.type]) - return - - if(!GlobalPool[diver.type]) - GlobalPool[diver.type] = list() - - GlobalPool[diver.type] |= diver - - if(destroy) - diver.Destroy() - - diver.ResetVars() - -var/list/exclude = list("animate_movement", "contents", "loc", "locs", "parent_type", "vars", "verbs", "type") -var/list/pooledvariables = list() -//thanks to clusterfack @ /vg/station for these two procs -/datum/proc/createVariables() - pooledvariables[type] = new/list() - var/list/exclude = global.exclude + args - - for(var/key in vars) - if(key in exclude) - continue - pooledvariables[type][key] = initial(vars[key]) - -/datum/proc/ResetVars() - if(!pooledvariables[type]) - createVariables(args) - - for(var/key in pooledvariables[type]) - vars[key] = pooledvariables[type][key] - -/atom/movable/ResetVars() - ..() - loc = null - contents = initial(contents) //something is really wrong if this object still has stuff in it by this point - -/image/ResetVars() - ..() - loc = null diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index ae931484524..56da9cf9b07 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -678,7 +678,7 @@ to_chat(H, "The APC power currents surge erratically, damaging your chassis!") H.adjustFireLoss(10,0) else if(src.cell && src.cell.charge > 0) - if(H.nutrition < 450) + if(H.nutrition < NUTRITION_LEVEL_WELL_FED) if(src.cell.charge >= 500) H.nutrition += 50 src.cell.charge -= 500 @@ -689,8 +689,8 @@ to_chat(user, "You slot your fingers into the APC interface and siphon off some of the stored charge for your own use.") if(src.cell.charge < 0) src.cell.charge = 0 - if(H.nutrition > 500) - H.nutrition = 500 + if(H.nutrition > NUTRITION_LEVEL_WELL_FED + 50) + H.nutrition = NUTRITION_LEVEL_WELL_FED + 50 src.charging = 1 else to_chat(user, "You are already fully charged.") @@ -1368,8 +1368,7 @@ spawn(0) for(var/obj/machinery/light/L in area) if(prob(chance)) - L.on = 1 - L.broken() + L.broken(0, 1) stoplag() /obj/machinery/power/apc/proc/setsubsystem(val) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index e2e97437b68..f88dce25b51 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -1,34 +1,6 @@ // the power cell // charge from 0 to 100% // fits in APC to provide backup power -/obj/item/weapon/stock_parts/cell/var/image/overlay_image - -/obj/item/weapon/stock_parts/cell/New() - ..() - processing_objects.Add(src) - charge = maxcharge - - spawn(5) - updateicon() - -/obj/item/weapon/stock_parts/cell/Destroy() - processing_objects.Remove(src) - return ..() - -/obj/item/weapon/stock_parts/cell/proc/updateicon() - if(isnull(src.overlay_image)) - src.overlay_image = image('icons/obj/power.dmi') - overlays.Cut() - - if(charge < 0.01) - return - else if(charge/maxcharge >=0.995) - src.overlay_image.icon_state = "cell-o2" - overlays += src.overlay_image - else - src.overlay_image.icon_state = "cell-o1" - overlays += src.overlay_image - /obj/item/weapon/stock_parts/cell/proc/percent() // return % charge of cell return 100.0*charge/maxcharge @@ -80,12 +52,12 @@ to_chat(user, "You inject the solution into the power cell.") - if(S.reagents.has_reagent("plasma", 5)) + if(S.reagents.has_reagent("plasma", 5) || S.reagents.has_reagent("plasma_dust", 5)) rigged = 1 - log_admin("LOG: [user.name] ([user.ckey]) injected a power cell with plasma, rigging it to explode.") - message_admins("LOG: [user.name] ([user.ckey]) injected a power cell with plasma, rigging it to explode.") + log_admin("LOG: [key_name(user)] injected a power cell with plasma, rigging it to explode.") + message_admins("LOG: [key_name_admin(user)] injected a power cell with plasma, rigging it to explode.") S.reagents.clear_reagents() diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 0ff6289ea66..a61aca5661c 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -10,23 +10,23 @@ var/obj/machinery/atmospherics/binary/circulator/hot_circ var/cold_dir = WEST - var/hot_dir = EAST - + var/hot_dir = EAST + var/lastgen = 0 var/lastgenlev = -1 var/lastcirc = "00" - + /obj/machinery/power/generator/New() ..() update_desc() - + /obj/machinery/power/generator/proc/update_desc() desc = initial(desc) + " Its cold circulator is located on the [dir2text(cold_dir)] side, and its heat circulator is located on the [dir2text(hot_dir)] side." - + /obj/machinery/power/generator/Destroy() disconnect() return ..() - + /obj/machinery/power/generator/proc/disconnect() if(cold_circ) cold_circ.generator = null @@ -38,10 +38,10 @@ /obj/machinery/power/generator/initialize() ..() connect() - + /obj/machinery/power/generator/proc/connect() connect_to_network() - + var/obj/machinery/atmospherics/binary/circulator/circpath = /obj/machinery/atmospherics/binary/circulator cold_circ = locate(circpath) in get_step(src, cold_dir) hot_circ = locate(circpath) in get_step(src, hot_dir) @@ -61,13 +61,13 @@ power_change() update_icon() updateDialog() - + /obj/machinery/power/generator/power_change() if(!anchored) stat |= NOPOWER else ..() - + /obj/machinery/power/generator/update_icon() if(stat & (NOPOWER|BROKEN)) overlays.Cut() @@ -79,7 +79,7 @@ overlays += image('icons/obj/power.dmi', "teg-oc[lastcirc]") -/obj/machinery/power/generator/process() +/obj/machinery/power/generator/process() if(stat & (NOPOWER|BROKEN)) return @@ -128,11 +128,11 @@ // update icon overlays only if displayed level has changed if(hot_air) - var/datum/gas_mixture/hot_circ_air1 = hot_circ.air1 + var/datum/gas_mixture/hot_circ_air1 = hot_circ.get_outlet_air() hot_circ_air1.merge(hot_air) if(cold_air) - var/datum/gas_mixture/cold_circ_air1 = cold_circ.air1 + var/datum/gas_mixture/cold_circ_air1 = cold_circ.get_outlet_air() cold_circ_air1.merge(cold_air) var/genlev = max(0, min( round(11 * lastgen / 100000), 11)) @@ -146,12 +146,12 @@ /obj/machinery/power/generator/attack_ai(mob/user) return attack_hand(user) - + /obj/machinery/power/generator/attack_ghost(mob/user) if(stat & (NOPOWER|BROKEN)) return - interact(user) - + interact(user) + /obj/machinery/power/generator/attack_hand(mob/user) if(..()) user << browse(null, "window=teg") @@ -168,29 +168,35 @@ connect() playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) to_chat(user, "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.") - else if(istype(W, /obj/item/device/multitool)) + else if(ismultitool(W)) if(cold_dir == WEST) cold_dir = EAST hot_dir = WEST - else + else if(cold_dir == NORTH) + cold_dir = SOUTH + hot_dir = NORTH + else if(cold_dir == EAST) cold_dir = WEST hot_dir = EAST + else + cold_dir = NORTH + hot_dir = SOUTH connect() to_chat(user, "You reverse the generator's circulator settings. The cold circulator is now on the [dir2text(cold_dir)] side, and the heat circulator is now on the [dir2text(hot_dir)] side.") update_desc() else - ..() - + ..() + /obj/machinery/power/generator/proc/get_menu(include_link = 1) var/t = "" if(!powernet) t += "Unable to connect to the power network!" t += "
Retry" else if(cold_circ && hot_circ) - var/datum/gas_mixture/cold_circ_air1 = cold_circ.air1 - var/datum/gas_mixture/cold_circ_air2 = cold_circ.air2 - var/datum/gas_mixture/hot_circ_air1 = hot_circ.air1 - var/datum/gas_mixture/hot_circ_air2 = hot_circ.air2 + var/datum/gas_mixture/cold_circ_air1 = cold_circ.get_outlet_air() + var/datum/gas_mixture/cold_circ_air2 = cold_circ.get_inlet_air() + var/datum/gas_mixture/hot_circ_air1 = hot_circ.get_outlet_air() + var/datum/gas_mixture/hot_circ_air2 = hot_circ.get_inlet_air() t += "
" diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 18a760f5f1d..2b2b3e20183 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -514,14 +514,14 @@ status = LIGHT_EMPTY update() -/obj/machinery/light/proc/broken(skip_sound_and_sparks = 0) +/obj/machinery/light/proc/broken(skip_sound_and_sparks = 0, overloaded = 0) if(status == LIGHT_EMPTY || status == LIGHT_BROKEN) return if(!skip_sound_and_sparks) if(status == LIGHT_OK || status == LIGHT_BURNED) playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) - if(on) + if(on || overloaded) var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() @@ -674,10 +674,10 @@ to_chat(user, "You inject the solution into the [src].") - if(S.reagents.has_reagent("plasma", 5)) + if(S.reagents.has_reagent("plasma", 5) || S.reagents.has_reagent("plasma_dust", 5)) - log_admin("LOG: [user.name] ([user.ckey]) injected a light with plasma, rigging it to explode.") - message_admins("LOG: [user.name] ([user.ckey]) injected a light with plasma, rigging it to explode.") + log_admin("LOG: [key_name(user)] injected a light with plasma, rigging it to explode.") + message_admins("LOG: [key_name_admin(user)] injected a light with plasma, rigging it to explode.") rigged = 1 diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index ee8f6d96c67..03b1d07b85b 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -32,7 +32,7 @@ var/area/A = get_area(src) if(A) var/image/alert_overlay = image('icons/effects/effects.dmi', "ghostalertsie") - notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, attack_not_jump = 1) + notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.", source = src, alert_overlay = alert_overlay, action=NOTIFY_ATTACK) narsie_spawn_animation() @@ -123,6 +123,8 @@ /obj/singularity/narsie/proc/acquire(var/mob/food) + if(food == target) + return to_chat(target, "[uppertext(ticker.mode.cultdat.entity_name)] HAS LOST INTEREST IN YOU") target = food if(ishuman(target)) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 2fa6facdab0..c0e61cc8236 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -37,6 +37,7 @@ src.energy = starting_energy ..() processing_objects.Add(src) + poi_list |= src for(var/obj/machinery/power/singularity_beacon/singubeacon in world) if(singubeacon.active) target = singubeacon @@ -45,6 +46,7 @@ /obj/singularity/Destroy() processing_objects.Remove(src) + poi_list.Remove(src) singularities -= src target = null return ..() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 323c240d239..c1a202fa134 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -64,6 +64,7 @@ /obj/machinery/power/supermatter_shard/New() . = ..() + poi_list |= src radio = new(src) radio.listening = 0 investigate_log("has been created.", "supermatter") @@ -71,8 +72,10 @@ /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") - qdel(radio) - radio = null + if(radio) + qdel(radio) + radio = null + poi_list.Remove(src) return ..() /obj/machinery/power/supermatter_shard/proc/explode() diff --git a/code/modules/power/supermatter/wall.dm b/code/modules/power/supermatter/wall.dm index e8997dee07c..afadcb23a46 100644 --- a/code/modules/power/supermatter/wall.dm +++ b/code/modules/power/supermatter/wall.dm @@ -49,7 +49,7 @@ icon_state = "smatter" temperature = T20C+80 density = 1 - opacity = 1 + set_opacity(1) blocks_air = 1 spawn(2) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index 14407ef9202..67bad46f4b2 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -34,6 +34,8 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics, var/produced_power var/energy_to_raise = 32 var/energy_to_lower = -20 + + /obj/singularity/energy_ball/Destroy() if(orbiting && istype(orbiting, /obj/singularity/energy_ball)) @@ -44,6 +46,8 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics, for(var/ball in orbiting_balls) var/obj/singularity/energy_ball/EB = ball qdel(EB) + + poi_list.Remove(src) return ..() @@ -125,6 +129,7 @@ var/list/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics, /obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target) if(istype(target)) target.orbiting_balls += src + poi_list.Remove(src) . = ..() diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index b5a990dec69..cbbe43cd32c 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -188,3 +188,9 @@ //Behavior for magazines /obj/item/ammo_box/magazine/proc/ammo_count() return stored_ammo.len + +/obj/item/ammo_box/magazine/proc/empty_magazine() + var/turf_mag = get_turf(src) + for(var/obj/item/ammo in stored_ammo) + ammo.forceMove(turf_mag) + stored_ammo -= ammo \ No newline at end of file diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index df34a279caf..3b808c64d53 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -3,6 +3,12 @@ caliber = "357" projectile_type = /obj/item/projectile/bullet +/obj/item/ammo_casing/rubber9mm + desc = "A 9mm rubber bullet casing." + caliber = "9mm" + icon_state = "r-casing" + projectile_type = /obj/item/projectile/bullet/weakbullet4 + /obj/item/ammo_casing/a762 desc = "A 7.62mm bullet casing." icon_state = "762-casing" @@ -20,6 +26,7 @@ /obj/item/ammo_casing/c38 desc = "A .38 bullet casing." caliber = "38" + icon_state = "r-casing" projectile_type = /obj/item/projectile/bullet/weakbullet2/rubber /obj/item/ammo_casing/c10mm @@ -76,6 +83,12 @@ caliber = "4.6x30mm" projectile_type = /obj/item/projectile/bullet/incendiary/firebullet +/obj/item/ammo_casing/rubber45 + desc = "A .45 rubber bullet casing." + caliber = ".45" + icon_state = "r-casing" + projectile_type = /obj/item/projectile/bullet/weakbullet4 + /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." caliber = ".45" @@ -120,7 +133,7 @@ /obj/item/ammo_casing/shotgun/rubbershot name = "rubber shot" desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance." - icon_state = "bshell" + icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/rpellet pellets = 6 variance = 25 @@ -233,9 +246,9 @@ /obj/item/ammo_casing/shotgun/dart/New() ..() - flags |= NOREACT flags |= OPENCONTAINER create_reagents(30) + reagents.set_reacting(FALSE) /obj/item/ammo_casing/shotgun/dart/attackby() return @@ -247,14 +260,14 @@ ..() reagents.add_reagent("neurotoxin", 6) reagents.add_reagent("spore", 6) - reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT + reagents.add_reagent("capulettium_plus", 6) //;HELP OPS IN MAINT reagents.add_reagent("coniine", 6) reagents.add_reagent("sodium_thiopental", 6) /obj/item/ammo_casing/shotgun/tranquilizer name = "tranquilizer darts" desc = "A tranquilizer round used to subdue individuals utilizing stimulants." - icon_state = "cshell" + icon_state = "nshell" projectile_type = /obj/item/projectile/bullet/dart/syringe/tranquilizer materials = list(MAT_METAL=250) @@ -362,3 +375,9 @@ desc = "A cap for children toys." caliber = "caps" projectile_type = /obj/item/projectile/bullet/cap + +/obj/item/ammo_casing/laser + desc = "An experimental laser casing." + caliber = "laser" + projectile_type = /obj/item/projectile/beam/laser + icon_state = "lasercasing" diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 894b5ac25b1..865ddc9641b 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -35,6 +35,12 @@ ammo_type = /obj/item/ammo_casing/c45 max_ammo = 20 +/obj/item/ammo_box/rubber45 + name = "ammo box (.45 rubber)" + icon_state = "45box-r" + ammo_type = /obj/item/ammo_casing/rubber45 + max_ammo = 16 + /obj/item/ammo_box/a40mm name = "ammo box (40mm grenades)" icon_state = "40mm" @@ -52,14 +58,14 @@ /obj/item/ammo_box/n762 name = "ammo box (7.62x38mmR)" - icon_state = "10mmbox" + icon_state = "riflebox" origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/n762 max_ammo = 14 /obj/item/ammo_box/shotgun name = "Ammunition Box (slug)" - icon_state = "9mmbox" + icon_state = "slugbox" origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/shotgun max_ammo = 7 @@ -67,26 +73,30 @@ /obj/item/ammo_box/shotgun/buck name = "Ammunition Box (buckshot)" + icon_state = "buckshotbox" ammo_type = /obj/item/ammo_casing/shotgun/buckshot /obj/item/ammo_box/shotgun/stun name = "Ammunition Box (stun shells)" + icon_state = "stunbox" ammo_type = /obj/item/ammo_casing/shotgun/stunslug materials = list(MAT_METAL=1750) /obj/item/ammo_box/shotgun/beanbag name = "Ammunition Box (beanbag shells)" + icon_state = "beanbagbox" ammo_type = /obj/item/ammo_casing/shotgun/beanbag materials = list(MAT_METAL=1750) /obj/item/ammo_box/shotgun/rubbershot name = "Ammunition Box (rubbershot shells)" + icon_state = "rubbershotbox" ammo_type = /obj/item/ammo_casing/shotgun/rubbershot materials = list(MAT_METAL=28000) /obj/item/ammo_box/shotgun/tranquilizer name = "Ammunition Box (tranquilizer darts)" - icon_state = "45box" + icon_state = "tranqbox" ammo_type = /obj/item/ammo_casing/shotgun/tranquilizer materials = list(MAT_METAL=1750) diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index 93e5d5f2bb4..d98f53ef74c 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -118,18 +118,6 @@ projectile_type = /obj/item/projectile/meteor select_name = "goddamn meteor" -/obj/item/ammo_casing/energy/kinetic - projectile_type = /obj/item/projectile/kinetic - select_name = "kinetic" - e_cost = 5000 - fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap - -/obj/item/ammo_casing/energy/kinetic/super - projectile_type = /obj/item/projectile/kinetic/super - -/obj/item/ammo_casing/energy/kinetic/hyper - projectile_type = /obj/item/projectile/kinetic/hyper - /obj/item/ammo_casing/energy/disabler projectile_type = /obj/item/projectile/beam/disabler select_name = "disable" diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 0f587c54bf4..5487f8d5bc9 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -209,6 +209,34 @@ caliber = ".45" max_ammo = 8 multiple_sprites = 1 +/obj/item/ammo_box/magazine/m45/enforcer45 + name = "handgun magazine (.45)" + icon_state = "enforcer" + ammo_type = /obj/item/ammo_casing/rubber45 + +/obj/item/ammo_box/magazine/m45/enforcer45/update_icon() + ..() + overlays.Cut() + + var/ammo = ammo_count() + if(ammo && is_rubber()) + overlays += image('icons/obj/ammo.dmi', icon_state = "enforcer-r") + +/obj/item/ammo_box/magazine/m45/enforcer45/examine(mob/user, var/distance) + ..() + if(distance <= 2) + to_chat(user, "It seems to be loaded with [is_rubber() ? "rubber" : "lethal"] bullets.")//only can see the topmost one. + +/obj/item/ammo_box/magazine/m45/enforcer45/proc/is_rubber()//if the topmost bullet is a rubber one + var/ammo = ammo_count() + if(!ammo) + return 0 + if(istype(contents[contents.len], /obj/item/ammo_casing/rubber45)) + return 1 + return 0 + + /obj/item/ammo_box/magazine/m45/enforcer45/lethal + ammo_type = /obj/item/ammo_casing/c45 /obj/item/ammo_box/magazine/wt550m9 name = "wt550 magazine (4.6x30mm)" @@ -409,3 +437,12 @@ /obj/item/ammo_box/magazine/toy/m762/update_icon() ..() icon_state = "a762-[round(ammo_count(),10)]" + +/obj/item/ammo_box/magazine/laser + name = "encased laser projector magazine" + desc = "Fits experimental laser ammo casings." + icon_state = "laser" + ammo_type = /obj/item/ammo_casing/laser + origin_tech = "combat=3" + caliber = "laser" + max_ammo = 20 diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm index d17d65e9fc8..d5c7df48200 100644 --- a/code/modules/projectiles/ammunition/special.dm +++ b/code/modules/projectiles/ammunition/special.dm @@ -26,6 +26,9 @@ /obj/item/ammo_casing/magic/chaos projectile_type = /obj/item/projectile/magic + +/obj/item/ammo_casing/magic/spellblade + projectile_type = /obj/item/projectile/magic/spellblade /obj/item/ammo_casing/magic/chaos/newshot() projectile_type = pick(typesof(/obj/item/projectile/magic)) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 6cafcce56c3..bba922624f1 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -45,7 +45,7 @@ lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/guns_righthand.dmi' - var/obj/item/device/flashlight/F = null + var/obj/item/device/flashlight/gun_light = null var/can_flashlight = 0 var/list/upgrades = list() @@ -63,7 +63,7 @@ /obj/item/weapon/gun/New() ..() - if(F) + if(gun_light) verbs += /obj/item/weapon/gun/proc/toggle_gunlight build_zooming() @@ -241,27 +241,27 @@ obj/item/weapon/gun/proc/newshot() if(istype(I, /obj/item/device/flashlight/seclite)) var/obj/item/device/flashlight/seclite/S = I if(can_flashlight) - if(!F) + if(!gun_light) if(!user.unEquip(I)) return to_chat(user, "You click [S] into place on [src].") if(S.on) set_light(0) - F = S + gun_light = S I.loc = src update_icon() - update_gunlight(user) + update_gun_light(user) var/datum/action/A = new /datum/action/item_action/toggle_gunlight(src) if(loc == user) A.Grant(user) if(istype(I, /obj/item/weapon/screwdriver)) - if(F && can_flashlight) + if(gun_light && can_flashlight) for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") - F = null + gun_light = null S.loc = get_turf(user) - update_gunlight(user) + update_gun_light(user) S.update_brightness(user) update_icon() for(var/datum/action/item_action/toggle_gunlight/TGL in actions) @@ -273,26 +273,26 @@ obj/item/weapon/gun/proc/newshot() ..() /obj/item/weapon/gun/proc/toggle_gunlight() - set name = "Toggle Gunlight" + set name = "Toggle Gun Light" set category = "Object" set desc = "Click to toggle your weapon's attached flashlight." - if(!F) + if(!gun_light) return var/mob/living/carbon/human/user = usr if(!isturf(user.loc)) to_chat(user, "You cannot turn the light on while in this [user.loc]!") - F.on = !F.on - to_chat(user, "You toggle the gunlight [F.on ? "on":"off"].") + gun_light.on = !gun_light.on + to_chat(user, "You toggle the gun light [gun_light.on ? "on":"off"].") playsound(user, 'sound/weapons/empty.ogg', 100, 1) - update_gunlight(user) + update_gun_light(user) -/obj/item/weapon/gun/proc/update_gunlight(mob/user = null) - if(F) - if(F.on) - set_light(F.brightness_on) +/obj/item/weapon/gun/proc/update_gun_light(mob/user = null) + if(gun_light) + if(gun_light.on) + set_light(gun_light.brightness_on) else set_light(0) update_icon() diff --git a/code/modules/projectiles/guns/dartgun.dm b/code/modules/projectiles/guns/dartgun.dm index b8f659eb09f..4ec3b827945 100644 --- a/code/modules/projectiles/guns/dartgun.dm +++ b/code/modules/projectiles/guns/dartgun.dm @@ -154,7 +154,7 @@ qdel(S) D.icon_state = "syringeproj" D.name = "syringe" - D.flags |= NOREACT + D.reagents.set_reacting(FALSE) playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) for(var/i=0, i<6, i++) @@ -173,8 +173,8 @@ R += A.id + " (" R += num2text(A.volume) + ")," if(istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" + M.create_attack_log("[user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])") + user.create_attack_log("[user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])") if(M.ckey) msg_admin_attack("[key_name_admin(user)] shot [M] ([M.ckey]) with a dartgun ([R]).") if(!iscarbon(user)) @@ -183,7 +183,7 @@ M.LAssailant = user else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [key_name_admin(M)] with a dartgun ([R])" + M.create_attack_log("UNKNOWN SUBJECT (No longer exists) shot [key_name_admin(M)] with a dartgun ([R])") msg_admin_attack("UNKNOWN shot [key_name(M)] with a dartgun ([R]) (JMP)") if(D.reagents) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 2d87a32be2b..4e5bbce386c 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -30,6 +30,12 @@ else power_supply = new(src) power_supply.give(power_supply.maxcharge) + update_ammo_types() + if(selfcharge) + processing_objects.Add(src) + update_icon() + +/obj/item/weapon/gun/energy/proc/update_ammo_types() var/obj/item/ammo_casing/energy/shot for(var/i = 1, i <= ammo_type.len, i++) var/shottype = ammo_type[i] @@ -38,9 +44,6 @@ shot = ammo_type[select] fire_sound = shot.fire_sound fire_delay = shot.delay - if(selfcharge) - processing_objects.Add(src) - update_icon() /obj/item/weapon/gun/energy/Destroy() if(selfcharge) @@ -129,9 +132,9 @@ overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1)) else overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]") - if(F && can_flashlight) + if(gun_light && can_flashlight) var/iconF = "flight" - if(F.on) + if(gun_light.on) iconF = "flight_on" overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) if(itemState) @@ -160,6 +163,14 @@ playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) return (OXYLOSS) +/obj/item/weapon/gun/energy/on_varedit(modified_var) + if(modified_var == "selfcharge") + if(selfcharge) + processing_objects.Add(src) + else + processing_objects.Remove(src) + ..() + /obj/item/weapon/gun/energy/proc/robocharge() if(isrobot(loc)) var/mob/living/silicon/robot/R = loc diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm new file mode 100644 index 00000000000..7b8872f7819 --- /dev/null +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -0,0 +1,416 @@ +/obj/item/weapon/gun/energy/kinetic_accelerator + name = "proto-kinetic accelerator" + desc = "A self recharging, ranged mining tool that does increased damage in low pressure. Capable of holding up to six slots worth of mod kits." + icon_state = "kineticgun" + item_state = "kineticgun" + ammo_type = list(/obj/item/ammo_casing/energy/kinetic) + cell_type = /obj/item/weapon/stock_parts/cell/emproof + needs_permit = 0 + unique_rename = 1 + origin_tech = "combat=3;powerstorage=3;engineering=3" + weapon_weight = WEAPON_LIGHT + can_flashlight = 1 + flight_x_offset = 15 + flight_y_offset = 9 + var/overheat_time = 16 + var/holds_charge = FALSE + var/unique_frequency = FALSE // modified by KA modkits + var/overheat = FALSE + + var/max_mod_capacity = 100 + var/list/modkits = list() + + var/empty_state = "kineticgun_empty" + +/obj/item/weapon/gun/energy/kinetic_accelerator/examine(mob/user) + if(..(user, 1)) + if(max_mod_capacity) + to_chat(user, "[get_remaining_mod_capacity()]% mod capacity remaining.") + for(var/A in get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + to_chat(user, "There is a [M.name] mod installed, using [M.cost]% capacity.") + +/obj/item/weapon/gun/energy/kinetic_accelerator/attackby(obj/item/A, mob/user) + if(istype(A, /obj/item/weapon/crowbar)) + if(modkits.len) + to_chat(user, "You pry the modifications out.") + playsound(loc, 'sound/items/Crowbar.ogg', 100, 1) + for(var/obj/item/borg/upgrade/modkit/M in modkits) + M.uninstall(src) + else + to_chat(user, "There are no modifications currently installed.") + else if(istype(A, /obj/item/borg/upgrade/modkit)) + var/obj/item/borg/upgrade/modkit/MK = A + MK.install(src, user) + else + ..() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity() + var/current_capacity_used = 0 + for(var/A in get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + current_capacity_used += M.cost + return max_mod_capacity - current_capacity_used + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_modkits() + . = list() + for(var/A in modkits) + . += A + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/item/projectile/kinetic/K) + for(var/A in get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + M.modify_projectile(K) + +/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg + holds_charge = TRUE + unique_frequency = TRUE + max_mod_capacity = 80 + +/obj/item/weapon/gun/energy/kinetic_accelerator/New() + . = ..() + if(!holds_charge) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot() + . = ..() + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user) + . = ..() + if(!can_shoot()) + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/dropped() + . = ..() + if(!holds_charge) + // Put it on a delay because moving item from slot to hand + // calls dropped(). + spawn(2) + empty_if_not_held() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty_if_not_held() + if(!ismob(loc)) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty() + power_supply.use(5000) + update_icon() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload() + if(overheat) + return + overheat = TRUE + + var/carried = 0 + if(!unique_frequency) + for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \ + loc.GetAllContents()) + + carried++ + + carried = max(carried, 1) + else + carried = 1 + + spawn(overheat_time * carried) + reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) + return + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload() + power_supply.give(5000) + if(!suppressed) + playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + else if(isliving(loc)) + to_chat(loc, "[src] silently charges up.") + update_icon() + overheat = FALSE + +/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon() + overlays.Cut() + if(empty_state && !can_shoot()) + overlays += empty_state + + if(gun_light && can_flashlight) + var/iconF = "flight" + if(gun_light.on) + iconF = "flight_on" + overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + + +//Casing +/obj/item/ammo_casing/energy/kinetic + projectile_type = /obj/item/projectile/kinetic + select_name = "kinetic" + e_cost = 5000 + fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap + +/obj/item/ammo_casing/energy/kinetic/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + if(loc && istype(loc, /obj/item/weapon/gun/energy/kinetic_accelerator)) + var/obj/item/weapon/gun/energy/kinetic_accelerator/KA = loc + KA.modify_projectile(BB) + + var/turf/proj_turf = get_turf(BB) + if(!isturf(proj_turf)) + return + var/datum/gas_mixture/environment = proj_turf.return_air() + var/pressure = environment.return_pressure() + if(pressure > 50) + BB.name = "weakened [BB.name]" + var/obj/item/projectile/kinetic/K = BB + K.damage *= K.pressure_decrease + + +//Projectiles +/obj/item/projectile/kinetic + name = "kinetic force" + icon_state = null + damage = 40 + damage_type = BRUTE + flag = "bomb" + range = 3 + log_override = TRUE + + var/pressure_decrease = 0.25 + var/turf_aoe = FALSE + var/mob_aoe = 0 + var/list/hit_overlays = list() + +/obj/item/projectile/kinetic/on_range() + strike_thing() + ..() + +/obj/item/projectile/kinetic/on_hit(atom/target) + strike_thing(target) + . = ..() + +/obj/item/projectile/kinetic/proc/strike_thing(atom/target) + var/turf/target_turf = get_turf(target) + if(!target_turf) + target_turf = get_turf(src) + if(ismineralturf(target_turf)) + var/turf/simulated/mineral/M = target_turf + M.gets_drilled(firer) + var/obj/effect/overlay/temp/kinetic_blast/K = new /obj/effect/overlay/temp/kinetic_blast(target_turf) + K.color = color + for(var/type in hit_overlays) + new type(target_turf) + if(turf_aoe) + for(var/T in RANGE_TURFS(1, target_turf) - target_turf) + if(ismineralturf(T)) + var/turf/simulated/mineral/M = T + M.gets_drilled(firer) + if(mob_aoe) + for(var/mob/living/L in range(1, target_turf) - firer - target) + var/armor = L.run_armor_check(def_zone, flag, "", "", armour_penetration) + L.apply_damage(damage*mob_aoe, damage_type, def_zone, armor) + to_chat(L, "You're struck by a [name]!") + + +//Modkits +/obj/item/borg/upgrade/modkit + name = "modification kit" + desc = "An upgrade for kinetic accelerators." + icon = 'icons/obj/objects.dmi' + icon_state = "modkit" + origin_tech = "programming=2;materials=2;magnets=4" + require_module = 1 + module_type = /obj/item/weapon/robot_module/miner + var/denied_type = null + var/maximum_of_type = 1 + var/cost = 30 + var/modifier = 1 //For use in any mod kit that has numerical modifiers + +/obj/item/borg/upgrade/modkit/examine(mob/user) + if(..(user, 1)) + to_chat(user, "Occupies [cost]% of mod capacity.") + +/obj/item/borg/upgrade/modkit/attackby(obj/item/A, mob/user) + if(istype(A, /obj/item/weapon/gun/energy/kinetic_accelerator) && !issilicon(user)) + install(A, user) + else + ..() + +/obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R) + if(..()) + return + + for(var/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules) + return install(H, usr) + +/obj/item/borg/upgrade/modkit/proc/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user) + . = TRUE + if(denied_type) + var/number_of_denied = 0 + for(var/A in KA.get_modkits()) + var/obj/item/borg/upgrade/modkit/M = A + if(istype(M, denied_type)) + number_of_denied++ + if(number_of_denied >= maximum_of_type) + . = FALSE + break + if(KA.get_remaining_mod_capacity() >= cost) + if(.) + to_chat(user, "You install the modkit.") + playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1) + user.unEquip(src) + forceMove(KA) + KA.modkits += src + else + to_chat(user, "The modkit you're trying to install would conflict with an already installed modkit. Use a crowbar to remove existing modkits.") + else + to_chat(user, "You don't have room([KA.get_remaining_mod_capacity()]% remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.") + . = FALSE + +/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA) + forceMove(get_turf(KA)) + KA.modkits -= src + +/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K) + + +//Range +/obj/item/borg/upgrade/modkit/range + name = "range increase" + desc = "Increases the range of a kinetic accelerator when installed." + modifier = 1 + cost = 24 //so you can fit four plus a tracer cosmetic + +/obj/item/borg/upgrade/modkit/range/modify_projectile(obj/item/projectile/kinetic/K) + K.range += modifier + + +//Damage +/obj/item/borg/upgrade/modkit/damage + name = "damage increase" + desc = "Increases the damage of kinetic accelerator when installed." + modifier = 10 + +/obj/item/borg/upgrade/modkit/damage/modify_projectile(obj/item/projectile/kinetic/K) + K.damage += modifier + + +//Cooldown +/obj/item/borg/upgrade/modkit/cooldown + name = "cooldown decrease" + desc = "Decreases the cooldown of a kinetic accelerator." + modifier = 2.5 + +/obj/item/borg/upgrade/modkit/cooldown/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user) + . = ..() + if(.) + KA.overheat_time -= modifier + +/obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA) + KA.overheat_time += modifier + ..() + + +//AoE blasts +/obj/item/borg/upgrade/modkit/aoe + modifier = 0 + +/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K) + K.name = "kinetic explosion" + if(!K.turf_aoe && !K.mob_aoe) + K.hit_overlays += /obj/effect/overlay/temp/explosion/fast + K.mob_aoe += modifier + +/obj/item/borg/upgrade/modkit/aoe/turfs + name = "mining explosion" + desc = "Causes the kinetic accelerator to destroy rock in an AoE." + denied_type = /obj/item/borg/upgrade/modkit/aoe/turfs + +/obj/item/borg/upgrade/modkit/aoe/turfs/modify_projectile(obj/item/projectile/kinetic/K) + ..() + K.turf_aoe = TRUE + +/obj/item/borg/upgrade/modkit/aoe/turfs/andmobs + name = "offensive mining explosion" + desc = "Causes the kinetic accelerator to destroy rock and damage mobs in an AoE." + maximum_of_type = 3 + modifier = 0.25 + +/obj/item/borg/upgrade/modkit/aoe/mobs + name = "offensive explosion" + desc = "Causes the kinetic accelerator to damage mobs in an AoE." + modifier = 0.2 + + +//Indoors +/obj/item/borg/upgrade/modkit/indoors + name = "decrease pressure penalty" + desc = "Increases the damage a kinetic accelerator does in a high pressure environment." + modifier = 2 + denied_type = /obj/item/borg/upgrade/modkit/indoors + maximum_of_type = 2 + cost = 40 + +/obj/item/borg/upgrade/modkit/indoors/modify_projectile(obj/item/projectile/kinetic/K) + K.pressure_decrease *= modifier + + +//Trigger Guard +/obj/item/borg/upgrade/modkit/trigger_guard + name = "modified trigger guard" + desc = "Allows creatures normally incapable of firing guns to operate the weapon when installed." + cost = 20 + denied_type = /obj/item/borg/upgrade/modkit/trigger_guard + +/obj/item/borg/upgrade/modkit/trigger_guard/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user) + . = ..() + if(.) + KA.trigger_guard = TRIGGER_GUARD_ALLOW_ALL + +/obj/item/borg/upgrade/modkit/trigger_guard/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA) + KA.trigger_guard = TRIGGER_GUARD_NORMAL + ..() + + +//Cosmetic + +/obj/item/borg/upgrade/modkit/chassis_mod + name = "super chassis" + desc = "Makes your KA yellow. All the fun of having a more powerful KA without actually having a more powerful KA." + cost = 0 + denied_type = /obj/item/borg/upgrade/modkit/chassis_mod + var/chassis_icon = "kineticgun_u" + var/chassis_name = "super-kinetic accelerator" + +/obj/item/borg/upgrade/modkit/chassis_mod/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user) + . = ..() + if(.) + KA.icon_state = chassis_icon + KA.name = chassis_name + +/obj/item/borg/upgrade/modkit/chassis_mod/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA) + KA.icon_state = initial(KA.icon_state) + KA.name = initial(KA.name) + ..() + +/obj/item/borg/upgrade/modkit/chassis_mod/orange + name = "hyper chassis" + desc = "Makes your KA orange. All the fun of having explosive blasts without actually having explosive blasts." + chassis_icon = "kineticgun_h" + chassis_name = "hyper-kinetic accelerator" + +/obj/item/borg/upgrade/modkit/tracer + name = "white tracer bolts" + desc = "Causes kinetic accelerator bolts to have a white tracer trail and explosion." + cost = 0 + denied_type = /obj/item/borg/upgrade/modkit/tracer + var/bolt_color = "#FFFFFF" + +/obj/item/borg/upgrade/modkit/tracer/modify_projectile(obj/item/projectile/kinetic/K) + K.icon_state = "ka_tracer" + K.color = bolt_color + +/obj/item/borg/upgrade/modkit/tracer/adjustable + name = "adjustable tracer bolts" + desc = "Causes kinetic accelerator bolts to have a adjustably-colored tracer trail and explosion. Use in-hand to change color." + +/obj/item/borg/upgrade/modkit/tracer/adjustable/attack_self(mob/user) + bolt_color = input(user,"Choose Color") as color diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 8d920a7e736..ef184bd8d5b 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -37,14 +37,14 @@ can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update /obj/item/weapon/gun/energy/gun/mini/New() - F = new /obj/item/device/flashlight/seclite(src) + gun_light = new /obj/item/device/flashlight/seclite(src) ..() power_supply.maxcharge = 6000 power_supply.charge = 6000 /obj/item/weapon/gun/energy/gun/mini/update_icon() ..() - if(F && F.on) + if(gun_light && gun_light.on) overlays += "mini-light" /obj/item/weapon/gun/energy/gun/hos diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index a648831cd8b..12eb34e8c54 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -84,141 +84,6 @@ ammo_type = list(/obj/item/ammo_casing/energy/mindflayer) ammo_x_offset = 2 -/obj/item/weapon/gun/energy/kinetic_accelerator - name = "proto-kinetic accelerator" - desc = "In the year 2544, only a year after the discovery of a potentially \ - world-changing substance, now colloquially referred to as plasma, the \ - Nanotrasen-UEG mining conglomerate introduced a prototype of a gun-like \ - device intended for quick, effective mining of plasma in the low \ - pressures of the solar system. Included in this presentation were \ - demonstrations of the gun being fired at collections of rocks contained \ - in vacuumed environments, obliterating them instantly while maintaining \ - the structure of the ores buried within them. Additionally, volunteers \ - were called from the crowd to have the gun used on them, only proving that \ - the gun caused little harm to objects in standard pressure. \n\ - An official from an unnamed, now long dissipated company observed this \ - presentation and offered to share their self-recharger cells, powered \ - by the user's bioelectrical field, another new and unknown technology. \ - They warned that the cells were incredibly experimental and several times \ - had injured workers, but the scientists as Nanotrasen were unable to resist \ - the money-saving potential of self recharging cells. Upon accepting this \ - offer, it took only a matter of days to prove the volatility of these cells, \ - as they exploded left and right whenever inserted into the prototype devices, \ - only throwing more money in the bin. \n\ - Whenever the Nanotrasen scientists were on the edge of giving up, a \ - breakthrough was made by head researcher Miles Parks McCollum, who \ - demonstrated that the cells could be stabilized when exposed to radium \ - then cooled with cryostylane. After this discovery, the low pressure gun, \ - now named the Kinetic Accelerator, was hastily completed and made compatible \ - with the self-recharging cells. As a result of poor testing, the currently \ - used guns lose their charge when not in use, and when two Kinetic Accelerators \ - come in proximity of one another, they will interfere with each other. Despite \ - this, the shoddy guns still see use in the mining of plasma to this day." - icon_state = "kineticgun" - item_state = "kineticgun" - ammo_type = list(/obj/item/ammo_casing/energy/kinetic) - cell_type = /obj/item/weapon/stock_parts/cell/emproof - // Apparently these are safe to carry? I'm sure goliaths would disagree. - needs_permit = 0 - unique_rename = 1 - origin_tech = "combat=3;powerstorage=3;engineering=3" - weapon_weight = WEAPON_LIGHT - can_flashlight = 1 - flight_x_offset = 15 - flight_y_offset = 9 - var/overheat_time = 16 - var/holds_charge = FALSE - var/unique_frequency = FALSE // modified by KA modkits - var/overheat = FALSE - -/obj/item/weapon/gun/energy/kinetic_accelerator/super - name = "super-kinetic accelerator" - desc = "An upgraded, superior version of the proto-kinetic accelerator." - icon_state = "kineticgun_u" - ammo_type = list(/obj/item/ammo_casing/energy/kinetic/super) - overheat_time = 15 - origin_tech = "combat=3;powerstorage=2" - -/obj/item/weapon/gun/energy/kinetic_accelerator/hyper - name = "hyper-kinetic accelerator" - desc = "An upgraded, even more superior version of the proto-kinetic accelerator." - icon_state = "kineticgun_h" - ammo_type = list(/obj/item/ammo_casing/energy/kinetic/hyper) - overheat_time = 14 - origin_tech = "combat=4;powerstorage=3" - -/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg - holds_charge = TRUE - unique_frequency = TRUE - -/obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg - holds_charge = TRUE - unique_frequency = TRUE - -/obj/item/weapon/gun/energy/kinetic_accelerator/New() - . = ..() - if(!holds_charge) - empty() - -/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot() - . = ..() - attempt_reload() - -/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user) - . = ..() - if(!can_shoot()) - attempt_reload() - -/obj/item/weapon/gun/energy/kinetic_accelerator/dropped() - . = ..() - if(!holds_charge) - // Put it on a delay because moving item from slot to hand - // calls dropped(). - spawn(1) - if(!ismob(loc)) - empty() - -/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty() - power_supply.use(5000) - update_icon() - -/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload() - if(overheat) - return - overheat = TRUE - - var/carried = 0 - if(!unique_frequency) - for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \ - loc.GetAllContents()) - - carried++ - - carried = max(carried, 1) - else - carried = 1 - - spawn(overheat_time * carried) - reload() - overheat = FALSE - -/obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) - return - -/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload() - power_supply.give(5000) - if(!suppressed) - playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) - else if(ismob(loc)) - to_chat(loc, "[src] silently charges up.") - update_icon() - -/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon() - if(!can_shoot()) - icon_state = "[initial(icon_state)]_empty" - else - icon_state = initial(icon_state) - /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow name = "mini energy crossbow" desc = "A weapon favored by syndicate stealth specialists." @@ -234,6 +99,9 @@ overheat_time = 20 holds_charge = TRUE unique_frequency = TRUE + can_flashlight = 0 + max_mod_capacity = 0 + empty_state = null /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja name = "energy dart thrower" diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index 9ef7de7f369..6479854f854 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -8,6 +8,7 @@ ammo_type = /obj/item/ammo_casing/magic/change icon_state = "staffofchange" item_state = "staffofchange" + fire_sound = "sound/magic/Staff_Change.ogg" /obj/item/weapon/gun/magic/staff/animate name = "staff of animation" @@ -15,6 +16,7 @@ ammo_type = /obj/item/ammo_casing/magic/animate icon_state = "staffofanimation" item_state = "staffofanimation" + fire_sound = "sound/magic/Staff_animation.ogg" /obj/item/weapon/gun/magic/staff/healing name = "staff of healing" @@ -22,6 +24,7 @@ ammo_type = /obj/item/ammo_casing/magic/heal icon_state = "staffofhealing" item_state = "staffofhealing" + fire_sound = "sound/magic/Staff_Healing.ogg" /obj/item/weapon/gun/magic/staff/healing/handle_suicide() //Stops people trying to commit suicide to heal themselves return @@ -35,6 +38,7 @@ max_charges = 10 recharge_rate = 2 no_den_usage = 1 + fire_sound = "sound/magic/Staff_Chaos.ogg" /obj/item/weapon/gun/magic/staff/door name = "staff of door creation" @@ -45,16 +49,17 @@ max_charges = 10 recharge_rate = 2 no_den_usage = 1 + fire_sound = "sound/magic/Staff_Door.ogg" /obj/item/weapon/gun/magic/staff/honk name = "staff of the honkmother" desc = "Honk" - fire_sound = "sound/items/airhorn.ogg" ammo_type = /obj/item/ammo_casing/magic/honk icon_state = "honker" item_state = "honker" max_charges = 4 recharge_rate = 8 + fire_sound = "sound/items/airhorn.ogg" /obj/item/weapon/gun/magic/staff/focus name = "mental focus" @@ -63,3 +68,23 @@ icon_state = "focus" item_state = "focus" ammo_type = list(/obj/item/ammo_casing/forcebolt) + +/obj/item/weapon/gun/magic/staff/spellblade + name = "spellblade" + desc = "A deadly combination of laziness and boodlust, this blade allows the user to dismember their enemies without all the hard work of actually swinging the sword." + fire_sound = "sound/magic/Fireball.ogg" + ammo_type = /obj/item/ammo_casing/magic/spellblade + icon_state = "spellblade" + item_state = "spellblade" + hitsound = 'sound/weapons/rapierhit.ogg' + force = 20 + armour_penetration = 75 + block_chance = 50 + sharp = 1 + edge = 1 + max_charges = 4 + +/obj/item/weapon/gun/magic/staff/spellblade/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(attack_type == PROJECTILE_ATTACK) + final_block_chance = 0 + return ..() diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index abde404e87d..572412dee8b 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -50,7 +50,7 @@ /obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user) user.visible_message("[user] zaps \himself with [src].") playsound(user, fire_sound, 50, 1) - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] zapped \himself with a [src]" + user.create_attack_log("[user]/[user.ckey] zapped \himself with a [src]") ///////////////////////////////////// //WAND OF DEATH @@ -59,6 +59,7 @@ /obj/item/weapon/gun/magic/wand/death name = "wand of death" desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail." + fire_sound = "sound/magic/WandoDeath.ogg" ammo_type = /obj/item/ammo_casing/magic/death icon_state = "deathwand" max_charges = 3 //3, 2, 2, 1 @@ -67,7 +68,7 @@ var/message ="You irradiate yourself with pure energy! " message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") to_chat(user, message) - user.adjustFireLoss(500) + user.adjustFireLoss(3000) charges-- ..() @@ -79,6 +80,7 @@ name = "wand of resurrection" desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason." ammo_type = /obj/item/ammo_casing/magic/heal + fire_sound = "sound/magic/Staff_Healing.ogg" icon_state = "revivewand" max_charges = 3 //3, 2, 2, 1 @@ -96,6 +98,7 @@ name = "wand of polymorph" desc = "This wand is attuned to chaos and will radically alter the victim's form." ammo_type = /obj/item/ammo_casing/magic/change + fire_sound = "sound/magic/Staff_Change.ogg" icon_state = "polywand" max_charges = 10 //10, 5, 5, 4 @@ -115,6 +118,7 @@ icon_state = "telewand" max_charges = 10 //10, 5, 5, 4 no_den_usage = 1 + fire_sound = "sound/magic/Wand_Teleport.ogg" /obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user) do_teleport(user, user, 10) @@ -132,6 +136,7 @@ name = "wand of door creation" desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics." ammo_type = /obj/item/ammo_casing/magic/door + fire_sound = "sound/magic/Staff_Door.ogg" icon_state = "doorwand" max_charges = 20 //20, 10, 10, 7 @@ -147,6 +152,7 @@ /obj/item/weapon/gun/magic/wand/fireball name = "wand of fireball" desc = "This wand shoots scorching balls of fire that explode into destructive flames." + fire_sound = "sound/magic/Fireball.ogg" ammo_type = /obj/item/ammo_casing/magic/fireball icon_state = "firewand" max_charges = 8 //8, 4, 4, 3 diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index d0e7efcd26b..e8ff8969fdf 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -249,3 +249,15 @@ /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) ..() empty_alarm() + +/obj/item/weapon/gun/projectile/automatic/lasercarbine + name = "\improper IK-60 Laser Carbine" + desc = "An experimental carbine. Uses encased laser projectors as ammunition."//we need to uncouple the toroidal resistance dejammers + icon_state = "lasercarbine" + item_state = "laser" + w_class = 3 + origin_tech = "combat=5;materials=5" + mag_type = /obj/item/ammo_box/magazine/laser + fire_sound = 'sound/weapons/emitter2.ogg' + can_suppress = 0 + burst_size = 2 diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm new file mode 100644 index 00000000000..2512ebfa35f --- /dev/null +++ b/code/modules/projectiles/guns/projectile/bow.dm @@ -0,0 +1,98 @@ +/obj/item/weapon/gun/projectile/bow + name = "bow" + desc = "A sturdy bow made out of wood and reinforced with iron." + icon_state = "bow_unloaded" + item_state = "bow" + fire_sound = 'sound/weapons/grenadelaunch.ogg' + mag_type = /obj/item/ammo_box/magazine/internal/bow + flags = HANDSLOW + weapon_weight = WEAPON_HEAVY + var/draw_sound = 'sound/weapons/draw_bow.ogg' + var/ready_to_fire = 0 + var/slowdown_when_ready = 2 + +/obj/item/weapon/gun/projectile/bow/update_icon() + if(magazine.ammo_count() && !ready_to_fire) + icon_state = "bow_loaded" + else if(ready_to_fire) + icon_state = "bow_firing" + slowdown = slowdown_when_ready + else + icon_state = initial(icon_state) + slowdown = initial(slowdown) + +/obj/item/weapon/gun/projectile/bow/dropped(mob/user) + if(magazine && magazine.ammo_count()) + magazine.empty_magazine() + ready_to_fire = FALSE + update_icon() + +/obj/item/weapon/gun/projectile/bow/attack_self(mob/living/user) + if(!ready_to_fire && magazine.ammo_count()) + ready_to_fire = TRUE + playsound(user, draw_sound, 100, 1) + update_icon() + else + ready_to_fire = FALSE + update_icon() + +/obj/item/weapon/gun/projectile/bow/attackby(obj/item/A, mob/user, params) + var/num_loaded = magazine.attackby(A, user, params, 1) + if(num_loaded) + to_chat(user, "You ready \the [A] into \the [src].") + update_icon() + chamber_round() + +/obj/item/weapon/gun/projectile/bow/can_shoot() + . = ..() + if(!ready_to_fire) + return FALSE + +/obj/item/weapon/gun/projectile/bow/shoot_with_empty_chamber(mob/living/user as mob|obj) + return + +/obj/item/weapon/gun/projectile/bow/process_chamber(eject_casing = 0, empty_chamber = 1) + . = ..() + ready_to_fire = FALSE + update_icon() + +// ammo +/obj/item/ammo_box/magazine/internal/bow + name = "bow internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/arrow + caliber = "arrow" + max_ammo = 1 + + +/obj/item/projectile/bullet/reusable/arrow + name = "arrow" + icon_state = "arrow" + ammo_type = /obj/item/ammo_casing/caseless/arrow + range = 10 + damage = 25 + damage_type = BRUTE + +/obj/item/ammo_casing/caseless/arrow + name = "arrow" + desc = "Stab, stab, stab." + icon_state = "arrow" + force = 10 + sharp = 1 + projectile_type = /obj/item/projectile/bullet/reusable/arrow + caliber = "arrow" + +//quiver +/obj/item/weapon/storage/backpack/quiver + name = "quiver" + desc = "A quiver for holding arrows." + icon_state = "quiver" + item_state = "quiver" + storage_slots = 20 + can_hold = list( + /obj/item/ammo_casing/caseless/arrow + ) + +/obj/item/weapon/storage/backpack/quiver/full/New() + ..() + for(var/i in 1 to storage_slots) + new /obj/item/ammo_casing/caseless/arrow(src) diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index d1d65dcbfc0..5de627d7933 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -40,6 +40,14 @@ mag_type = /obj/item/ammo_box/magazine/m50 can_suppress = 0 +/obj/item/weapon/gun/projectile/automatic/pistol/enforcer45 + name = "Enforcer .45" + desc = "A pistol of modern design." + icon_state = "enforcer" + force = 10 + mag_type = /obj/item/ammo_box/magazine/m45/enforcer45 + can_suppress = 0 + /obj/item/weapon/gun/projectile/automatic/pistol/deagle/update_icon() ..() icon_state = "[initial(icon_state)][magazine ? "" : "-e"]" diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm index d36ad1dd2c6..72e4bacebab 100644 --- a/code/modules/projectiles/guns/projectile/saw.dm +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -87,7 +87,7 @@ obj/item/projectile/bullet/saw/incen/Move() ..() var/turf/location = get_turf(src) if(location) - PoolOrNew(/obj/effect/hotspot, location) + new /obj/effect/hotspot(location) location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/saw/incen/on_hit(atom/target, blocked = 0) diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index cf7c2a4bb35..bf26dad78b3 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -53,6 +53,7 @@ damage = 70 stun = 5 weaken = 5 + dismemberment = 50 armour_penetration = 50 var/breakthings = TRUE @@ -82,6 +83,7 @@ armour_penetration = 0 nodamage = 1 stun = 0 + dismemberment = 0 weaken = 0 breakthings = FALSE @@ -113,6 +115,7 @@ armour_penetration = 15 damage = 15 stun = 0 + dismemberment = 0 weaken = 0 breakthings = FALSE @@ -142,5 +145,6 @@ damage = 60 forcedodge = 1 stun = 0 + dismemberment = 0 weaken = 0 breakthings = FALSE diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 6692e493f79..4a3afd18684 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -50,6 +50,9 @@ var/jitter = 0 var/embed = 0 // whether or not the projectile can embed itself in the mob var/forcedodge = 0 //to pass through everything + var/dismemberment = 0 //The higher the number, the greater the bonus to dismembering. 0 will not dismember at all. + + var/log_override = FALSE //whether print to admin attack logs or just keep it in the diary /obj/item/projectile/New() permutated = list() @@ -87,7 +90,8 @@ for(var/datum/reagent/R in reagents.reagent_list) reagent_note += R.id + " (" reagent_note += num2text(R.volume) + ") " - add_logs(firer, L, "shot", src, reagent_note) + if(!log_override && firer && original) + add_logs(firer, L, "shot", src, reagent_note) return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) /obj/item/projectile/proc/vol_by_damage() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index d9cf8360d2a..6cddc1c1b91 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -20,6 +20,7 @@ name = "practice laser" damage = 0 nodamage = 1 + log_override = TRUE /obj/item/projectile/beam/scatter name = "laser pellet" @@ -74,6 +75,7 @@ damage_type = STAMINA flag = "laser" var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) + log_override = TRUE /obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0) . = ..() diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 9c3475d2141..ccab76f6e92 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -42,6 +42,7 @@ damage = 5 weaken = 3 stamina = 60 + icon_state = "bullet-r" /obj/item/projectile/bullet/weakbullet2/rubber //detective's bullets that don't embed embed = 0 @@ -50,6 +51,13 @@ /obj/item/projectile/bullet/weakbullet3 damage = 20 +/obj/item/projectile/bullet/weakbullet4 + name = "rubber bullet" + damage = 5 + stamina = 30 + icon_state = "bullet-r" + embed = 0 + sharp = 0 /obj/item/projectile/bullet/toxinbullet damage = 15 @@ -135,6 +143,7 @@ name = "rubber pellet" damage = 3 stamina = 25 + icon_state = "bullet-r" /obj/item/projectile/bullet/stunshot//taser slugs for shotguns, nothing special name = "stunshot" @@ -197,7 +206,7 @@ nodamage = 1 pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE hitsound = 'sound/items/bikehorn.ogg' - icon = 'icons/obj/harvest.dmi' + icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "banana" range = 200 @@ -234,8 +243,8 @@ /obj/item/projectile/bullet/dart/New() ..() - flags |= NOREACT create_reagents(50) + reagents.set_reacting(FALSE) /obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) if(iscarbon(target)) @@ -251,7 +260,7 @@ target.visible_message("The [name] was deflected!", \ "You were protected against the [name]!") ..(target, blocked, hit_zone) - flags &= ~NOREACT + reagents.set_reacting(TRUE) reagents.handle_reactions() return 1 diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 838f1acd90c..b0d2a53c0d9 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -10,9 +10,6 @@ /obj/item/projectile/magic/death name = "bolt of death" icon_state = "pulse1_bl" - damage_type = BURN //OXY does not kill IPCs - damage = 50000 - nodamage = 0 /obj/item/projectile/magic/fireball name = "bolt of fireball" @@ -20,15 +17,32 @@ damage = 10 damage_type = BRUTE nodamage = 0 + + //explosion values + var/exp_heavy = 0 + var/exp_light = 2 + var/exp_flash = 3 + var/exp_fire = 2 + +/obj/item/projectile/magic/death/on_hit(var/mob/living/carbon/G) + . = ..() + if(isliving(G)) + G.adjustFireLoss(3000) + visible_message("[G] topples backwards as the death bolt impacts them!") /obj/item/projectile/magic/fireball/Range() var/turf/T1 = get_step(src,turn(dir, -45)) var/turf/T2 = get_step(src,turn(dir, 45)) + var/turf/T3 = get_step(src,dir) var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it. if(L && L.stat != DEAD) Bump(L) //Magic Bullet #teachthecontroversy return L = locate(/mob/living) in T2 + if(L && L.stat != DEAD) + Bump(L) + return + L = locate(/mob/living) in T3 if(L && L.stat != DEAD) Bump(L) return @@ -41,6 +55,14 @@ if(ismob(target)) //multiple flavors of pain var/mob/living/M = target M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately + + +/obj/item/projectile/magic/fireball/infernal + name = "infernal fireball" + exp_heavy = -1 + exp_light = -1 + exp_flash = 4 + exp_fire= 5 /obj/item/projectile/magic/resurrection name = "bolt of resurrection" @@ -218,7 +240,7 @@ proc/wabbajack(mob/living/M) else return - M.attack_log += text("\[[time_stamp()]\] [M.real_name] ([M.ckey]) became [new_mob.real_name].") + M.create_attack_log("[M.real_name] ([M.ckey]) became [new_mob.real_name].") new_mob.attack_log = M.attack_log new_mob.a_intent = I_HARM @@ -263,3 +285,12 @@ proc/wabbajack(mob/living/M) // Change our allegiance! var/mob/living/simple_animal/hostile/mimic/copy/C = change C.ChangeOwner(firer) + +/obj/item/projectile/magic/spellblade + name = "blade energy" + icon_state = "lavastaff" + damage = 15 + damage_type = BURN + flag = "magic" + dismemberment = 50 + nodamage = 0 \ No newline at end of file diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 12e7b30c759..cb0ee34ad75 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -37,6 +37,7 @@ var/obj/item/weapon/pen/pen = null edge = 0 embed = 0 + log_override = TRUE//it won't log even when there's a pen inside, but since the damage will be so low, I don't think there's any point in making it any more complex /obj/item/projectile/bullet/reusable/foam_dart/handle_drop() if(dropped) @@ -64,3 +65,4 @@ icon_state = "foamdart_riot" ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot stamina = 25 + log_override = FALSE diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 27e996bb457..83a4ec0650c 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -136,12 +136,11 @@ var/mob/living/M = target if(ishuman(target)) var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) + if(H.species.flags & IS_PLANT) if(prob(15)) M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) - for(var/mob/V in viewers(src)) - V.show_message("[M] writhes in pain as \his vacuoles boil.", 3, "You hear the crunching of leaves.", 2) + M.visible_message("[M] writhes in pain as \his vacuoles boil.", "You writhe in pain as your vacuoles boil!", "You hear the crunching of leaves.") if(prob(35)) if(prob(80)) randmutb(M) @@ -152,7 +151,7 @@ else M.adjustFireLoss(rand(5,15)) M.show_message("The radiation beam singes you!") - else if(istype(target, /mob/living/carbon/)) + else if(iscarbon(target)) M.show_message("The radiation beam dissipates harmlessly through your body.") else return 1 @@ -170,9 +169,9 @@ var/mob/M = target if(ishuman(target)) //These rays make plantmen fat. var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) - M.nutrition += 30 - else if(istype(target, /mob/living/carbon/)) + if(H.species.flags & IS_PLANT) + H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL) + else if(iscarbon(target)) M.show_message("The radiation beam dissipates harmlessly through your body.") else return 1 @@ -202,62 +201,6 @@ playsound(src, 'sound/effects/snap.ogg', 50, 1) qdel(src) -/obj/item/projectile/kinetic - name = "kinetic force" - icon_state = null - damage = 10 - damage_type = BRUTE - flag = "bomb" - range = 3 - var/splash = 0 - -/obj/item/projectile/kinetic/super - damage = 11 - range = 4 - -/obj/item/projectile/kinetic/hyper - damage = 12 - range = 5 - splash = 1 - -obj/item/projectile/kinetic/New() - var/turf/proj_turf = get_turf(src) - if(!istype(proj_turf, /turf)) - return - var/datum/gas_mixture/environment = proj_turf.return_air() - var/pressure = environment.return_pressure() - if(pressure < 50) - name = "full strength kinetic force" - damage *= 4 - ..() - -/obj/item/projectile/kinetic/on_range() - new /obj/effect/kinetic_blast(loc) - ..() - -/obj/item/projectile/kinetic/on_hit(atom/target) - . = ..() - var/turf/target_turf= get_turf(target) - if(istype(target_turf, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = target_turf - M.gets_drilled(firer) - new /obj/effect/kinetic_blast(target_turf) - if(splash) - for(var/turf/T in range(splash, target_turf)) - if(istype(T, /turf/simulated/mineral)) - var/turf/simulated/mineral/M = T - M.gets_drilled(firer) - -/obj/effect/kinetic_blast - name = "kinetic explosion" - icon = 'icons/obj/projectiles.dmi' - icon_state = "kinetic_blast" - layer = 4.1 - -/obj/effect/kinetic_blast/New() - spawn(4) - qdel(src) - /obj/item/projectile/beam/wormhole name = "bluespace beam" icon_state = "spark" @@ -300,6 +243,7 @@ obj/item/projectile/kinetic/New() damage_type = BRUTE damage = 5 range = 3 + dismemberment = 20 /obj/item/projectile/plasma/New() var/turf/proj_turf = get_turf(src) diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9c0c14014e4..2b1a8706123 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -13,10 +13,12 @@ var/const/INGEST = 2 var/atom/my_atom = null var/chem_temp = 300 var/list/datum/reagent/addiction_list = new/list() + var/flags -/datum/reagents/New(maximum=100) +/datum/reagents/New(maximum = 100) maximum_volume = maximum - + if(!(flags & REAGENT_NOREACT)) + processing_objects |= src //I dislike having these here but map-objects are initialised before world/New() is called. >_> if(!chemical_reagents_list) //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -288,11 +290,24 @@ var/const/INGEST = 2 od_chems.Add(R.id) return od_chems +/datum/reagents/proc/process() + if(flags & REAGENT_NOREACT) + processing_objects -= src + return -/datum/reagents/proc/reagent_on_tick() for(var/datum/reagent/R in reagent_list) R.on_tick() - return + +/datum/reagents/proc/set_reacting(react = TRUE) + if(react) + // Order is important, process() can remove from processing if + // the flag is present + flags &= ~(REAGENT_NOREACT) + processing_objects |= src + else + processing_objects -= src + flags |= REAGENT_NOREACT + /* if(!target) return var/total_transfered = 0 @@ -337,7 +352,7 @@ var/const/INGEST = 2 update_total() /datum/reagents/proc/handle_reactions() - if(my_atom.flags & NOREACT) + if(flags & REAGENT_NOREACT) return //Yup, no reactions here. No siree. var/reaction_occured = 0 @@ -711,6 +726,16 @@ atom/proc/create_reagents(max_vol) reagents = new/datum/reagents(max_vol) reagents.my_atom = src +/proc/get_random_reagent_id() // Returns a random reagent ID minus blacklisted reagents + var/static/list/random_reagents = list() + if(!random_reagents.len) + for(var/thing in subtypesof(/datum/reagent)) + var/datum/reagent/R = thing + if(initial(R.can_synth)) + random_reagents += initial(R.id) + var/picked_reagent = pick(random_reagents) + return picked_reagent + /datum/reagents/proc/get_reagent_from_id(id) var/datum/reagent/result = null for(var/datum/reagent/R in reagent_list) @@ -721,7 +746,7 @@ atom/proc/create_reagents(max_vol) /datum/reagents/Destroy() . = ..() - processing_objects.Remove(src) + processing_objects -= src for(var/datum/reagent/R in reagent_list) qdel(R) reagent_list.Cut() diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 38cfdf4b0ae..278ec7ad82f 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -3,62 +3,85 @@ icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" layer = 2.9 - density = 1 anchored = 1 use_power = 1 idle_power_usage = 5 active_power_usage = 100 - var/inuse = 0 + pass_flags = PASSTABLE + var/operating = 0 var/obj/item/weapon/reagent_containers/beaker = null var/limit = 10 //IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent var/list/blend_items = list ( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma_dust" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/weapon/grown/novaflower = list("capsaicin" = 0), + //Sheets + /obj/item/stack/sheet/mineral/plasma = list("plasma_dust" = 20), + /obj/item/stack/sheet/metal = list("iron" = 20), + /obj/item/stack/rods = list("iron" = 10), + /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma_dust" = 20), + /obj/item/stack/sheet/wood = list("carbon" = 20), + /obj/item/stack/sheet/glass = list("silicon" = 20), + /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), + /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), + /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), + /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20), + /obj/item/stack/sheet/mineral/silver = list("silver" = 20), + /obj/item/stack/sheet/mineral/gold = list("gold" = 20), + /obj/item/weapon/grown/nettle/basic = list("sacid" = 0), + /obj/item/weapon/grown/nettle/death = list("facid" = 0, "sacid" = 0), + /obj/item/weapon/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //archaeology! - ///obj/item/weapon/rocksliver = list("ground_rock" = 50), + //Blender Stuff + /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), + /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), + /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), + /obj/item/weapon/reagent_containers/food/snacks/egg = list("egg" = -5), + + //Grinder stuff, but only if dry + /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/weapon/reagent_containers/food = list(), - /obj/item/weapon/reagent_containers/honeycomb = list() - ) - - var/list/blend_tags = list ( - "nettle" = list("sacid" = 0), - "deathnettle" = list("facid" = 0), - "soybeans" = list("soymilk" = 0), - "tomato" = list("ketchup" = 0), - "wheat" = list("flour" = -5), - "rice" = list("rice" = -5), - "cherries" = list("cherryjelly" = 0), + //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! + /obj/item/slime_extract = list(), + /obj/item/weapon/reagent_containers/food = list(), + /obj/item/weapon/reagent_containers/honeycomb = list() ) var/list/juice_items = list ( - /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), + + //Juicer Stuff + /obj/item/weapon/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/banana = list("banana" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/potato = list("potato" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0), ) - var/list/juice_tags = list ( - "tomato" = list("tomatojuice" = 0), - "carrot" = list("carrotjuice" = 0), - "berries" = list("berryjuice" = 0), - "banana" = list("banana" = 0), - "potato" = list("potato" = 0), - "lemon" = list("lemonjuice" = 0), - "orange" = list("orangejuice" = 0), - "lime" = list("limejuice" = 0), - "poisonberries" = list("poisonberryjuice" = 0), - "grapes" = list("grapejuice" = 0), - "corn" = list("cornoil" = 0), + var/list/dried_items = list( + //Grinder stuff, but only if dry, + /obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), + /obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0) ) var/list/holdingitems = list() @@ -68,348 +91,359 @@ beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) return +/obj/machinery/reagentgrinder/Destroy() + if(beaker) + qdel(beaker) + beaker = null + return ..() + +/obj/machinery/reagentgrinder/ex_act(severity) + if(beaker) + beaker.ex_act(severity) + ..() + /obj/machinery/reagentgrinder/update_icon() - icon_state = "juicer"+num2text(!isnull(beaker)) - return + if(beaker) + icon_state = "juicer1" + else + icon_state = "juicer0" -/obj/machinery/reagentgrinder/attackby(obj/item/O, mob/user, params) - - if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) - - if(beaker) - return 1 - else - if(!user.drop_item()) - to_chat(user, "[O] is stuck to you!") +/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) + if(default_unfasten_wrench(user, I)) return - beaker = O - O.forceMove(src) - update_icon() - updateUsrDialog() - return 0 - if(holdingitems && holdingitems.len >= limit) - to_chat(usr, "The machine cannot hold anymore items.") - return 1 + if (istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER) ) + if (!beaker) + if(!user.drop_item()) + return 1 + beaker = I + beaker.loc = src + update_icon() + src.updateUsrDialog() + else + to_chat(user, "There's already a container inside.") + return 1 //no afterattack - //Fill machine with a plantbag! - if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/PB = O - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents) - PB.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - to_chat(user, "You must dry that first!") + return 1 - if(!PB.contents.len) - to_chat(user, "You empty [PB] into the All-In-One grinder.") + if(holdingitems && holdingitems.len >= limit) + to_chat(usr, "The machine cannot hold anymore items.") + return 1 - updateUsrDialog() - return 0 + //Fill machine with a bag! + if(istype(I, /obj/item/weapon/storage/bag)) + var/obj/item/weapon/storage/bag/B = I + for (var/obj/item/weapon/reagent_containers/food/snacks/grown/G in B.contents) + B.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill + to_chat(user, "You fill the All-In-One grinder to the brim.") + break + if(!I.contents.len) + to_chat(user, "You empty the plant bag into the All-In-One grinder.") - if(!is_type_in_list(O, blend_items) && !is_type_in_list(O, juice_items)) - to_chat(user, "Cannot refine into a reagent.") - return 1 + src.updateUsrDialog() + return 1 - user.unEquip(O) - O.forceMove(src) - holdingitems += O - updateUsrDialog() - return 0 + if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(user.a_intent == I_HARM) + return ..() + else + to_chat(user, "Cannot refine into a reagent!") + return 1 + + if(user.drop_item()) + I.loc = src + holdingitems += I + src.updateUsrDialog() + return 0 /obj/machinery/reagentgrinder/attack_ai(mob/user) - return 0 + return 0 /obj/machinery/reagentgrinder/attack_hand(mob/user) - user.set_machine(src) - interact(user) + user.set_machine(src) + interact(user) /obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" + var/is_chamber_empty = 0 + var/is_beaker_ready = 0 + var/processing_chamber = "" + var/beaker_contents = "" + var/dat = "" - if(!inuse) - for(var/obj/item/O in holdingitems) - processing_chamber += "\A [O.name]
" + if(!operating) + for (var/obj/item/O in holdingitems) + processing_chamber += "\A [O.name]
" - if(!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if(!beaker) - beaker_contents = "No beaker attached.
" + if (!processing_chamber) + is_chamber_empty = 1 + processing_chamber = "Nothing." + if (!beaker) + beaker_contents = "No beaker attached.
" + else + is_beaker_ready = 1 + beaker_contents = "The beaker contains:
" + var/anything = 0 + for(var/datum/reagent/R in beaker.reagents.reagent_list) + anything = 1 + beaker_contents += "[R.volume] - [R.name]
" + if(!anything) + beaker_contents += "Nothing
" + + + dat = {" + Processing chamber contains:
+ [processing_chamber]
+ [beaker_contents]
+ "} + if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) + dat += "Grind the reagents
" + dat += "Juice the reagents

" + if(holdingitems && holdingitems.len > 0) + dat += "Eject the reagents
" + if (beaker) + dat += "Detach the beaker
" else - is_beaker_ready = 1 - beaker_contents = "The beaker contains:
" - var/anything = 0 - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = 1 - beaker_contents += "[R.volume] - [R.name]
" - if(!anything) - beaker_contents += "Nothing
" + dat += "Please wait..." - - dat = {" - Processing chamber contains:
- [processing_chamber]
- [beaker_contents]
- "} - if(is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
" - dat += "Juice the reagents

" - if(holdingitems && holdingitems.len > 0) - dat += "Eject the reagents
" - if(beaker) - dat += "Detach the beaker
" - else - dat += "Please wait..." - user << browse("All-In-One Grinder[dat]", "window=reagentgrinder") - onclose(user, "reagentgrinder") - return + var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open(1) + return /obj/machinery/reagentgrinder/Topic(href, href_list) if(..()) return usr.set_machine(src) + if(operating) + updateUsrDialog() + return switch(href_list["action"]) - if("grind") + if ("grind") grind() if("juice") juice() if("eject") eject() - if("detach") + if ("detach") detach() - updateUsrDialog() - return /obj/machinery/reagentgrinder/proc/detach() - if(usr.stat != 0) - return - if(!beaker) - return - beaker.forceMove(loc) - beaker = null - update_icon() + if (usr.stat != 0) + return + if (!beaker) + return + beaker.loc = src.loc + beaker = null + update_icon() + updateUsrDialog() /obj/machinery/reagentgrinder/proc/eject() - if(usr.stat != 0) - return - if(holdingitems && holdingitems.len == 0) - return + if (usr.stat != 0) + return + if (holdingitems && holdingitems.len == 0) + return - for(var/obj/item/O in holdingitems) - O.forceMove(loc) - holdingitems -= O - holdingitems = list() + for(var/obj/item/O in holdingitems) + O.loc = src.loc + holdingitems -= O + holdingitems = list() + updateUsrDialog() /obj/machinery/reagentgrinder/proc/is_allowed(obj/item/weapon/reagent_containers/O) - for(var/i in blend_items) - if(istype(O, i)) - return 1 - return 0 + for (var/i in blend_items) + if(istype(O, i)) + return 1 + return 0 -/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/weapon/grown/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] +/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O) + for (var/i in blend_items) + if (istype(O, i)) + return blend_items[i] /obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] + for(var/i in blend_items) + if(istype(O, i)) + return blend_items[i] /obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) - for(var/i in blend_tags) - if(O.seed.kitchen_tag == i) - return blend_tags[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) - for(var/i in juice_tags) - if(O.seed.kitchen_tag == i) - return juice_tags[i] + for(var/i in juice_items) + if(istype(O, i)) + return juice_items[i] /obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/weapon/grown/O) - if(!istype(O)) - return 5 - else if(O.potency == -1) - return 5 - else - return round(O.potency) + if (!istype(O) || !O.seed) + return 5 + else if (O.seed.potency == -1) + return 5 + else + return round(O.seed.potency) /obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O) - if(!istype(O)) - return 5 - else if(O.potency == -1) - return 5 - else - return round(5*sqrt(O.potency)) + if (!istype(O) || !O.seed) + return 5 + else if (O.seed.potency == -1) + return 5 + else + return round(5*sqrt(O.seed.potency)) /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) - holdingitems -= O - qdel(O) + holdingitems -= O + qdel(O) /obj/machinery/reagentgrinder/proc/juice() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(loc, 'sound/machines/juicer.ogg', 20, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - inuse = 1 - spawn(50) - pixel_x = initial(pixel_x) //return to its spot after shaking - inuse = 0 - interact(usr) - //Snacks - for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break + power_change() + if(stat & (NOPOWER|BROKEN)) + return + if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking + operating = 1 + updateUsrDialog() + spawn(50) + pixel_x = initial(pixel_x) //return to its spot after shaking + operating = 0 + updateUsrDialog() - var/allowed = null - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - allowed = get_allowed_juice_by_tag(O) - else - allowed = get_allowed_juice_by_id(O) - if(isnull(allowed)) - break + //Snacks + for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break - for(var/r_id in allowed) + var/allowed = get_allowed_juice_by_id(O) + if(isnull(allowed)) + break - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) + for (var/r_id in allowed) - beaker.reagents.add_reagent(r_id, min(amount, space)) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = get_juice_amount(O) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break + beaker.reagents.add_reagent(r_id, min(amount, space)) - remove_object(O) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + remove_object(O) /obj/machinery/reagentgrinder/proc/grind() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(loc, 'sound/machines/blender.ogg', 50, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - inuse = 1 - spawn(60) - pixel_x = initial(pixel_x) //return to its spot after shaking - inuse = 0 - interact(usr) - //Snacks and Plants - for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break + power_change() + if(stat & (NOPOWER|BROKEN)) + return + if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking + operating = 1 + updateUsrDialog() + spawn(60) + pixel_x = initial(pixel_x) //return to its spot after shaking + operating = 0 + updateUsrDialog() - var/allowed = null - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - allowed = get_allowed_snack_by_tag(O) - else - allowed = get_allowed_snack_by_id(O) - if(isnull(allowed)) - break + //Snacks and Plants + for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break - for(var/r_id in allowed) + var/allowed = get_allowed_snack_by_id(O) + if(isnull(allowed)) + break - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) //Negative amounts are multipliers for the reagent amount (Example: "amount = -5" means "reagent_amount * 5") - if(amount == 0) - if(O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - if(O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space)) - O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) - else - if(O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - if(O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space)) - O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) + for (var/r_id in allowed) - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + if(amount <= 0) + if(amount == 0) + if (O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + if (O.reagents != null && O.reagents.has_reagent("plantmatter")) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space)) + O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) + else + if (O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + if (O.reagents != null && O.reagents.has_reagent("plantmatter")) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space)) + O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - if(O.reagents.reagent_list.len == 0) - remove_object(O) + else + O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - //Sheets - for(var/obj/item/stack/sheet/O in holdingitems) - var/allowed = get_allowed_by_id(O) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - for(var/i = 1; i <= round(O.amount, 1); i++) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if(space < amount) - break - if(i == round(O.amount, 1)) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + if(O.reagents.reagent_list.len == 0) + remove_object(O) + + //Sheets + for (var/obj/item/stack/sheet/O in holdingitems) + var/allowed = get_allowed_by_id(O) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + for(var/i = 1; i <= round(O.amount, 1); i++) + for (var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + beaker.reagents.add_reagent(r_id,min(amount, space)) + if (space < amount) + break + if (i == round(O.amount, 1)) + remove_object(O) + break + //Plants + for (var/obj/item/weapon/grown/O in holdingitems) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/allowed = get_allowed_by_id(O) + for (var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + if (amount == 0) + if (O.reagents != null && O.reagents.has_reagent(r_id)) + beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) + else + beaker.reagents.add_reagent(r_id,min(amount, space)) + + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break remove_object(O) - break - //Plants - for(var/obj/item/weapon/grown/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount == 0) - if(O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) + //Slime Extractis + for (var/obj/item/slime_extract/O in holdingitems) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if (O.reagents != null) + var/amount = O.reagents.total_volume + O.reagents.trans_to(beaker, min(amount, space)) + if (O.Uses > 0) + beaker.reagents.add_reagent("slimejelly",min(20, space)) + remove_object(O) - //xenoarch - /*for(var/obj/item/weapon/rocksliver/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space), O.geological_data) - - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O)*/ - - //Everything else - Transfers reagents from it into beaker - for(var/obj/item/weapon/reagent_containers/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) \ No newline at end of file + //Everything else - Transfers reagents from it into beaker + for (var/obj/item/weapon/reagent_containers/O in holdingitems) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/amount = O.reagents.total_volume + O.reagents.trans_to(beaker, amount) + if(!O.reagents.total_volume) + remove_object(O) \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 367c747c4e0..db77f30e76b 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,7 +1,3 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - /datum/reagent var/name = "Reagent" var/id = "reagent" @@ -73,7 +69,7 @@ /datum/reagent/proc/on_mob_life(mob/living/M) current_cycle++ - holder.remove_reagent(id, metabolization_rate) //By default it slowly disappears. + holder.remove_reagent(id, metabolization_rate * M.metabolism_efficiency * M.digestion_ratio) //By default it slowly disappears. /datum/reagent/proc/on_mob_death(mob/living/M) //use this to have chems have a "death-triggered" effect return diff --git a/code/modules/reagents/chemistry/reagents/alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm index 536385d7614..b07e9da9124 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol.dm @@ -37,7 +37,7 @@ name = "Beer" id = "beer" description = "An alcoholic beverage made from malted grains, hops, yeast, and water." - nutriment_factor = 2 * REAGENTS_METABOLISM + nutriment_factor = 1 * REAGENTS_METABOLISM color = "#664300" // rgb: 102, 67, 0 alcohol_perc = 0.2 drink_icon ="beerglass" @@ -49,6 +49,7 @@ id = "cider" description = "An alcoholic beverage derived from apples." color = "#174116" + nutriment_factor = 1 * REAGENTS_METABOLISM alcohol_perc = 0.2 drink_icon = "rewriter" drink_name = "Cider" @@ -217,6 +218,7 @@ description = "A potent mixture of caffeine and alcohol." reagent_state = LIQUID color = "#102000" // rgb: 16, 32, 0 + nutriment_factor = 1 * REAGENTS_METABOLISM alcohol_perc = 0.3 heart_rate_increase = 1 drink_icon = "thirteen_loko_glass" @@ -240,6 +242,7 @@ description = "This appears to be beer mixed with milk. Disgusting." reagent_state = LIQUID color = "#895C4C" // rgb: 137, 92, 76 + nutriment_factor = 2 * REAGENTS_METABOLISM alcohol_perc = 0.2 drink_icon = "glass_brown" drink_name = "Glass of bilk" @@ -714,6 +717,7 @@ description = "A Vikings drink, though a cheap one." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 + nutriment_factor = 1 * REAGENTS_METABOLISM alcohol_perc = 0.2 drink_icon = "meadglass" drink_name = "Mead" @@ -979,6 +983,27 @@ drink_name = "Jack Rose" drink_desc = "Drinking this makes you feel like you belong in a luxury hotel bar during the 1920s." +/datum/reagent/consumable/ethanol/drunkenblumpkin + name = "Drunken Blumpkin" + id = "drunkenblumpkin" + description = "A weird mix of whiskey and blumpkin juice." + color = "#1EA0FF" // rgb: 102, 67, 0 + alcohol_perc = 0.5 + drink_icon = "drunkenblumpkin" + drink_name = "Drunken Blumpkin" + drink_desc = "A drink for the drunks" + +/datum/reagent/consumable/ethanol/eggnog + name = "Eggnog" + id = "eggnog" + description = "For enjoying the most wonderful time of the year." + color = "#fcfdc6" // rgb: 252, 253, 198 + nutriment_factor = 2 * REAGENTS_METABOLISM + alcohol_perc = 0.1 + drink_icon = "glass_yellow" + drink_name = "Eggnog" + drink_desc = "For enjoying the most wonderful time of the year." + /datum/reagent/consumable/ethanol/dragons_breath //inaccessible to players, but here for admin shennanigans name = "Dragon's Breath" id = "dragonsbreath" diff --git a/code/modules/reagents/chemistry/reagents/drinks.dm b/code/modules/reagents/chemistry/reagents/drinks.dm index 489eac3eb81..7db9387c3ff 100644 --- a/code/modules/reagents/chemistry/reagents/drinks.dm +++ b/code/modules/reagents/chemistry/reagents/drinks.dm @@ -111,6 +111,12 @@ M.adjustToxLoss(1) ..() +/datum/reagent/consumable/applejuice + name = "Apple Juice" + id = "applejuice" + description = "The sweet juice of an apple, fit for all ages." + color = "#ECFF56" // rgb: 236, 255, 86 + /datum/reagent/consumable/drink/watermelonjuice name = "Watermelon Juice" id = "watermelonjuice" @@ -213,7 +219,7 @@ name = "Hot Chocolate" id = "hot_coco" description = "Made with love! And coco beans." - nutriment_factor = 2 * REAGENTS_METABOLISM + nutriment_factor = 3 * REAGENTS_METABOLISM color = "#403010" // rgb: 64, 48, 16 adj_temp_hot = 5 drink_icon = "hot_coco" @@ -225,6 +231,7 @@ id = "coffee" description = "Coffee is a brewed drink prepared from roasted seeds, commonly called coffee beans, of the coffee plant." color = "#482000" // rgb: 72, 32, 0 + nutriment_factor = 0 adj_dizzy = -5 adj_drowsy = -3 adj_sleepy = -2 @@ -307,6 +314,7 @@ id = "tea" description = "Tasty black tea: It has antioxidants. It's good for you!" color = "#101000" // rgb: 16, 16, 0 + nutriment_factor = 0 adj_dizzy = -2 adj_drowsy = -1 adj_sleepy = -3 @@ -359,4 +367,82 @@ if(ishuman(M) && M.job in list("Mime")) M.adjustBruteLoss(-1) M.adjustFireLoss(-1) - ..() \ No newline at end of file + ..() + +/datum/reagent/consumable/drink/chocolatepudding + name = "Chocolate Pudding" + id = "chocolatepudding" + description = "A great dessert for chocolate lovers." + color = "#800000" + nutriment_factor = 4 * REAGENTS_METABOLISM + drink_icon = "chocolatepudding" + drink_name = "Chocolate Pudding" + drink_desc = "Tasty" + +/datum/reagent/consumable/drink/vanillapudding + name = "Vanilla Pudding" + id = "vanillapudding" + description = "A great dessert for vanilla lovers." + color = "#FAFAD2" + nutriment_factor = 4 * REAGENTS_METABOLISM + drink_icon = "vanillapudding" + drink_name = "Vanilla Pudding" + drink_desc = "Tasty." + +/datum/reagent/consumable/drink/cherryshake + name = "Cherry Shake" + id = "cherryshake" + description = "A cherry flavored milkshake." + color = "#FFB6C1" + nutriment_factor = 4 * REAGENTS_METABOLISM + drink_icon = "cherryshake" + drink_name = "Cherry Shake" + drink_desc = "A cherry flavored milkshake." + +/datum/reagent/consumable/drink/bluecherryshake + name = "Blue Cherry Shake" + id = "bluecherryshake" + description = "An exotic milkshake." + color = "#00F1FF" + nutriment_factor = 4 * REAGENTS_METABOLISM + drink_icon = "bluecherryshake" + drink_name = "Blue Cherry Shake" + drink_desc = "An exotic blue milkshake." + +/datum/reagent/consumable/drink/pumpkin_latte + name = "Pumpkin Latte" + id = "pumpkin_latte" + description = "A mix of pumpkin juice and coffee." + color = "#F4A460" + nutriment_factor = 3 * REAGENTS_METABOLISM + drink_icon = "pumpkin_latte" + drink_name = "Pumpkin Latte" + drink_desc = "A mix of coffee and pumpkin juice." + +/datum/reagent/consumable/drink/gibbfloats + name = "Gibb Floats" + id = "gibbfloats" + description = "Ice cream on top of a Dr. Gibb glass." + color = "#B22222" + nutriment_factor = 3 * REAGENTS_METABOLISM + drink_icon= "gibbfloats" + drink_name = "Gibbfloat" + drink_desc = "Dr. Gibb with ice cream on top." + +/datum/reagent/consumable/drink/pumpkinjuice + name = "Pumpkin Juice" + id = "pumpkinjuice" + description = "Juiced from real pumpkin." + color = "#FFA500" + +/datum/reagent/consumable/drink/blumpkinjuice + name = "Blumpkin Juice" + id = "blumpkinjuice" + description = "Juiced from real blumpkin." + color = "#00BFFF" + +/datum/reagent/consumable/drink/grape_soda + name = "Grape soda" + id = "grapesoda" + description = "Beloved of children and teetotalers." + color = "#E6CDFF" \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index e2aef002060..e3b16330986 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -21,7 +21,7 @@ id = "nutriment" description = "A questionable mixture of various pure nutrients commonly found in processed foods." reagent_state = SOLID - nutriment_factor = 12 * REAGENTS_METABOLISM + nutriment_factor = 15 * REAGENTS_METABOLISM color = "#664330" // rgb: 102, 67, 48 /datum/reagent/consumable/nutriment/on_mob_life(mob/living/M) @@ -42,14 +42,12 @@ name = "Protein" id = "protein" description = "Various essential proteins and fats commonly found in animal flesh and blood." - nutriment_factor = 15 * REAGENTS_METABOLISM diet_flags = DIET_CARN | DIET_OMNI /datum/reagent/consumable/nutriment/plantmatter // Plant-based biomatter, digestable by herbivores and omnivores, worthless to carnivores name = "Plant-matter" id = "plantmatter" description = "Vitamin-rich fibers and natural sugars commonly found in fresh produce." - nutriment_factor = 15 * REAGENTS_METABOLISM diet_flags = DIET_HERB | DIET_OMNI /datum/reagent/consumable/vitamin @@ -63,6 +61,8 @@ if(prob(50)) M.adjustBruteLoss(-1) M.adjustFireLoss(-1) + if(M.satiety < 600) + M.satiety += 30 if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.species.exotic_blood) @@ -72,6 +72,38 @@ H.vessel.add_reagent("blood", 0.5) ..() +/datum/reagent/consumable/sugar + name = "Sugar" + id = "sugar" + description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste." + reagent_state = SOLID + color = "#FFFFFF" // rgb: 255, 255, 255 + nutriment_factor = 5 * REAGENTS_METABOLISM + overdose_threshold = 200 // Hyperglycaemic shock + +/datum/reagent/consumable/sugar/on_mob_life(mob/living/M) + M.AdjustDrowsy(-5) + if(current_cycle >= 90) + M.AdjustJitter(2) + if(prob(50)) + M.AdjustParalysis(-1) + M.AdjustStunned(-1) + M.AdjustWeakened(-1) + if(prob(4)) + M.reagents.add_reagent("epinephrine", 1.2) + ..() + +/datum/reagent/consumable/sugar/overdose_start(mob/living/M) + to_chat(M, "You pass out from hyperglycemic shock!") + M.emote("collapse") + ..() + +/datum/reagent/consumable/sugar/overdose_process(mob/living/M, severity) + M.Paralyse(3 * severity) + M.Weaken(4 * severity) + if(prob(8)) + M.adjustToxLoss(severity) + /datum/reagent/consumable/soysauce name = "Soysauce" id = "soysauce" @@ -250,6 +282,14 @@ nutriment_factor = 5 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 +/datum/reagent/consumable/vanilla + name = "Vanilla Powder" + id = "vanilla" + description = "A fatty, bitter paste made from vanilla pods." + reagent_state = SOLID + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#FFFACD" + /datum/reagent/consumable/hot_coco name = "Hot Chocolate" id = "hot_coco" @@ -351,6 +391,7 @@ id = "rice" description = "Enjoy the great taste of nothing." reagent_state = SOLID + nutriment_factor = 3 * REAGENTS_METABOLISM color = "#FFFFFF" // rgb: 0, 0, 0 /datum/reagent/consumable/cherryjelly @@ -360,6 +401,13 @@ reagent_state = LIQUID color = "#801E28" // rgb: 128, 30, 40 +/datum/reagent/consumable/bluecherryjelly + name = "Blue Cherry Jelly" + id = "bluecherryjelly" + description = "Blue and tastier kind of cherry jelly." + reagent_state = LIQUID + color = "#00F0FF" + /datum/reagent/consumable/egg name = "Egg" id = "egg" @@ -409,9 +457,10 @@ description = "A sweet substance produced by bees through partial digestion. Bee barf." reagent_state = LIQUID color = "#d3a308" + nutriment_factor = 15 * REAGENTS_METABOLISM /datum/reagent/consumable/honey/on_mob_life(mob/living/M) - M.reagents.add_reagent("sugar", 0.4) + M.reagents.add_reagent("sugar", 3) if(prob(20)) M.adjustBruteLoss(-3) M.adjustFireLoss(-1) @@ -483,8 +532,6 @@ description = "Some cheese. Pour it out to make it solid." reagent_state = SOLID color = "#FFFF00" - metabolization_rate = 0 //heheheh - nutriment_factor = 0 /datum/reagent/consumable/cheese/on_mob_life(mob/living/M) if(prob(3)) @@ -514,9 +561,7 @@ description = "Hell, I don't even know if this IS cheese. Whatever it is, it ain't normal. If you want to, pour it out to make it solid." reagent_state = SOLID color = "#50FF00" - metabolization_rate = 0 //heheheh addiction_chance = 5 - nutriment_factor = 0 /datum/reagent/consumable/weird_cheese/on_mob_life(mob/living/M) if(prob(5)) @@ -671,37 +716,6 @@ ///Food Related, but non-nutritious -/datum/reagent/sugar - name = "Sugar" - id = "sugar" - description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste." - reagent_state = SOLID - color = "#FFFFFF" // rgb: 255, 255, 255 - overdose_threshold = 200 // Hyperglycaemic shock - -/datum/reagent/sugar/on_mob_life(mob/living/M) - M.AdjustDrowsy(-5) - if(current_cycle >= 90) - M.AdjustJitter(2) - if(prob(50)) - M.AdjustParalysis(-1) - M.AdjustStunned(-1) - M.AdjustWeakened(-1) - if(prob(4)) - M.reagents.add_reagent("epinephrine", 1.2) - ..() - -/datum/reagent/sugar/overdose_start(mob/living/M) - to_chat(M, "You pass out from hyperglycemic shock!") - M.emote("collapse") - ..() - -/datum/reagent/sugar/overdose_process(mob/living/M, severity) - M.Paralyse(3 * severity) - M.Weaken(4 * severity) - if(prob(8)) - M.adjustToxLoss(severity) - /datum/reagent/questionmark // food poisoning name = "????" id = "????" @@ -832,4 +846,52 @@ /datum/reagent/greenvomit/reaction_turf(turf/T, volume) if(volume >= 5 && !istype(T, /turf/space)) new /obj/effect/decal/cleanable/vomit/green(T) - playsound(T, 'sound/effects/splat.ogg', 50, 1, -3) \ No newline at end of file + playsound(T, 'sound/effects/splat.ogg', 50, 1, -3) + +////Lavaland Flora Reagents//// + +/datum/reagent/consumable/entpoly + name = "Entropic Polypnium" + id = "entpoly" + description = "An ichor, derived from a certain mushroom, makes for a bad time." + color = "#1d043d" + +/datum/reagent/consumable/entpoly/on_mob_life(mob/living/M) + if(current_cycle >= 10) + M.Paralyse(2) + if(prob(20)) + M.LoseBreath(4) + M.adjustBrainLoss(2 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(3 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustStaminaLoss(10 * REAGENTS_EFFECT_MULTIPLIER) + M.EyeBlurry(5) + ..() + +/datum/reagent/consumable/tinlux + name = "Tinea Luxor" + id = "tinlux" + description = "A stimulating ichor which causes luminescent fungi to grow on the skin. " + color = "#b5a213" + var/light_activated = 0 + +/datum/reagent/consumable/tinlux/on_mob_life(mob/living/M) + if(!light_activated) + M.set_light(2) + light_activated = 1 + ..() + +/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M) + M.set_light(0) + +/datum/reagent/consumable/vitfro + name = "Vitrium Froth" + id = "vitfro" + description = "A bubbly paste that heals wounds of the skin." + color = "#d3a308" + nutriment_factor = 3 * REAGENTS_METABOLISM + +/datum/reagent/consumable/vitfro/on_mob_life(mob/living/M) + if(prob(80)) + M.adjustBruteLoss(-1 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustFireLoss(-1 * REAGENTS_EFFECT_MULTIPLIER) + ..() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index b3b94ff7e88..451452936fe 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -2,6 +2,10 @@ name = "Medicine" id = "medicine" +/datum/reagent/medicine/on_mob_life(mob/living/M) + current_cycle++ + holder.remove_reagent(id, (metabolization_rate / M.metabolism_efficiency) * M.digestion_ratio) //medicine reagents stay longer if you have a better metabolism + /datum/reagent/medicine/hydrocodone name = "Hydrocodone" id = "hydrocodone" @@ -87,8 +91,7 @@ var/mob/living/carbon/human/H = M //Mitocholide is hard enough to get, it's probably fair to make this all internal organs - for(var/name in H.internal_organs) - var/obj/item/organ/internal/I = H.get_int_organ(name) + for(var/obj/item/organ/internal/I in H.internal_organs) if(I.damage > 0) I.damage = max(I.damage-0.4, 0) ..() @@ -631,7 +634,8 @@ return var/mob/dead/observer/ghost = M.get_ghost() if(ghost) - to_chat(ghost, "Your are attempting to be revived with Strange Reagent. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") + to_chat(ghost, "You are attempting to be revived with Strange Reagent. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)") + window_flash(ghost.client) ghost << sound('sound/effects/genetics.ogg') M.visible_message("[M] doesn't appear to respond, perhaps try again later?") if(!M.suiciding && !ghost && !(NOCLONE in M.mutations)) @@ -874,38 +878,10 @@ ..() /datum/reagent/medicine/omnizine_diluted/overdose_process(mob/living/M, severity) - var/effect = ..() - if(severity == 1) //lesser - M.stuttering += 1 - if(effect <= 1) - M.visible_message("[M] suddenly cluches their gut!") - M.emote("scream") - M.Stun(4) - M.Weaken(4) - else if(effect <= 3) - M.visible_message("[M] completely spaces out for a moment.") - M.AdjustConfused(15) - else if(effect <= 5) - M.visible_message("[M] stumbles and staggers.") - M.Dizzy(5) - M.Weaken(3) - else if(effect <= 7) - M.visible_message("[M] shakes uncontrollably.") - M.Jitter(30) - else if(severity == 2) // greater - if(effect <= 2) - M.visible_message("[M] suddenly cluches their gut!") - M.emote("scream") - M.Stun(7) - M.Weaken(7) - else if(effect <= 5) - M.visible_message("[M] jerks bolt upright, then collapses!") - M.Paralyse(5) - M.Weaken(4) - else if(effect <= 8) - M.visible_message("[M] stumbles and staggers.") - M.Dizzy(5) - M.Weaken(3) + M.adjustToxLoss(1.5*REAGENTS_EFFECT_MULTIPLIER) + M.adjustOxyLoss(1.5*REAGENTS_EFFECT_MULTIPLIER) + M.adjustBruteLoss(1.5*REAGENTS_EFFECT_MULTIPLIER) + M.adjustFireLoss(1.5*REAGENTS_EFFECT_MULTIPLIER) //virus-specific symptom reagents @@ -970,4 +946,61 @@ /datum/reagent/medicine/liquid_solder/on_mob_life(mob/living/M) M.adjustBrainLoss(-3) - ..() \ No newline at end of file + ..() + + + +//Trek-Chems. DO NOT USE THES OUTSIDE OF BOTANY OR FOR VERY SPECIFIC PURPOSES. NEVER GIVE A RECIPE UNDER ANY CIRCUMSTANCES// +/datum/reagent/medicine/bicaridine + name = "Bicaridine" + id = "bicaridine" + description = "Restores bruising. Overdose causes it instead." + reagent_state = LIQUID + color = "#C8A5DC" + overdose_threshold = 30 + +/datum/reagent/medicine/bicaridine/on_mob_life(mob/living/M) + M.adjustBruteLoss(-2*REAGENTS_EFFECT_MULTIPLIER) + ..() + +/datum/reagent/medicine/bicaridine/overdose_process(mob/living/M) + M.adjustBruteLoss(4*REAGENTS_EFFECT_MULTIPLIER) + +/datum/reagent/medicine/kelotane + name = "Kelotane" + id = "kelotane" + description = "Restores fire damage. Overdose causes it instead." + reagent_state = LIQUID + color = "#C8A5DC" + overdose_threshold = 30 + +/datum/reagent/medicine/kelotane/on_mob_life(mob/living/M) + M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER) + ..() + +/datum/reagent/medicine/kelotane/overdose_process(mob/living/M) + M.adjustFireLoss(4*REAGENTS_EFFECT_MULTIPLIER) + + +/datum/reagent/medicine/earthsblood //Created by ambrosia gaia plants + name = "Earthsblood" + id = "earthsblood" + description = "Ichor from an extremely powerful plant. Great for restoring wounds, but it's a little heavy on the brain." + color = "#FFAF00" + overdose_threshold = 25 + +/datum/reagent/medicine/earthsblood/on_mob_life(mob/living/M) + M.adjustBruteLoss(-3 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustFireLoss(-3 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustOxyLoss(-15 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustToxLoss(-3 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustBrainLoss(2 * REAGENTS_EFFECT_MULTIPLIER) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! + M.adjustCloneLoss(-1 * REAGENTS_EFFECT_MULTIPLIER) + M.adjustStaminaLoss(-30 * REAGENTS_EFFECT_MULTIPLIER) + M.SetJitter(min(max(0, M.jitteriness + 3), 30)) + M.SetDruggy(min(max(0, M.druggy + 10), 15)) //See above + ..() + +/datum/reagent/medicine/earthsblood/overdose_process(mob/living/M) + M.SetHallucinate(min(max(0, M.hallucination + 10), 50)) + M.adjustToxLoss(5 * REAGENTS_EFFECT_MULTIPLIER) \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index bb386d0215c..f755f61219f 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -176,15 +176,6 @@ reagent_state = LIQUID color = "#322D00" -// Allows you to make planks from any plant that has this reagent in it. -// Also vines with this reagent are considered dense. -/datum/reagent/woodpulp - name = "Wood Pulp" - id = "woodpulp" - description = "A mass of wood fibers." - reagent_state = LIQUID - color = "#B97A57" - /datum/reagent/oil name = "Oil" id = "oil" @@ -415,6 +406,37 @@ M.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz...")) ..() +/datum/reagent/growthserum + name = "Growth serum" + id = "growthserum" + description = "A commercial chemical designed to help older men in the bedroom." //not really it just makes you a giant + color = "#ff0000"//strong red. rgb 255, 0, 0 + var/current_size = 1 + +/datum/reagent/growthserum/on_mob_life(mob/living/carbon/H) + var/newsize = current_size + switch(volume) + if(0 to 19) + newsize = 1.25 + if(20 to 49) + newsize = 1.5 + if(50 to 99) + newsize = 2 + if(100 to 199) + newsize = 2.5 + if(200 to INFINITY) + newsize = 3.5 + + H.resize = newsize/current_size + current_size = newsize + H.update_transform() + ..() + +/datum/reagent/growthserum/on_mob_delete(mob/living/M) + M.resize = 1/current_size + M.update_transform() + ..() + /datum/reagent/toxin/coffeepowder name = "Coffee Grounds" id = "coffeepowder" @@ -429,25 +451,40 @@ reagent_state = SOLID color = "#7F8400" // rgb: 127, 132, 0 -//Reagents used for plant fertilizers. -/datum/reagent/toxin/fertilizer - name = "fertilizer" - id = "fertilizer" - description = "A chemical mix good for growing plants with." - reagent_state = LIQUID - color = "#664330" // rgb: 102, 67, 48 +//////////////////////////////////Hydroponics stuff/////////////////////////////// -/datum/reagent/toxin/fertilizer/eznutrient - name = "EZ Nutrient" - id = "eznutrient" +/datum/reagent/plantnutriment + name = "Generic nutriment" + id = "plantnutriment" + description = "Some kind of nutriment. You can't really tell what it is. You should probably report it, along with how you obtained it." + color = "#000000" // RBG: 0, 0, 0 + var/tox_prob = 0 -/datum/reagent/toxin/fertilizer/left4zed - name = "Left-4-Zed" - id = "left4zed" +/datum/reagent/plantnutriment/on_mob_life(mob/living/M) + if(prob(tox_prob)) + M.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) + ..() -/datum/reagent/toxin/fertilizer/robustharvest +/datum/reagent/plantnutriment/eznutriment + name = "E-Z-Nutrient" + id = "eznutriment" + description = "Cheap and extremely common type of plant nutriment." + color = "#376400" // RBG: 50, 100, 0 + tox_prob = 10 + +/datum/reagent/plantnutriment/left4zednutriment + name = "Left 4 Zed" + id = "left4zednutriment" + description = "Unstable nutriment that makes plants mutate more often than usual." + color = "#1A1E4D" // RBG: 26, 30, 77 + tox_prob = 25 + +/datum/reagent/plantnutriment/robustharvestnutriment name = "Robust Harvest" - id = "robustharvest" + id = "robustharvestnutriment" + description = "Very potent nutriment that prevents plants from mutating." + color = "#9D9D00" // RBG: 157, 157, 0 + tox_prob = 15 ///Alchemical Reagents diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 411e6a7bae5..73109f0f7e5 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -271,7 +271,7 @@ /datum/reagent/sacid/reaction_obj(obj/O, volume) if((istype(O,/obj/item) || istype(O,/obj/effect/glowshroom)) && prob(40)) if(!O.unacidable) - var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) + var/obj/effect/decal/cleanable/molten_object/I = new/obj/effect/decal/cleanable/molten_object(O.loc) I.desc = "Looks like this was \an [O] some time ago." O.visible_message("[O] melts.") qdel(O) @@ -617,7 +617,7 @@ /datum/reagent/facid/reaction_obj(obj/O, volume) if((istype(O, /obj/item) || istype(O, /obj/effect/glowshroom))) if(!O.unacidable) - var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) + var/obj/effect/decal/cleanable/molten_object/I = new/obj/effect/decal/cleanable/molten_object(O.loc) I.desc = "Looks like this was \an [O] some time ago." O.visible_message("[O] melts.") qdel(O) @@ -900,41 +900,41 @@ M.adjustFireLoss(1) ..() -/datum/reagent/atrazine - name = "Atrazine" - id = "atrazine" - description = "A herbicidal compound used for destroying unwanted plants." +/datum/reagent/glyphosate + name = "Glyphosate" + id = "glyphosate" + description = "A broad-spectrum herbicide that is highly effective at killing all plants." reagent_state = LIQUID - color = "#17002D" + color = "#d3cf50" + var/lethality = 0 //Glyphosate is non-toxic to people -/datum/reagent/atrazine/on_mob_life(mob/living/M) - M.adjustToxLoss(2) +/datum/reagent/glyphosate/on_mob_life(mob/living/M) + M.adjustToxLoss(lethality) ..() -/datum/reagent/atrazine/reaction_turf(turf/simulated/wall/W, volume) // Clear off wallrot fungi +/datum/reagent/glyphosate/reaction_turf(turf/simulated/wall/W, volume) // Clear off wallrot fungi if(istype(W) && W.rotting) for(var/obj/effect/overlay/wall_rot/WR in W) qdel(WR) W.rotting = 0 W.visible_message("The fungi are completely dissolved by the solution!") -/datum/reagent/atrazine/reaction_obj(obj/O, volume) +/datum/reagent/glyphosate/reaction_obj(obj/O, volume) if(istype(O,/obj/structure/alien/weeds/)) var/obj/structure/alien/weeds/alien_weeds = O alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast alien_weeds.healthcheck() else if(istype(O, /obj/effect/glowshroom)) //even a small amount is enough to kill it qdel(O) - else if(istype(O,/obj/effect/plant)) - if(prob(50)) - qdel(O) //Kills kudzu too. - // Damage that is done to growing plants is separately at code/game/machinery/hydroponics at obj/item/hydroponics + else if(istype(O,/obj/effect/spacevine)) + var/obj/effect/spacevine/SV = O + SV.on_chem_effect(src) -/datum/reagent/atrazine/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/glyphosate/reaction_mob(mob/living/M, method=TOUCH, volume) if(iscarbon(M)) var/mob/living/carbon/C = M if(!C.wear_mask) // If not wearing a mask - C.adjustToxLoss(2) // 2 toxic damage per application + C.adjustToxLoss(lethality) if(ishuman(M)) var/mob/living/carbon/human/H = M if(H.species.flags & IS_PLANT) //plantmen take a LOT of damage @@ -945,6 +945,35 @@ D.adjustHealth(100) ..() +/datum/reagent/glyphosate/atrazine + name = "Atrazine" + id = "atrazine" + description = "A herbicidal compound used for destroying unwanted plants." + reagent_state = LIQUID + color = "#17002D" + lethality = 2 //Atrazine, however, is definitely toxic + + +/datum/reagent/pestkiller // To-Do; make this more realistic. + name = "Pest Killer" + id = "pestkiller" + description = "A harmful toxic mixture to kill pests. Do not ingest!" + color = "#4B004B" // rgb: 75, 0, 75 + +/datum/reagent/pestkiller/on_mob_life(mob/living/M) + M.adjustToxLoss(1) + ..() + +/datum/reagent/pestkiller/reaction_mob(mob/living/M, method=TOUCH, volume) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.wear_mask) // If not wearing a mask + C.adjustToxLoss(2) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.get_species() == "Kidan") //RIP + H.adjustToxLoss(20) + /datum/reagent/capulettium name = "Capulettium" id = "capulettium" diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index f5e409a1cb4..286af5d4863 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -131,7 +131,7 @@ /datum/reagent/blood - data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"blood_colour"="#A10808","resistances"=null,"trace_chem"=null, "antibodies" = null) + data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"blood_colour"="#A10808","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Blood" id = "blood" reagent_state = LIQUID @@ -158,6 +158,7 @@ /datum/reagent/blood/on_merge(list/mix_data) if(data && mix_data) + data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning, or else we won't know who's even getting cloned, etc if(data["viruses"] || mix_data["viruses"]) var/list/mix1 = data["viruses"] @@ -348,25 +349,24 @@ metabolization_rate = 1 /datum/reagent/fuel/unholywater/on_mob_life(mob/living/M) - M.adjustBrainLoss(3) if(iscultist(M)) - M.status_flags |= GOTTAGOFAST M.AdjustDrowsy(-5) - M.AdjustParalysis(-2) + M.AdjustParalysis(-1) M.AdjustStunned(-2) M.AdjustWeakened(-2) + M.adjustToxLoss(-2) + M.adjustFireLoss(-2) + M.adjustOxyLoss(-2) + M.adjustBruteLoss(-2) else - M.adjustToxLoss(2) + M.adjustBrainLoss(3) + M.adjustToxLoss(1) M.adjustFireLoss(2) M.adjustOxyLoss(2) M.adjustBruteLoss(2) M.AdjustCultSlur(10)//CUASE WHY THE HELL NOT ..() -/datum/reagent/fuel/unholywater/on_mob_delete(mob/living/M) - M.status_flags &= ~GOTTAGOFAST - ..() - /datum/reagent/hellwater name = "Hell Water" id = "hell_water" diff --git a/code/modules/reagents/chemistry/recipes/drinks.dm b/code/modules/reagents/chemistry/recipes/drinks.dm index d1866a2b2f1..b8d31e55e1c 100644 --- a/code/modules/reagents/chemistry/recipes/drinks.dm +++ b/code/modules/reagents/chemistry/recipes/drinks.dm @@ -768,4 +768,77 @@ required_reagents = list("lemonjuice" = 1, "limejuice" = 1, "orangejuice" = 1) result_amount = 3 mix_message = "The citrus juices begin to blend together." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/chocolatepudding + name = "Chocolate Pudding" + id = "chocolatepudding" + result = "chocolatepudding" + required_reagents = list("cocoa" = 5, "milk" = 5, "egg" = 5) + result_amount = 20 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/vanillapudding + name = "Vanilla Pudding" + id = "vanillapudding" + result = "vanillapudding" + required_reagents = list("vanilla" = 5, "milk" = 5, "egg" = 5) + result_amount = 20 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/cherryshake + name = "Cherry Shake" + id = "cherryshake" + result = "cherryshake" + required_reagents = list("cherryjelly" = 1, "ice" = 1, "cream" = 1) + result_amount = 3 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/bluecherryshake + name = "Blue Cherry Shake" + id = "bluecherryshake" + result = "bluecherryshake" + required_reagents = list("bluecherryjelly" = 1, "ice" = 1, "cream" = 1) + result_amount = 3 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/drunkenblumpkin + name = "Drunken Blumpkin" + id = "drunkenblumpkin" + result = "drunkenblumpkin" + required_reagents = list("blumpkinjuice" = 1, "irishcream" = 2, "ice" = 1) + result_amount = 4 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/pumpkin_latte + name = "Pumpkin space latte" + id = "pumpkin_latte" + result = "pumpkin_latte" + required_reagents = list("pumpkinjuice" = 5, "coffee" = 5, "cream" = 5) + result_amount = 15 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/gibbfloats + name = "Gibb Floats" + id = "gibbfloats" + result = "gibbfloats" + required_reagents = list("dr_gibb" = 5, "ice" = 5, "cream" = 5) + result_amount = 15 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/grape_soda + name = "grape soda" + id = "grapesoda" + result = "grapesoda" + required_reagents = list("grapejuice" = 1, "sodawater" = 1) + result_amount = 2 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/eggnog + name = "eggnog" + id = "eggnog" + result = "eggnog" + required_reagents = list("rum" = 5, "cream" = 5, "egg" = 5) + result_amount = 15 + mix_message = "The eggs nog together. Pretend that \"nog\" is a verb." mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index 9a48e07e6a5..133ab0e6378 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -67,12 +67,24 @@ /datum/chemical_reaction/slimemetal/on_reaction(datum/reagents/holder) feedback_add_details("slime_cores_used","[type]") - var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal - M.amount = 15 - M.forceMove(get_turf(holder.my_atom)) - var/obj/item/stack/sheet/plasteel/P = new /obj/item/stack/sheet/plasteel - P.amount = 5 - P.forceMove(get_turf(holder.my_atom)) + var/turf/location = get_turf(holder.my_atom) + new /obj/item/stack/sheet/plasteel (location, 5) + new /obj/item/stack/sheet/metal (location, 15) + +/datum/chemical_reaction/slimeglass + name = "Slime Glass" + id = "m_glass" + result = null + required_reagents = list("water" = 1) + result_amount = 1 + required_container = /obj/item/slime_extract/metal + required_other = 1 + +/datum/chemical_reaction/slimeglass/on_reaction(datum/reagents/holder) + feedback_add_details("slime_cores_used","[type]") + var/turf/location = get_turf(holder.my_atom) + new /obj/item/stack/sheet/rglass (location, 5) + new /obj/item/stack/sheet/glass (location, 15) //Gold /datum/chemical_reaction/slimecrit @@ -209,8 +221,7 @@ required_other = 1 /datum/chemical_reaction/slimefrost/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[type]") - + feedback_add_details("slime_cores_used","[type]") /datum/chemical_reaction/slimestabilizer name = "Slime Stabilizer" @@ -226,8 +237,6 @@ var/obj/item/slimepotion/stabilizer/P = new /obj/item/slimepotion/stabilizer P.forceMove(get_turf(holder.my_atom)) - - //Dark Blue /datum/chemical_reaction/slimefreeze name = "Slime Freeze" @@ -383,12 +392,10 @@ /datum/chemical_reaction/slimeplasma/on_reaction(datum/reagents/holder) feedback_add_details("slime_cores_used","[type]") - var/obj/item/stack/sheet/mineral/plasma/P = new /obj/item/stack/sheet/mineral/plasma - P.amount = 3 - P.forceMove(get_turf(holder.my_atom)) + var/turf/location = get_turf(holder.my_atom) + new /obj/item/stack/sheet/mineral/plasma (location, 3) //Red - /datum/chemical_reaction/slimemutator name = "Slime Mutator" id = "m_slimemutator" @@ -661,4 +668,18 @@ var/mob/living/carbon/slime/S = new /mob/living/carbon/slime S.colour = pick("grey","orange", "metal", "blue", "purple", "dark purple", "dark blue", "green", "silver", "yellow", "gold", "yellow", "red", "silver", "pink", "cerulean", "sepia", "bluespace", "pyrite", "light pink", "oil", "adamantine", "black") S.forceMove(get_turf(holder.my_atom)) - S.visible_message("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!") \ No newline at end of file + S.visible_message("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!") + +/datum/chemical_reaction/slime_transfer + name = "Transfer Potion" + id = "slimetransfer" + result = null + required_reagents = list("blood" = 1) + result_amount = 1 + required_other = 1 + required_container = /obj/item/slime_extract/rainbow + +/datum/chemical_reaction/slime_transfer/on_reaction(datum/reagents/holder) + feedback_add_details("slime_cores_used","[type]") + var/obj/item/slimepotion/transference/P = new /obj/item/slimepotion/transference + P.forceMove(get_turf(holder.my_atom)) diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm index 2181401b2da..082e209e18b 100644 --- a/code/modules/reagents/chemistry/recipes/toxins.dm +++ b/code/modules/reagents/chemistry/recipes/toxins.dm @@ -93,6 +93,13 @@ if(C.can_breathe_gas()) C.reagents.add_reagent("sarin", 4) +/datum/chemical_reaction/glyphosate + name = "glyphosate" + id = "glyphosate" + result = "glyphosate" + required_reagents = list("chlorine" = 1, "phosphorus" = 1, "formaldehyde" = 1, "ammonia" = 1) + result_amount = 4 + /datum/chemical_reaction/atrazine name = "atrazine" id = "atrazine" @@ -101,6 +108,14 @@ result_amount = 3 mix_message = "The mixture gives off a harsh odor" +/datum/chemical_reaction/pestkiller // To-Do make this more realistic + name = "Pest Killer" + id = "pestkiller" + result = "pestkiller" + required_reagents = list("toxin" = 1, "ethanol" = 4) + result_amount = 5 + mix_message = "The mixture gives off a harsh odor" + /datum/chemical_reaction/capulettium name = "capulettium" id = "capulettium" diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index f46d4010e69..727574fed16 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -30,7 +30,6 @@ if(!possible_transfer_amounts) verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT create_reagents(volume) - processing_objects.Add(src) if(spawned_disease) var/datum/disease/F = new spawned_disease(0) var/list/data = list("viruses" = list(F), "blood_colour" = "#A10808") @@ -38,11 +37,6 @@ if(list_reagents) reagents.add_reagent_list(list_reagents) -/obj/item/weapon/reagent_containers/process() - if(reagents) - reagents.reagent_on_tick() - return - /obj/item/weapon/reagent_containers/ex_act() if(reagents) for(var/datum/reagent/R in reagents.reagent_list) diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index c69c7b4a0ef..70ba27e7dcc 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -84,8 +84,8 @@ if(M.reagents) var/datum/reagent/injected = chemical_reagents_list[reagent_ids[mode]] var/contained = injected.name - M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [key_name(user)]. Reagents: [contained]") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [key_name(M)]. Reagents: [contained]") + M.create_attack_log("Has been injected with [name] by [key_name(user)]. Reagents: [contained]") + user.create_attack_log("Used the [name] to inject [key_name(M)]. Reagents: [contained]") if(M.ckey) msg_admin_attack("[key_name_admin(user)] injected [key_name_admin(M)] with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)])") M.LAssailant = user diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index deeeb76b58d..b80adc356c7 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -69,8 +69,8 @@ for(var/datum/reagent/R in reagents.reagent_list) injected += R.name var/contained = english_list(injected) - M.attack_log += text("\[[time_stamp()]\] Has been squirted with [name] by [key_name(user)]. Reagents: [contained]") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to squirt [key_name(M)]. Reagents: [contained]") + M.create_attack_log("Has been squirted with [name] by [key_name(user)]. Reagents: [contained]") + user.create_attack_log("Used the [name] to squirt [key_name(M)]. Reagents: [contained]") if(M.ckey) msg_admin_attack("[key_name_admin(user)] squirted [key_name_admin(M)] with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)])") if(!iscarbon(user)) diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index 60c924e0515..b170f6b0867 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -38,8 +38,9 @@ /obj/machinery/sleeper, /obj/machinery/smartfridge/, /obj/machinery/biogenerator, - /obj/machinery/portable_atmospherics/hydroponics, - /obj/machinery/constructable_frame) + /obj/machinery/hydroponics, + /obj/machinery/constructable_frame, + /obj/machinery/icemachine) /obj/item/weapon/reagent_containers/glass/New() ..() @@ -62,7 +63,8 @@ update_icon() /obj/item/weapon/reagent_containers/glass/afterattack(obj/target, mob/user, proximity) - if(!proximity) return + if(!proximity) + return if(!is_open_container()) return @@ -78,8 +80,8 @@ for(var/datum/reagent/R in reagents.reagent_list) injected += R.name var/contained = english_list(injected) - M.attack_log += text("\[[time_stamp()]\] Has been splashed with [name] by [key_name(user)]. Reagents: [contained]") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to splash [key_name(M)]. Reagents: [contained]") + M.create_attack_log("Has been splashed with [name] by [key_name(user)]. Reagents: [contained]") + user.create_attack_log("Used the [name] to splash [key_name(M)]. Reagents: [contained]") if(M.ckey) msg_admin_attack("[key_name_admin(user)] splashed [key_name_admin(M)] with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)])") if(!iscarbon(user)) @@ -94,16 +96,16 @@ return else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - if(!target.reagents.total_volume && target.reagents) - to_chat(user, "[target] is empty.") + if(target.reagents && !target.reagents.total_volume) + to_chat(user, "[target] is empty and can't be refilled!") return if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "[src] is full.") + to_chat(user, "[src] is full.") return - var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] units of the contents of [target].") + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].") else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. if(!reagents.total_volume) @@ -290,7 +292,11 @@ materials = list(MAT_GLASS=500) volume = 50 amount_per_transfer_from_this = 10 - flags = OPENCONTAINER | NOREACT + flags = OPENCONTAINER + +/obj/item/weapon/reagent_containers/glass/beaker/noreact/New() + ..() + reagents.set_reacting(FALSE) /obj/item/weapon/reagent_containers/glass/beaker/bluespace name = "bluespace beaker" diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index a706d443d90..cc4bf75ea45 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -19,7 +19,7 @@ /obj/item/weapon/reagent_containers/spray/afterattack(atom/A, mob/user) if(istype(A, /obj/item/weapon/storage) || istype(A, /obj/structure/table) || istype(A, /obj/structure/rack) || istype(A, /obj/structure/closet) \ - || istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/portable_atmospherics/hydroponics)) + || istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) return if(istype(A, /obj/effect/proc_holder/spell)) @@ -34,7 +34,7 @@ to_chat(user, "[src] is full.") return - var/trans = A.reagents.trans_to(src, A:amount_per_transfer_from_this) + var/trans = A.reagents.trans_to(src, 50) //This is a static amount, otherwise, it'll take forever to fill. to_chat(user, "You fill [src] with [trans] units of the contents of [A].") return @@ -127,7 +127,7 @@ /obj/item/weapon/reagent_containers/spray/waterflower name = "water flower" desc = "A seemingly innocent sunflower...with a twist." - icon = 'icons/obj/harvest.dmi' + icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "sunflower" item_state = "sunflower" amount_per_transfer_from_this = 1 @@ -200,20 +200,8 @@ /obj/item/weapon/reagent_containers/spray/plantbgone // -- Skie name = "Plant-B-Gone" desc = "Kills those pesky weeds!" - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "plantbgone" item_state = "plantbgone" volume = 100 - list_reagents = list("atrazine" = 100) - - -/obj/item/weapon/reagent_containers/spray/plantbgone/afterattack(atom/A, mob/user, proximity) - if(!proximity) return - - if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) // We are targeting hydrotray - return - - if(istype(A, /obj/effect/blob)) // blob damage in blob code - return - - ..() \ No newline at end of file + list_reagents = list("glyphosate" = 100) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index bb84295a22d..6bd1ee79cbf 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -196,8 +196,8 @@ for(var/datum/reagent/R in reagents.reagent_list) injected += R.name var/contained = english_list(injected) - M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [key_name(user)]. Reagents: [contained]") - user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [key_name(M)]. Reagents: [contained]") + M.create_attack_log("Has been injected with [name] by [key_name(user)]. Reagents: [contained]") + user.create_attack_log("Used the [name] to inject [key_name(M)]. Reagents: [contained]") if(M.ckey) msg_admin_attack("[key_name_admin(user)] injected [key_name_admin(M)] with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)])") if(!iscarbon(user)) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 4c2d2caa6b8..f050f6708e7 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -1,5 +1,3 @@ -#define AUTOIGNITION_WELDERFUEL 561.15 - /obj/structure/reagent_dispensers name = "Dispenser" desc = "..." @@ -9,109 +7,97 @@ anchored = 0 pressure_resistance = 2*ONE_ATMOSPHERE - var/amount_per_transfer_from_this = 10 - var/possible_transfer_amounts = list(10,25,50,100) + var/tank_volume = 1000 //In units, how much the dispenser can hold + var/reagent_id = "water" //The ID of the reagent that the dispenser uses /obj/structure/reagent_dispensers/attackby(obj/item/weapon/W, mob/user, params) return /obj/structure/reagent_dispensers/New() - create_reagents(1000) - if(!possible_transfer_amounts) - verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT + create_reagents(tank_volume) + reagents.add_reagent(reagent_id, tank_volume) ..() /obj/structure/reagent_dispensers/examine(mob/user) if(!..(user, 2)) return - to_chat(user, "It contains:") - if(reagents && reagents.reagent_list.len) - for(var/datum/reagent/R in reagents.reagent_list) - to_chat(user, "[R.volume] units of [R.name]") + if(reagents.total_volume) + to_chat(user, "It has [reagents.total_volume] units left.") else - to_chat(user, "Nothing.") + to_chat(user, "It's empty.") -/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this - set name = "Set transfer amount" - set category = "Object" - set src in view(1) - if(usr.stat || !usr.canmove || usr.restrained()) - return - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts - if(N) - amount_per_transfer_from_this = N + +/obj/structure/reagent_dispensers/proc/boom() + visible_message("[src] ruptures!") + qdel(src) /obj/structure/reagent_dispensers/ex_act(severity) switch(severity) - if(1.0) - qdel(src) - return - if(2.0) + if(1) + boom() + if(2) if(prob(50)) - new /obj/effect/effect/water(loc) - qdel(src) - return - if(3.0) + boom() + if(3) if(prob(5)) - new /obj/effect/effect/water(loc) - qdel(src) - return - else - return + boom() /obj/structure/reagent_dispensers/blob_act() if(prob(50)) - new /obj/effect/effect/water(loc) - qdel(src) - - - - - + boom() //Dispensers /obj/structure/reagent_dispensers/watertank - name = "watertank" - desc = "A watertank" - icon = 'icons/obj/objects.dmi' - icon_state = "watertank" - amount_per_transfer_from_this = 10 + name = "water tank" + desc = "A water tank." + icon_state = "water" -/obj/structure/reagent_dispensers/watertank/New() +/obj/structure/reagent_dispensers/watertank/boom() + playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) + new /obj/effect/effect/water(loc) + for(var/turf/simulated/T in view(5, loc)) + T.MakeSlippery() + for(var/mob/living/L in T) + L.adjust_fire_stacks(-20) ..() - reagents.add_reagent("water",1000) + +/obj/structure/reagent_dispensers/watertank/high + name = "high-capacity water tank" + desc = "A highly-pressurized water tank made to hold gargantuan amounts of water.." + icon_state = "water_high" //I was gonna clean my room... + tank_volume = 100000 /obj/structure/reagent_dispensers/fueltank - name = "fueltank" - desc = "A fueltank" - icon = 'icons/obj/objects.dmi' - icon_state = "weldtank" - amount_per_transfer_from_this = 10 + name = "fuel tank" + desc = "A tank full of industrial welding fuel. Do not consume." + icon_state = "fuel" + reagent_id = "fuel" var/obj/item/device/assembly_holder/rig = null var/accepts_rig = 1 -/obj/structure/reagent_dispensers/fueltank/New() +/obj/structure/reagent_dispensers/fueltank/Destroy() + if(rig) + qdel(rig) + rig = null + return ..() + +/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P) ..() - reagents.add_reagent("fuel",1000) + if(!qdeleted(src)) //wasn't deleted by the projectile's effects. + if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE))) + message_admins("[key_name_admin(P.firer)] triggered a fueltank explosion.") + log_game("[key_name(P.firer)] triggered a fueltank explosion.") + boom() -/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/Proj) - ..() - if(istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))) - message_admins("[key_name_admin(Proj.firer)] triggered a fueltank explosion.") - log_game("[key_name(Proj.firer)] triggered a fueltank explosion.") - boom() +/obj/structure/reagent_dispensers/fueltank/boom() + explosion(loc, 0, 1, 5, 7, 10, flame_range = 5) + qdel(src) -/obj/structure/reagent_dispensers/fueltank/proc/boom() - explosion(loc,0,1,5,7,10, flame_range = 5) - if(src) - qdel(src) - -/obj/structure/reagent_dispensers/fueltank/blob_act(obj/effect/blob/B) +/obj/structure/reagent_dispensers/fueltank/blob_act() boom() - /obj/structure/reagent_dispensers/fueltank/ex_act() boom() @@ -133,34 +119,53 @@ usr.visible_message("[usr] begins to detach [rig] from [src].", "You begin to detach [rig] from [src].") if(do_after(usr, 20, target = src)) usr.visible_message("[usr] detaches [rig] from [src].", "You detach [rig] from [src].") - rig.loc = get_turf(usr) + rig.forceMove(get_turf(usr)) rig = null - overlays = new/list() + overlays.Cut() -/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W,/obj/item/device/assembly_holder) && accepts_rig) +/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/device/assembly_holder) && accepts_rig) if(rig) to_chat(user, "There is another device in the way.") return ..() - user.visible_message("[user] begins rigging [W] to [src].", "You begin rigging [W] to [src]") + user.visible_message("[user] begins rigging [I] to [src].", "You begin rigging [I] to [src]") if(do_after(user, 20, target = src)) - user.visible_message("[user] rigs [W] to [src].", "You rig [W] to [src].") + user.visible_message("[user] rigs [I] to [src].", "You rig [I] to [src].") - var/obj/item/device/assembly_holder/H = W - if(istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) + var/obj/item/device/assembly_holder/H = I + if(istype(H.a_left, /obj/item/device/assembly/igniter) || istype(H.a_right, /obj/item/device/assembly/igniter)) msg_admin_attack("[key_name_admin(user)] rigged a fueltank for explosion (JMP)") log_game("[key_name(user)] rigged fueltank a fueltank for explosion at [loc.x], [loc.y], [loc.z]") - rig = W + rig = H user.drop_item() - W.loc = src + H.forceMove(src) - var/icon/test = getFlatIcon(W) - test.Shift(NORTH,1) - test.Shift(EAST,6) + var/icon/test = getFlatIcon(H) + test.Shift(NORTH, 1) + test.Shift(EAST, 6) overlays += test - return ..() + if(istype(I, /obj/item/weapon/weldingtool)) + if(!reagents.has_reagent("fuel")) + to_chat(user, "[src] is out of fuel!") + return + var/obj/item/weapon/weldingtool/W = I + if(!W.welding) + if(W.reagents.has_reagent("fuel", W.max_fuel)) + to_chat(user, "Your [W] is already full!") + return + reagents.trans_to(W, W.max_fuel) + user.visible_message("[user] refills \his [W].", "You refill [W].") + playsound(src, 'sound/effects/refill.ogg', 50, 1) + W.update_icon() + else + user.visible_message("[user] catastrophically fails at refilling \his [W]!", "That was stupid of you.") + message_admins("[key_name_admin(user)] triggered a fueltank explosion.") + log_game("[key_name(user)] triggered a fueltank explosion.") + boom() + else + ..() /obj/structure/reagent_dispensers/fueltank/Move() ..() @@ -190,76 +195,65 @@ /obj/structure/reagent_dispensers/peppertank - name = "Pepper Spray Refiller" - desc = "Refill pepper spray canisters." - icon = 'icons/obj/objects.dmi' - icon_state = "peppertank" + name = "pepper spray refiller" + desc = "Contains condensed capsaicin for use in law \"enforcement.\"" + icon_state = "pepper" anchored = 1 density = 0 - amount_per_transfer_from_this = 45 - -/obj/structure/reagent_dispensers/peppertank/New() - ..() - reagents.add_reagent("condensedcapsaicin",1000) - + reagent_id = "condensedcapsaicin" /obj/structure/reagent_dispensers/water_cooler - name = "Water-Cooler" - desc = "A machine that dispenses water to drink" - amount_per_transfer_from_this = 5 + name = "liquid cooler" + desc = "A machine that dispenses liquid to drink." icon = 'icons/obj/vending.dmi' icon_state = "water_cooler" - possible_transfer_amounts = null anchored = 1 + tank_volume = 500 + var/paper_cups = 25 //Paper cups left from the cooler -/obj/structure/reagent_dispensers/water_cooler/New() - ..() - reagents.add_reagent("water",500) +/obj/structure/reagent_dispensers/water_cooler/examine(mob/user) + if(!..(user, 2)) + return + to_chat(user, "There are [paper_cups ? paper_cups : "no"] paper cups left.") +/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user) + if(!paper_cups) + to_chat(user, "There aren't any cups left!") + return + user.visible_message("[user] takes a cup from [src].", "You take a paper cup from [src].") + var/obj/item/weapon/reagent_containers/food/drinks/sillycup/S = new(get_turf(src)) + user.put_in_hands(S) + paper_cups-- /obj/structure/reagent_dispensers/beerkeg name = "beer keg" - desc = "A beer keg" - icon = 'icons/obj/objects.dmi' - icon_state = "beertankTEMP" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/beerkeg/New() - ..() - reagents.add_reagent("beer",1000) + desc = "Beer is liquid bread, it's good for you..." + icon_state = "beer" + reagent_id = "beer" /obj/structure/reagent_dispensers/beerkeg/blob_act() - explosion(loc,0,3,5,7,10) + explosion(loc, 0, 3, 5, 7, 10) qdel(src) /obj/structure/reagent_dispensers/virusfood - name = "Virus Food Dispenser" - desc = "A dispenser of virus food." - icon = 'icons/obj/objects.dmi' - icon_state = "virusfoodtank" - amount_per_transfer_from_this = 10 + name = "virus food dispenser" + desc = "A dispenser of low-potency virus mutagenic." + icon_state = "virus_food" anchored = 1 density = 0 - -/obj/structure/reagent_dispensers/virusfood/New() - ..() - reagents.add_reagent("virusfood", 1000) + reagent_id = "virusfood" /obj/structure/reagent_dispensers/spacecleanertank name = "space cleaner refiller" desc = "Refills space cleaner bottles." - icon = 'icons/obj/objects.dmi' - icon_state = "spacecleanertank" + icon_state = "cleaner" anchored = 1 density = 0 - amount_per_transfer_from_this = 250 - -/obj/structure/reagent_dispensers/spacecleanertank/New() - ..() - reagents.add_reagent("cleaner",5000) + tank_volume = 5000 + reagent_id = "cleaner" /obj/structure/reagent_dispensers/fueltank/chem - icon_state = "weldingtank_chem" + icon_state = "fuel_chem" anchored = 1 density = 0 accepts_rig = 0 \ No newline at end of file diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index 1e56d9d6d57..3d57f950995 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -50,6 +50,10 @@ dir = newdir update_move_direction() +/obj/machinery/conveyor/setDir(newdir) + . = ..() + update_move_direction() + /obj/machinery/conveyor/proc/update_move_direction() switch(dir) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 6691df19a1d..622fe780031 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -132,13 +132,14 @@ for(var/mob/C in viewers(src)) C.show_message("\red [GM.name] has been placed in the [src] by [user].", 3) qdel(G) - usr.attack_log += text("\[[time_stamp()]\] Has placed [key_name(GM)] in disposals.") - GM.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [key_name(user)]") + usr.create_attack_log("Has placed [key_name(GM)] in disposals.") + GM.create_attack_log("Has been placed in disposals by [key_name(user)]") if(GM.ckey) msg_admin_attack("[key_name_admin(user)] placed [key_name_admin(GM)] in a disposals unit. (JMP)") return - if(!I) return + if(!I) + return if(!user.drop_item()) return @@ -180,8 +181,8 @@ msg = "[user.name] stuffs [target.name] into the [src]!" to_chat(user, "You stuff [target.name] into the [src]!") - user.attack_log += text("\[[time_stamp()]\] Has placed [key_name(target)] in disposals.") - target.attack_log += text("\[[time_stamp()]\] Has been placed in disposals by [key_name(user)]") + user.create_attack_log("Has placed [key_name(target)] in disposals.") + target.create_attack_log("Has been placed in disposals by [key_name(user)]") if(target.ckey) msg_admin_attack("[key_name_admin(user)] placed [key_name_admin(target)] in a disposals unit") else @@ -530,14 +531,18 @@ has_fat_guy = 1 // set flag on holder if(istype(AM, /obj/structure/bigDelivery) && !hasmob) var/obj/structure/bigDelivery/T = AM - src.destinationTag = T.sortTag + destinationTag = T.sortTag if(istype(AM, /obj/item/smallDelivery) && !hasmob) var/obj/item/smallDelivery/T = AM - src.destinationTag = T.sortTag + destinationTag = T.sortTag //Drones can mail themselves through maint. if(istype(AM, /mob/living/silicon/robot/drone)) var/mob/living/silicon/robot/drone/drone = AM - src.destinationTag = drone.mail_destination + destinationTag = drone.mail_destination + if(istype(AM, /obj/item/shippingPackage) && !hasmob) + var/obj/item/shippingPackage/sp = AM + if(sp.sealed) //only sealed packages get delivered to their intended destination + destinationTag = sp.sortTag // start the movement process @@ -987,7 +992,7 @@ /obj/structure/disposalpipe/sortjunction icon_state = "pipe-j1s" - var/sortType = 0 //Look at the list called TAGGERLOCATIONS in setup.dm + var/sortType = 0 //Look at the list called TAGGERLOCATIONS in /code/_globalvars/lists/flavor_misc.dm var/posdir = 0 var/negdir = 0 var/sortdir = 0 diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 7f7b3bfbb45..a0e9d59a803 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -35,6 +35,16 @@ sortTag = O.currTag playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) + else if(istype(W, /obj/item/shippingPackage)) + var/obj/item/shippingPackage/sp = W + if(sp.sealed) + return + else + sortTag = sp.sortTag + to_chat(user, "You rip the label off the shipping package and affix it to [src].") + qdel(sp) + playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) + else if(istype(W, /obj/item/weapon/pen)) var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) if(!str || !length(str)) @@ -89,6 +99,16 @@ sortTag = O.currTag playsound(loc, 'sound/machines/twobeep.ogg', 100, 1) + else if(istype(W, /obj/item/shippingPackage)) + var/obj/item/shippingPackage/sp = W + if(sp.sealed) + return + else + sortTag = sp.sortTag + to_chat(user, "You rip the label off the shipping package and affix it to [src].") + qdel(sp) + playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) + else if(istype(W, /obj/item/weapon/pen)) var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN) if(!str || !length(str)) @@ -134,7 +154,7 @@ - if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box))) + if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box) && !istype(target, /obj/item/shippingPackage))) var/obj/item/O = target if(use(1)) var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up! @@ -182,7 +202,7 @@ return user.visible_message("[user] wraps [target].") - user.attack_log += text("\[[time_stamp()]\] Has used [name] on [target]") + user.create_attack_log("Has used [name] on [target]") if(amount <= 0 && !src.loc) //if we used our last wrapping paper, drop a cardboard tube new /obj/item/weapon/c_tube( get_turf(user) ) @@ -235,101 +255,181 @@ var/c_mode = 0 - New() - ..() - spawn(5) - trunk = locate() in src.loc - if(trunk) - trunk.linked = src // link the pipe trunk to self +/obj/machinery/disposal/deliveryChute/New() + ..() + spawn(5) + trunk = locate() in src.loc + if(trunk) + trunk.linked = src // link the pipe trunk to self - interact() - return +/obj/machinery/disposal/deliveryChute/interact() + return - update() - return +/obj/machinery/disposal/deliveryChute/update() + return - Bumped(var/atom/movable/AM) //Go straight into the chute - if(istype(AM, /obj/item/projectile)) return - switch(dir) - if(NORTH) - if(AM.loc.y != src.loc.y+1) return - if(EAST) - if(AM.loc.x != src.loc.x+1) return - if(SOUTH) - if(AM.loc.y != src.loc.y-1) return - if(WEST) - if(AM.loc.x != src.loc.x-1) return +/obj/machinery/disposal/deliveryChute/Bumped(atom/movable/AM) //Go straight into the chute + if(istype(AM, /obj/item/projectile)) return + switch(dir) + if(NORTH) + if(AM.loc.y != src.loc.y+1) return + if(EAST) + if(AM.loc.x != src.loc.x+1) return + if(SOUTH) + if(AM.loc.y != src.loc.y-1) return + if(WEST) + if(AM.loc.x != src.loc.x-1) return - if(istype(AM, /obj)) - var/obj/O = AM - O.loc = src - else if(istype(AM, /mob)) - var/mob/M = AM - M.loc = src - src.flush() + if(istype(AM, /obj)) + var/obj/O = AM + O.loc = src + else if(istype(AM, /mob)) + var/mob/M = AM + M.loc = src + src.flush() - flush() - flushing = 1 - flick("intake-closing", src) - var/deliveryCheck = 0 - var/obj/structure/disposalholder/H = new() // virtual holder object which actually +/obj/machinery/disposal/deliveryChute/flush() + flushing = 1 + flick("intake-closing", src) + var/deliveryCheck = 0 + var/obj/structure/disposalholder/H = new() // virtual holder object which actually // travels through the pipes. - for(var/obj/structure/bigDelivery/O in src) - deliveryCheck = 1 - if(O.sortTag == 0) - O.sortTag = 1 - for(var/obj/item/smallDelivery/O in src) - deliveryCheck = 1 - if(O.sortTag == 0) - O.sortTag = 1 - if(deliveryCheck == 0) - H.destinationTag = 1 + for(var/obj/structure/bigDelivery/O in src) + deliveryCheck = 1 + if(O.sortTag == 0) + O.sortTag = 1 + for(var/obj/item/smallDelivery/O in src) + deliveryCheck = 1 + if(O.sortTag == 0) + O.sortTag = 1 + for(var/obj/item/shippingPackage/O in src) + deliveryCheck = 1 + if(!O.sealed || O.sortTag == 0) //unsealed or untagged shipping packages will default to disposals + O.sortTag = 1 + if(deliveryCheck == 0) + H.destinationTag = 1 - sleep(10) - playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) - sleep(5) // wait for animation to finish + sleep(10) + playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0) + sleep(5) // wait for animation to finish - H.init(src) // copy the contents of disposer to holder - air_contents = new() // The holder just took our gas; replace it - H.start(src) // start the holder processing movement - flushing = 0 - // now reset disposal state - flush = 0 - if(mode == 2) // if was ready, - mode = 1 // switch to charging - update() + H.init(src) // copy the contents of disposer to holder + air_contents = new() // The holder just took our gas; replace it + H.start(src) // start the holder processing movement + flushing = 0 + // now reset disposal state + flush = 0 + if(mode == 2) // if was ready, + mode = 1 // switch to charging + update() + return + +/obj/machinery/disposal/deliveryChute/attackby(obj/item/I, mob/user, params) + if(!I || !user) return - attackby(var/obj/item/I, var/mob/user, params) - if(!I || !user) + if(istype(I, /obj/item/weapon/screwdriver)) + if(c_mode==0) + c_mode=1 + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + to_chat(user, "You remove the screws around the power connection.") + return + else if(c_mode==1) + c_mode=0 + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + to_chat(user, "You attach the screws around the power connection.") + return + else if(istype(I,/obj/item/weapon/weldingtool) && c_mode==1) + var/obj/item/weapon/weldingtool/W = I + if(W.remove_fuel(0,user)) + playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) + to_chat(user, "You start slicing the floorweld off the delivery chute.") + if(do_after(user,20, target = src)) + if(!src || !W.isOn()) return + to_chat(user, "You sliced the floorweld off the delivery chute.") + var/obj/structure/disposalconstruct/C = new (src.loc) + C.ptype = 8 // 8 = Delivery chute + C.update() + C.anchored = 1 + C.density = 1 + qdel(src) + return + else + to_chat(user, "You need more welding fuel to complete this task.") return - if(istype(I, /obj/item/weapon/screwdriver)) - if(c_mode==0) - c_mode=1 - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - to_chat(user, "You remove the screws around the power connection.") - return - else if(c_mode==1) - c_mode=0 - playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - to_chat(user, "You attach the screws around the power connection.") - return - else if(istype(I,/obj/item/weapon/weldingtool) && c_mode==1) - var/obj/item/weapon/weldingtool/W = I - if(W.remove_fuel(0,user)) - playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) - to_chat(user, "You start slicing the floorweld off the delivery chute.") - if(do_after(user,20, target = src)) - if(!src || !W.isOn()) return - to_chat(user, "You sliced the floorweld off the delivery chute.") - var/obj/structure/disposalconstruct/C = new (src.loc) - C.ptype = 8 // 8 = Delivery chute - C.update() - C.anchored = 1 - C.density = 1 - qdel(src) - return - else - to_chat(user, "You need more welding fuel to complete this task.") + +/obj/item/shippingPackage + name = "Shipping package" + desc = "A pre-labeled package for shipping an item to coworkers." + icon = 'icons/obj/storage.dmi' + icon_state = "shippack" + var/obj/item/wrapped = null + var/sortTag = 0 + var/sealed = 0 + +/obj/item/shippingPackage/attackby(obj/item/O, mob/user, params) + if(sealed) + if(istype(O, /obj/item/weapon/pen)) + var/str = copytext(sanitize(input(user,"Intended recipient?","Address","")),1,MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(user, "Invalid text.") return + user.visible_message("[user] addresses [src] to [str].") + name = "Shipping package (RE: [str])" + return + if(wrapped) + to_chat(user, "[src] already contains \a [wrapped].") + return + if(istype(O, /obj/item) && !istype(O, /obj/item/weapon/storage) && !istype(O, /obj/item/shippingPackage)) + if(!user.canUnEquip(O)) + to_chat(user, "[O] is stuck to your hand, you cannot put it in [src]!") + return + if(O.w_class > 3) + to_chat(user, "[O] is too large to fit in [src].") + else + wrapped = O + user.unEquip(O) + O.forceMove(src) + O.add_fingerprint(usr) + add_fingerprint(usr) + to_chat(user, "You put [O] in [src].") + +/obj/item/shippingPackage/attack_self(mob/user) + if(sealed) + to_chat(user, "You tear open [src], dropping the contents onto the floor.") + playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) + user.unEquip(src) + wrapped.forceMove(get_turf(user)) + wrapped = null + qdel(src) + else if(wrapped) + switch(alert("Select an action:",, "Remove Object", "Seal Package", "Cancel")) + if("Remove Object") + to_chat(user, "You shake out [src]'s contents onto the floor.") + wrapped.forceMove(get_turf(user)) + wrapped = null + if("Seal Package") + to_chat(user, "You seal [src], preparing it for delivery.") + icon_state = "shippack_sealed" + sealed = 1 + update_desc() + else + if(alert("Do you want to tear up the package?",, "Yes", "No") == "Yes") + to_chat(user, "You shred [src].") + playsound(loc, 'sound/items/poster_ripped.ogg', 50, 1) + user.unEquip(src) + qdel(src) + +/obj/item/shippingPackage/proc/update_desc() + desc = "A pre-labeled package for shipping an item to coworkers." + if(sortTag) + desc += " The label says \"Deliver to [TAGGERLOCATIONS[sortTag]]\"." + if(!sealed) + desc += " The package is not sealed." + +/obj/item/shippingPackage/Destroy() + if(wrapped) + qdel(wrapped) + wrapped = null + return ..() \ No newline at end of file diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 06dbba8d62e..26f9413bc5f 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -43,7 +43,8 @@ other types of metals and chemistry for reagents). var/build_type = null //Flag as to what kind machine the design is built in. See defines. var/list/materials = list() //List of materials. Format: "id" = amount. var/construction_time //Amount of time required for building the object - var/build_path = "" //The file path of the object that gets created + var/build_path = null //The file path of the object that gets created + var/list/make_reagents = list() //Reagents produced. Format: "id" = amount. Currently only supported by the biogenerator. var/locked = 0 //If true it will spawn inside a lockbox with currently sec access var/access_requirement = list(access_armory) //What special access requirements will the lockbox have? Defaults to armory. var/category = null //Primarily used for Mech Fabricators, but can be used for anything diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index f34d9797124..450b0b8982a 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -130,6 +130,14 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/weapon/airlock_electronics category = list("initial", "Electronics") + +/datum/design/firelock_board + name = "Firelock Electronics" + id = "firelock_board" + build_type = AUTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 50) + build_path = /obj/item/weapon/firelock_electronics + category = list("initial", "Electronics") /datum/design/apc_electronics name="Power Control Module" @@ -162,6 +170,14 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/weapon/firealarm_electronics category = list("initial", "Electronics") + +/datum/design/earmuffs + name = "Earmuffs" + id = "earmuffs" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/ears/earmuffs + category = list("initial", "Miscellaneous") /datum/design/igniter name = "Igniter" @@ -188,7 +204,7 @@ category = list("initial", "Medical") /datum/design/kitchen_knife - name = "Kitchen knife" + name = "Kitchen Knife" id = "kitchen_knife" build_type = AUTOLATHE materials = list(MAT_METAL = 12000) @@ -196,19 +212,19 @@ category = list("initial","Miscellaneous") /datum/design/minihoe - name = "Mini hoe" + name = "Mini Hoe" id = "mini_hoe" build_type = AUTOLATHE materials = list(MAT_METAL = 50) - build_path = /obj/item/weapon/minihoe + build_path = /obj/item/weapon/cultivator category = list("initial","Miscellaneous") /datum/design/plant_analyzer - name = "Plant analyzer" + name = "Plant Analyzer" id = "plant_analyzer" build_type = AUTOLATHE materials = list(MAT_METAL = 30, MAT_GLASS = 20) - build_path = /obj/item/device/analyzer/plant_analyzer + build_path = /obj/item/device/plant_analyzer category = list("initial","Miscellaneous") /datum/design/shovel @@ -324,12 +340,12 @@ category = list("initial", "Miscellaneous") /datum/design/foambox - name = "Box of Foam Force darts" - id = "foamforce" - build_type = AUTOLATHE - materials = list(MAT_METAL = 2000) - build_path = /obj/item/ammo_box/foambox - category = list("initial", "Miscellaneous") + name = "Box of Foam Force darts" + id = "foamforce" + build_type = AUTOLATHE + materials = list(MAT_METAL = 2000) + build_path = /obj/item/ammo_box/foambox + category = list("initial", "Miscellaneous") /datum/design/canvas/twentythreeXtwentythree name = "23px by 23px Canvas" diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm new file mode 100644 index 00000000000..fb6201eaf31 --- /dev/null +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -0,0 +1,220 @@ +/////////////////////////////////// +///////Biogenerator Designs /////// +/////////////////////////////////// + +/datum/design/milk + name = "10 milk" + id = "milk" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 20) + make_reagents = list("milk" = 10) + category = list("initial","Food") + +/datum/design/cream + name = "10 cream" + id = "cream" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 30) + make_reagents = list("cream" = 10) + category = list("initial","Food") + +/datum/design/milk_carton + name = "Milk carton" + id = "milk_carton" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 100) + build_path = /obj/item/weapon/reagent_containers/food/condiment/milk + category = list("initial","Food") + +/datum/design/cream_carton + name = "Cream carton" + id = "cream_carton" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/reagent_containers/food/drinks/bottle/cream + category = list("initial","Food") + +/datum/design/black_pepper + name = "10u black pepper" + id = "black_pepper" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 25) + make_reagents = list("blackpepper" = 10) + category = list("initial","Food") + +/datum/design/pepper_mill + name = "Pepper mill" + id = "pepper_mill" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 50) + build_path = /obj/item/weapon/reagent_containers/food/condiment/peppermill + make_reagents = list() + category = list("initial","Food") + +/datum/design/monkey_cube + name = "Monkey cube" + id = "mcube" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 250) + build_path = /obj/item/weapon/reagent_containers/food/snacks/monkeycube + category = list("initial", "Food") + +/datum/design/ez_nut + name = "E-Z-Nutrient" + id = "ez_nut" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 10) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/nutrient/ez + category = list("initial","Botany Chemicals") + +/datum/design/l4z_nut + name = "Left 4 Zed" + id = "l4z_nut" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 20) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/nutrient/l4z + category = list("initial","Botany Chemicals") + +/datum/design/rh_nut + name = "Robust Harvest" + id = "rh_nut" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 25) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/nutrient/rh + category = list("initial","Botany Chemicals") + +/datum/design/weed_killer + name = "Weed Killer" + id = "weed_killer" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 50) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/killer/weedkiller + category = list("initial","Botany Chemicals") + +/datum/design/pest_spray + name = "Pest Killer" + id = "pest_spray" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 50) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/killer/pestkiller + category = list("initial","Botany Chemicals") + +/datum/design/botany_bottle + name = "Empty Bottle" + id = "botany_bottle" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 5) + build_path = /obj/item/weapon/reagent_containers/glass/bottle/nutrient/empty + category = list("initial", "Botany Chemicals") + +/datum/design/cloth + name = "Roll of cloth" + id = "cloth" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 50) + build_path = /obj/item/stack/sheet/cloth + category = list("initial","Leather and Cloth") + +/datum/design/wallet + name = "Wallet" + id = "wallet" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 100) + build_path = /obj/item/weapon/storage/wallet + category = list("initial","Leather and Cloth") + +/datum/design/botany_gloves + name = "Botanical gloves" + id = "botany_gloves" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 150) + build_path = /obj/item/clothing/gloves/botanic_leather + category = list("initial","Leather and Cloth") + +/datum/design/toolbelt + name = "Utility Belt" + id = "toolbelt" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/utility + category = list("initial","Leather and Cloth") + +/datum/design/hydrobelt + name = "Botanist belt" + id = "hydrobelt" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/botany + category = list("initial","Leather and Cloth") + +/datum/design/secbelt + name = "Security belt" + id = "secbelt" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/security + category = list("initial","Leather and Cloth") + +/datum/design/medbelt + name = "Medical belt" + id = "medbel" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/medical + category = list("initial","Leather and Cloth") + +/datum/design/janibelt + name = "Janitorial belt" + id = "janibelt" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/janitor + category = list("initial","Leather and Cloth") + +/datum/design/bandolier + name = "Bandolier belt" + id = "bandolier" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/weapon/storage/belt/bandolier + category = list("initial","Leather and Cloth") + +/datum/design/s_holster + name = "Shoulder holster" + id = "s_holster" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 400) + build_path = /obj/item/weapon/storage/belt/holster + category = list("initial","Leather and Cloth") + +/datum/design/leather_satchel + name = "Leather satchel" + id = "leather_satchel" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 400) + build_path = /obj/item/weapon/storage/backpack/satchel + category = list("initial","Leather and Cloth") + +/datum/design/leather_jacket + name = "Leather jacket" + id = "leather_jacket" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 500) + build_path = /obj/item/clothing/suit/jacket/leather + category = list("initial","Leather and Cloth") + +/datum/design/leather_overcoat + name = "Leather overcoat" + id = "leather_overcoat" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 1000) + build_path = /obj/item/clothing/suit/jacket/leather/overcoat + category = list("initial","Leather and Cloth") + +/datum/design/rice_hat + name = "Rice hat" + id = "rice_hat" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 300) + build_path = /obj/item/clothing/head/rice_hat + category = list("initial","Leather and Cloth") diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index e7e14f2e4ba..6d3624701b9 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -342,29 +342,42 @@ build_path = /obj/item/weapon/circuitboard/teleporter category = list("Computer Boards") -datum/design/GAC - name = "Circuit Design (General Air Control)" +/datum/design/GAC + name = "Console Board (General Air Control)" desc = "Allows for the construction of circuit boards used to build a General Air Control Computer." id = "GAC" req_tech = list("programming" = 3, "magnets" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/air_management + category = list("Computer Boards") -datum/design/tank_control - name = "Circuit Design (Large Tank Control)" +/datum/design/tank_control + name = "Console Board (Large Tank Control)" desc = "Allows for the construction of circuit boards used to build a Large Tank Control Computer." id = "tankcontrol" req_tech = list("programming" = 3, "magnets" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/large_tank_control + category = list("Computer Boards") -datum/design/AAC - name = "Circuit Design (Atmospheric Automations Console)" - desc = "Allows for the construction of circuit boards used to build an Atmospheric Autmations Console." +/datum/design/AAC + name = "Console Board (Atmospheric Automations Console)" + desc = "Allows for the construction of circuit boards used to build an Atmospheric Automations Console." id = "AAC" req_tech = list("programming" = 4, "magnets" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1000, "sacid" = 20) - build_path = /obj/item/weapon/circuitboard/atmos_automation \ No newline at end of file + build_path = /obj/item/weapon/circuitboard/atmos_automation + category = list("Computer Boards") + +/datum/design/xenobiocamera + name = "Console Board (Xenobiology Console)" + desc = "Allows for the construction of circuit boards used to build xenobiology camera computers." + id = "xenobioconsole" + req_tech = list("programming" = 3, "biotech" = 3) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/xenobiology + category = list("Computer Boards") diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index ca63be9e4ae..c1d3c64d6b9 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -62,6 +62,16 @@ build_path = /obj/item/weapon/circuitboard/power_turbine category = list ("Engineering Machinery") +/datum/design/quantumpad + name = "Machine Board (Quantum Pad Board)" + desc = "The circuit board for a quantum telepad." + id = "quantumpad" + req_tech = list("programming" = 4, "bluespace" = 4, "plasmatech" = 3, "engineering" = 4) + build_type = IMPRINTER + materials = list(MAT_GLASS = 1000, "sacid" = 20) + build_path = /obj/item/weapon/circuitboard/quantumpad + category = list ("Teleportation Machinery") + /datum/design/telepad name = "Machine Board (Telepad Board)" desc = "Allows for the construction of circuit boards used to build a Telepad." @@ -340,7 +350,7 @@ build_type = IMPRINTER materials = list(MAT_GLASS = 1000, "sacid" = 20) build_path = /obj/item/weapon/circuitboard/seed_extractor - category = list ("Misc. Machinery") + category = list ("Hydroponics Machinery") /datum/design/processor name = "Machine Design (Processor Board)" @@ -512,23 +522,12 @@ build_path = /obj/item/weapon/circuitboard/gameboard category = list("Misc. Machinery") - -/datum/design/botany_extractor - name = "Machine Design (Lysis-Isolation Centrifuge)" - desc = "The circuit board for a lysis-isolation centrifuge." - id = "botany_extractor" - req_tech = list("biotech" = 3, "programming" = 3) +/datum/design/plantgenes + name = "Machine Design (Plant DNA Manipulator Board)" + desc = "The circuit board for a plant DNA manipulator." + id = "plantgenes" + req_tech = list("programming" = 4, "biotech" = 3) build_type = IMPRINTER materials = list(MAT_GLASS=1000, "sacid"=20) - build_path = /obj/item/weapon/circuitboard/botany_extractor - category = list("Hydroponics Machinery") - -/datum/design/botany_editor - name = "Machine Design (Bioballistic Delivery System)" - desc = "The circuit board for a bioballistic delivery system." - id = "botany_editor" - req_tech = list("biotech" = 3, "programming" = 3) - build_type = IMPRINTER - materials = list(MAT_GLASS=1000, "sacid"=20) - build_path = /obj/item/weapon/circuitboard/botany_editor - category = list("Hydroponics Machinery") + build_path = /obj/item/weapon/circuitboard/plantgenes + category = list("Hydroponics Machinery") \ No newline at end of file diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 702afa68f2f..779a0809577 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1038,16 +1038,6 @@ construction_time = 120 category = list("Cyborg Upgrade Modules") -/datum/design/borg_upgrade_hyperka - name = "Cyborg Upgrade (Hyper-Kinetic Accelerator)" - id = "borg_upgrade_hyperka" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) - build_type = MECHFAB //Reqs same as human Hyper KA - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) - build_path = /obj/item/borg/upgrade/hyperka - construction_time = 120 - category = list("Cyborg Upgrade Modules") - /datum/design/borg_syndicate_module name = "Cyborg Upgrade (Illegal Modules)" id = "borg_syndicate_module" @@ -1078,6 +1068,16 @@ construction_time = 50 category = list("Misc") +/datum/design/mecha_tracking_ai_control + name = "AI Control Beacon" + id = "mecha_tracking_ai_control" + build_type = MECHFAB + build_path = /obj/item/mecha_parts/mecha_tracking/ai_control + materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_SILVER = 200) + req_tech = list("programming" = 3, "magnets" = 2, "engineering" = 2) + construction_time = 50 + category = list("Misc") + /datum/design/ipc_head name = "IPC Head" id = "ipc_head" @@ -1100,7 +1100,7 @@ name = "IPC Optical Sensor" id = "ipc_optics" build_type = MECHFAB - build_path = /obj/item/organ/internal/optical_sensor + build_path = /obj/item/organ/internal/eyes/optical_sensor materials = list(MAT_METAL=1000, MAT_GLASS=2500) construction_time = 200 category = list("Misc") diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm index 2b7d911f2b1..aa3014e2825 100644 --- a/code/modules/research/designs/mining_designs.dm +++ b/code/modules/research/designs/mining_designs.dm @@ -64,26 +64,6 @@ build_path = /obj/item/weapon/pickaxe/drill/jackhammer category = list("Mining") -/datum/design/superaccelerator - name = "Super-Kinetic Accelerator" - desc = "An upgraded version of the proto-kinetic accelerator, with superior damage, speed and range." - id = "superaccelerator" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) - build_path = /obj/item/weapon/gun/energy/kinetic_accelerator/super - category = list("Mining") - -/datum/design/hyperaccelerator - name = "Hyper-Kinetic Accelerator" - desc = "An upgraded version of the proto-kinetic accelerator, with even more superior damage, speed and range." - id = "hyperaccelerator" - req_tech = list("materials" = 6, "powerstorage" = 6, "engineering" = 5, "magnets" = 6, "combat" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) - build_path = /obj/item/weapon/gun/energy/kinetic_accelerator/hyper - category = list("Mining") - /datum/design/superresonator name = "Upgraded Resonator" desc = "An upgraded version of the resonator that allows more fields to be active at once." @@ -92,4 +72,64 @@ build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) build_path = /obj/item/weapon/resonator/upgraded - category = list("Mining") \ No newline at end of file + category = list("Mining") + +/datum/design/trigger_guard_mod + name = "Kinetic Accelerator Trigger Guard Mod" + desc = "A device which allows kinetic accelerators to be wielded by any organism." + id = "triggermod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/trigger_guard + category = list("Mining") + +/datum/design/damage_mod + name = "Kinetic Accelerator Damage Mod" + desc = "A device which allows kinetic accelerators to deal more damage." + id = "damagemod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/damage + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/cooldown_mod + name = "Kinetic Accelerator Cooldown Mod" + desc = "A device which decreases the cooldown of a Kinetic Accelerator." + id = "cooldownmod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/cooldown + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/range_mod + name = "Kinetic Accelerator Range Mod" + desc = "A device which allows kinetic accelerators to fire at a further range." + id = "rangemod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/range + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/superaccelerator + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do more damage while indoors." + id = "indoormod" + req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000) + build_path = /obj/item/borg/upgrade/modkit/indoors + category = list("Mining", "Cyborg Upgrade Modules") + +/datum/design/hyperaccelerator + name = "Kinetic Accelerator Mining AoE Mod" + desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." + id = "hypermod" + req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) + build_path = /obj/item/borg/upgrade/modkit/aoe/turfs + category = list("Mining", "Cyborg Upgrade Modules") \ No newline at end of file diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 44aff0048d5..ea67fe5e809 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -11,6 +11,16 @@ build_path = /obj/item/weapon/disk/design_disk category = list("Miscellaneous") +/datum/design/diskplantgene + name = "Plant data disk" + desc = "A disk for storing plant genetic data." + id = "diskplantgene" + req_tech = list("programming" = 4, "biotech" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL=200, MAT_GLASS=100) + build_path = /obj/item/weapon/disk/plantgene + category = list("Miscellaneous") + /datum/design/intellicard name = "Intellicard" desc = "Allows for the construction of an intellicard." diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 121eb0ee2d3..1e7e9b1674a 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -410,6 +410,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(being_built) var/power = 2000 var/amount=text2num(href_list["amount"]) + if(being_built.make_reagents.len) + return 0 amount = max(1, min(10, amount)) for(var/M in being_built.materials) power += round(being_built.materials[M] * amount / 5) @@ -718,6 +720,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(b_type & AUTOLATHE) lathe_types += "Autolathe" if(b_type & MECHFAB) lathe_types += "Mech Fabricator" if(b_type & PODFAB) lathe_types += "Spacepod Fabricator" + if(b_type & BIOGENERATOR) lathe_types += "Biogenerator" var/list/materials = list() disk_data["materials"] = materials for(var/M in d_disk.blueprint.materials) diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm index 34b5a00fd71..d7ca9ef883d 100644 --- a/code/modules/research/research.dm +++ b/code/modules/research/research.dm @@ -178,6 +178,21 @@ research holder datum. return ..() +//Biogenerator files +/datum/research/biogenerator/New() + for(var/T in (subtypesof(/datum/tech))) + possible_tech += new T(src) + for(var/path in subtypesof(/datum/design)) + var/datum/design/D = new path(src) + possible_designs += D + if((D.build_type & BIOGENERATOR) && ("initial" in D.category)) + AddDesign2Known(D) + +/datum/research/biogenerator/AddDesign2Known(datum/design/D) + if(!(D.build_type & BIOGENERATOR)) + return + ..() + /*************************************************************** ** Technology Datums ** ** Includes all the various technoliges and what they make. ** @@ -311,10 +326,7 @@ datum/tech/robotics /obj/item/weapon/disk/tech_disk name = "\improper Technology Disk" desc = "A disk for storing technology data for further research." - icon = 'icons/obj/cloning.dmi' icon_state = "datadisk2" - item_state = "card-id" - w_class = 1 materials = list(MAT_METAL=30, MAT_GLASS=10) var/datum/tech/stored var/default_name = "\improper Technology Disk" @@ -339,10 +351,7 @@ datum/tech/robotics /obj/item/weapon/disk/design_disk name = "\improper Component Design Disk" desc = "A disk for storing device design data for construction in lathes." - icon = 'icons/obj/cloning.dmi' icon_state = "datadisk2" - item_state = "card-id" - w_class = 1 materials = list(MAT_METAL=30, MAT_GLASS=10) var/datum/design/blueprint // I'm doing this so that disk paths with pre-loaded designs don't get weird names diff --git a/code/modules/research/xenoarchaeology/machinery/coolant.dm b/code/modules/research/xenoarchaeology/machinery/coolant.dm index f0750f6388e..ffbf02c23bc 100644 --- a/code/modules/research/xenoarchaeology/machinery/coolant.dm +++ b/code/modules/research/xenoarchaeology/machinery/coolant.dm @@ -9,43 +9,5 @@ /obj/structure/reagent_dispensers/coolanttank name = "coolant tank" desc = "A tank of industrial coolant" - icon = 'icons/obj/objects.dmi' icon_state = "coolanttank" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/coolanttank/New() - ..() - reagents.add_reagent("coolant",1000) - -/obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) - if(!Proj.damage) - explode() - -/obj/structure/reagent_dispensers/coolanttank/blob_act() - explode() - -/obj/structure/reagent_dispensers/coolanttank/ex_act() - explode() - -/obj/structure/reagent_dispensers/coolanttank/proc/explode() - var/datum/effect/system/harmless_smoke_spread/S = new /datum/effect/system/harmless_smoke_spread - //S.attach(src) - S.set_up(5, 0, src.loc) - - playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - S.start() - - var/datum/gas_mixture/env = src.loc.return_air() - if(env) - if(reagents.total_volume > 750) - env.temperature = 0 - else if(reagents.total_volume > 500) - env.temperature -= 100 - else - env.temperature -= 50 - - sleep(10) - if(src) - qdel(src) + reagent_id = "coolant" \ No newline at end of file diff --git a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm index 8974d7ee1b0..1f530c832e7 100644 --- a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm +++ b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm @@ -210,6 +210,6 @@ M.lastattacker = user if(inserted_battery.battery_effect) - user.attack_log += "\[[time_stamp()]\] Tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" - M.attack_log += "\[[time_stamp()]\] Tapped by [key_name(user)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" + user.create_attack_log(" Tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])") + M.create_attack_log(" Tapped by [key_name(user)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])") msg_admin_attack("[key_name_admin(user)] tapped [key_name_admin(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" ) diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 7b27642722b..416eac1ba2a 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -3,11 +3,16 @@ visible_icon = 1 icon = 'icons/obj/abductor.dmi' icon_state = "camera_target" + var/allowed_area = null +/mob/camera/aiEye/remote/xenobio/New(loc) + var/area/A = get_area(loc) + allowed_area = A.name + ..() -/mob/camera/aiEye/remote/xenobio/setLoc(var/t) +/mob/camera/aiEye/remote/xenobio/setLoc(t) var/area/new_area = get_area(t) - if(new_area && new_area.name == "Xenobiology Lab" || istype(new_area, /area/toxins/xenobiology )) + if(new_area && new_area.name == allowed_area || istype(new_area, /area/toxins/xenobiology )) return ..() else return @@ -16,6 +21,7 @@ name = "Slime management console" desc = "A computer used for remotely handling slimes." networks = list("SS13") + circuit = /obj/item/weapon/circuitboard/xenobiology off_action = new /datum/action/innate/camera_off/xenobio var/datum/action/innate/slime_place/slime_place_action = new var/datum/action/innate/slime_pick_up/slime_up_action = new @@ -30,8 +36,7 @@ icon_keyboard = "rd_key" /obj/machinery/computer/camera_advanced/xenobio/CreateEye() - eyeobj = new /mob/camera/aiEye/remote/xenobio() - eyeobj.loc = get_turf(src) + eyeobj = new /mob/camera/aiEye/remote/xenobio(get_turf(src)) eyeobj.origin = src eyeobj.visible_icon = 1 eyeobj.icon = 'icons/obj/abductor.dmi' diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 03e0ae2645d..c3072758331 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -25,8 +25,8 @@ ..() /obj/item/slime_extract/New() - ..() - create_reagents(100) + ..() + create_reagents(100) /obj/item/slime_extract/grey name = "grey slime extract" @@ -124,7 +124,9 @@ w_class = 1 origin_tech = "biotech=4" -/obj/item/slimepotion/afterattack(obj/item/weapon/reagent_containers/target, mob/user , proximity) +/obj/item/slimepotion/afterattack(obj/item/weapon/reagent_containers/target, mob/user, proximity_flag) + if(!proximity_flag) + return if(istype(target)) to_chat(user, "You cannot transfer [src] to [target]! It appears the potion must be given directly to a slime to absorb.") // le fluff faec return @@ -134,50 +136,47 @@ desc = "A potent chemical mix that nullifies a slime's hunger, causing it to become docile and tame." icon = 'icons/obj/chemical.dmi' icon_state = "bottle19" + var/being_used = 0 /obj/item/slimepotion/docility/attack(mob/living/carbon/slime/M, mob/user) if(!isslime(M)) to_chat(user, " The potion only works on slimes!") - return ..() + return if(M.stat) to_chat(user, " The slime is dead!") - return..() + return if(M.mind) to_chat(user, " The slime resists!") - return ..() + return + if(being_used) + to_chat(user, " You're already using this on another slime!") + return + + var/mob/living/simple_animal/slime/pet if(M.is_adult) - var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) + pet = new /mob/living/simple_animal/slime/adult(M.loc) pet.icon_state = "[M.colour] adult slime" pet.icon_living = "[M.colour] adult slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - qdel(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - - if(!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - qdel(src) else - var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) + pet = new /mob/living/simple_animal/slime(M.loc) pet.icon_state = "[M.colour] baby slime" pet.icon_living = "[M.colour] baby slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - qdel(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) + pet.icon_dead = "[M.colour] baby slime dead" + pet.colour = "[M.colour]" + qdel(M) + being_used = 1 + var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - if(!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - qdel(src) + if(!newname) + newname = "pet slime" + pet.name = newname + pet.real_name = newname + qdel(src) to_chat(user, "You feed the slime the potion, removing it's powers and calming it.") /obj/item/slimepotion/sentience name = "sentience potion" - desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being." + desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels." icon = 'icons/obj/chemical.dmi' icon_state = "bottle19" origin_tech = "biotech=5" @@ -185,7 +184,9 @@ var/being_used = 0 var/sentience_type = SENTIENCE_ORGANIC -/obj/item/slimepotion/sentience/afterattack(mob/living/M, mob/user) +/obj/item/slimepotion/sentience/afterattack(mob/living/M, mob/user, proximity_flag) + if(!proximity_flag) + return if(being_used || !ismob(M)) return if(!isanimal(M) || M.ckey) //only works on animals that aren't player controlled @@ -224,6 +225,50 @@ being_used = 0 ..() +/obj/item/slimepotion/transference + name = "consciousness transference potion" + desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + origin_tech = "biotech=6" + var/prompted = FALSE + var/animal_type = SENTIENCE_ORGANIC + +/obj/item/slimepotion/transference/afterattack(mob/living/M, mob/user, proximity_flag) + if(!proximity_flag) + return + if(prompted || !ismob(M)) + return + if(!isanimal(M) || M.ckey) //much like sentience, these will not work on something that is already player controlled + to_chat(user, "[M] already has a higher consciousness!") + return ..() + if(M.stat) + to_chat(user, "[M] is dead!") + return ..() + var/mob/living/simple_animal/SM = M + if(SM.sentience_type != animal_type) + to_chat(user, "You cannot transfer your consciousness to [SM].") //no controlling machines + return ..() + if(jobban_isbanned(user, ROLE_SENTIENT)) + to_chat(user, "Your mind goes blank as you attempt to use the potion.") + return + + prompted = TRUE + if(alert("This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,"Yes","No")=="No") + prompted = FALSE + return + + to_chat(user, "You drink the potion then place your hands on [SM]...") + user.mind.transfer_to(SM) + SM.universal_speak = 1 + SM.faction = user.faction + SM.sentience_act() //Same deal here as with sentience + user.death() + to_chat(SM, "In a quick flash, you feel your consciousness flow into [SM]!") + to_chat(SM, "You are now [SM]. Your allegiances, alliances, and roles are still the same as they were prior to consciousness transfer!") + SM.name = "[SM.name] as [user.real_name]" + qdel(src) + /obj/item/slimepotion/steroid name = "slime steroid" desc = "A potent chemical mix that will cause a baby slime to generate more extract." @@ -306,15 +351,17 @@ icon = 'icons/obj/chemical.dmi' icon_state = "bottle3" -/obj/item/slimepotion/speed/afterattack(obj/item/C, mob/user) +/obj/item/slimepotion/speed/afterattack(obj/item/C, mob/user, proximity_flag) + if(!proximity_flag) + return ..() if(!istype(C)) to_chat(user, "The potion can only be used on items!") return if(C.slowdown <= 0) - to_chat(user, "The [C] can't be made any faster!") + to_chat(user, "[C] can't be made any faster!") return..() - to_chat(user, "You slather the red gunk over the [C], making it faster.") + to_chat(user, "You slather the red gunk over [C], making it faster.") C.color = "#FF0000" C.slowdown = 0 qdel(src) @@ -326,8 +373,10 @@ icon_state = "bottle17" var/uses = 3 -/obj/item/slimepotion/fireproof/afterattack(obj/item/clothing/C, mob/user) +/obj/item/slimepotion/fireproof/afterattack(obj/item/clothing/C, mob/user, proximity_flag) ..() + if(!proximity_flag) + return if(!uses) qdel(src) return @@ -335,9 +384,9 @@ to_chat(user, "The potion can only be used on clothing!") return if(C.max_heat_protection_temperature == FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) - to_chat(user, "The [C] is already fireproof!") + to_chat(user, "[C] is already fireproof!") return ..() - to_chat(user, "You slather the blue gunk over the [C], fireproofing it.") + to_chat(user, "You slather the blue gunk over [C], fireproofing it.") C.name = "fireproofed [C.name]" C.color = "#000080" C.max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT @@ -369,9 +418,9 @@ else icon_state = "golem" -/obj/effect/golemrune/attack_hand(mob/living/user as mob) +/obj/effect/golemrune/attack_hand(mob/living/user) var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) + for(var/mob/dead/observer/O in loc) if(!check_observer(O)) to_chat(O, "\red You are not eligible to become a golem.") continue @@ -394,21 +443,22 @@ volunteer(O) /obj/effect/golemrune/attack_ghost(var/mob/dead/observer/O) - if(!O) return + if(!O) + return volunteer(O) /obj/effect/golemrune/proc/check_observer(var/mob/dead/observer/O) if(!O) - return 0 + return FALSE if(!O.client) - return 0 + return FALSE if(O.mind && O.mind.current && O.mind.current.stat != DEAD) - return 0 + return FALSE if(!O.can_reenter_corpse) - return 0 + return FALSE if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) - return 0 - return 1 + return FALSE + return TRUE /obj/effect/golemrune/proc/volunteer(var/mob/dead/observer/O) if(O in ghosts) @@ -451,8 +501,8 @@ /obj/effect/timestop/proc/timestop() playsound(get_turf(src), 'sound/magic/TIMEPARADOX2.ogg', 100, 1, -1) for(var/i in 1 to duration-1) - for(var/A in orange (freezerange, src.loc)) - if(istype(A, /mob/living)) + for(var/A in orange (freezerange, loc)) + if(isliving(A)) var/mob/living/M = A if(M in immune) continue diff --git a/code/modules/security_levels/security levels.dm b/code/modules/security_levels/security levels.dm index a7a5162c231..bfa4f7449b6 100644 --- a/code/modules/security_levels/security levels.dm +++ b/code/modules/security_levels/security levels.dm @@ -7,8 +7,8 @@ //5 = code delta //config.alert_desc_blue_downto -/var/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 1, new_sound = sound('sound/misc/notice1.ogg')) -/var/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 1) +/var/datum/announcement/priority/security/security_announcement_up = new(do_log = 0, do_newscast = 0, new_sound = sound('sound/misc/notice1.ogg')) +/var/datum/announcement/priority/security/security_announcement_down = new(do_log = 0, do_newscast = 0) /proc/set_security_level(var/level) switch(level) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index f1ad87ddc7c..5f01cf8e890 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -166,12 +166,36 @@ shuttle_master.emergencyLastCallLoc = null emergency_shuttle_recalled.Announce("The emergency shuttle has been recalled.[shuttle_master.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]") -/* -/obj/docking_port/mobile/emergency/findTransitDock() - . = shuttle_master.getDock("emergency_transit") - if(.) return . - return ..() -*/ +/obj/docking_port/mobile/emergency/proc/is_hijacked() + for(var/mob/living/player in player_list) + if(player.mind) + if(player.stat != DEAD) + if(issilicon(player)) //Borgs are technically dead anyways + continue + if(isanimal(player)) //Poly does not own the shuttle + continue + + var/special_role = player.mind.special_role + if(special_role) + if(special_role == SPECIAL_ROLE_TRAITOR) // traitors can hijack the shuttle + continue + + if(special_role == SPECIAL_ROLE_CHANGELING) // changelings as well + continue + + if(special_role == SPECIAL_ROLE_VAMPIRE || special_role == SPECIAL_ROLE_VAMPIRE_THRALL) // for traitorvamp + continue + + if(special_role == SPECIAL_ROLE_NUKEOPS) // so can nukeops, for the hell of it + continue + + if(special_role == SPECIAL_ROLE_SYNDICATE_DEATHSQUAD) // and the syndie deathsquad i guess + continue + + if(get_area(player) == areaInstance) + return FALSE + + return TRUE /obj/docking_port/mobile/emergency/check() @@ -232,10 +256,19 @@ //move each escape pod to its corresponding escape dock for(var/obj/docking_port/mobile/pod/M in shuttle_master.mobile) M.dock(shuttle_master.getDock("[M.id]_away")) - //now move the actual emergency shuttle to centcomm + for(var/area/shuttle/escape/E in world) E << 'sound/effects/hyperspace_end.ogg' - dock(shuttle_master.getDock("emergency_away")) + + // now move the actual emergency shuttle to centcomm + // unless the shuttle is "hijacked" + var/destination_dock = "emergency_away" + if(is_hijacked()) + destination_dock = "emergency_syndicate" + priority_announcement.Announce("Corruption detected in shuttle navigation protocols. Please contact your supervisor.") + + dock_id(destination_dock) + mode = SHUTTLE_ENDGAME timer = 0 open_dock() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 1a03d3141c5..d48d892a86f 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -279,7 +279,7 @@ else // This isn't an error, per se, but we can't let the shuttle code // attempt to move us where we currently are, it will get weird. - return SHUTTLE_ALREADY_DOCKED + return SHUTTLE_ALREADY_DOCKED return SHUTTLE_CAN_DOCK /obj/docking_port/mobile/proc/check_dock(obj/docking_port/stationary/S) @@ -489,8 +489,14 @@ // Instead of spending a lot of time trying to work out where to place // our shuttle, just create it somewhere empty and send it to where // it should go - var/obj/docking_port/stationary/D = findRoundstartDock() - return dock(D) + . = dock_id(roundstart_move) + +/obj/docking_port/mobile/proc/dock_id(id) + var/port = shuttle_master.getDock(id) + if(port) + . = dock(port) + else + . = null /obj/effect/landmark/shuttle_import name = "Shuttle Import" @@ -761,6 +767,7 @@ /obj/machinery/computer/shuttle/ert name = "specops shuttle console" //circuit = /obj/item/weapon/circuitboard/ert + req_access = list(access_cent_general) shuttleId = "specops" possible_destinations = "specops_home;specops_away" @@ -799,13 +806,14 @@ /obj/machinery/computer/shuttle/sst name = "Syndicate Strike Time Shuttle Console" desc = "Used to call and send the SST shuttle." + req_access = list(access_syndicate) shuttleId = "sst" possible_destinations = "sst_home;sst_away" /obj/machinery/computer/shuttle/sit - req_access = list(access_syndicate) name = "Syndicate Infiltration Team Shuttle Console" desc = "Used to call and send the SIT shuttle." + req_access = list(access_syndicate) shuttleId = "sit" possible_destinations = "sit_arrivals;sit_scimaint;sit_engshuttle;sit_away" @@ -836,7 +844,7 @@ var/global/trade_dockrequest_timelimit = 0 if(world.time < trade_dockrequest_timelimit || world.time < trade_dock_timelimit) return to_chat(usr, "Request sent.") - command_announcement.Announce(docking_request_message, "Docking Request") + event_announcement.Announce(docking_request_message, "Docking Request") trade_dockrequest_timelimit = world.time + 1200 // They have 2 minutes to approve the request. /obj/machinery/computer/shuttle/trade/sol diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 970daf16e80..8944cf84131 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -199,20 +199,20 @@ // Sell exotic plants if(istype(thing, /obj/item/seeds)) var/obj/item/seeds/S = thing - if(S.seed.get_trait(TRAIT_RARITY) == 0) // Mundane species - msg += "+0: We don't need samples of mundane species \"[capitalize(S.seed.seed_name)]\".
" + if(S.rarity == 0) // Mundane species + msg += "+0: We don't need samples of mundane species \"[capitalize(S.species)]\".
" else if(shuttle_master.discoveredPlants[S.type]) // This species has already been sent to CentComm - var/potDiff = S.seed.get_trait(TRAIT_POTENCY) - shuttle_master.discoveredPlants[S.type] // Compare it to the previous best + var/potDiff = S.potency - shuttle_master.discoveredPlants[S.type] // Compare it to the previous best if(potDiff > 0) // This sample is better - shuttle_master.discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY) - msg += "+[potDiff]: New sample of \"[capitalize(S.seed.seed_name)]\" is superior. Good work.
" + shuttle_master.discoveredPlants[S.type] = S.potency + msg += "+[potDiff]: New sample of \"[capitalize(S.species)]\" is superior. Good work.
" shuttle_master.points += potDiff else // This sample is worthless - msg += "+0: New sample of \"[capitalize(S.seed.seed_name)]\" is not more potent than existing sample ([shuttle_master.discoveredPlants[S.type]] potency).
" + msg += "+0: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([shuttle_master.discoveredPlants[S.type]] potency).
" else // This is a new discovery! - shuttle_master.discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY) - msg += "+[S.seed.get_trait(TRAIT_RARITY)]: New species discovered: \"[capitalize(S.seed.seed_name)]\". Excellent work.
" - shuttle_master.points += S.seed.get_trait(TRAIT_RARITY) // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later + shuttle_master.discoveredPlants[S.type] = S.potency + msg += "[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
" + shuttle_master.points += S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later qdel(MA) shuttle_master.sold_atoms += "." @@ -246,7 +246,10 @@ /obj/machinery/teleport/station, /obj/machinery/teleport/hub, /obj/machinery/telepad, - /obj/machinery/clonepod + /obj/machinery/clonepod, + /obj/effect/hierophant, + /obj/item/device/warp_cube, + /obj/machinery/quantumpad ) if(A) if(is_type_in_list(A, blacklist)) diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 1c71f8837ee..af18daa893a 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -213,7 +213,7 @@ var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) deal_damage(damage) visible_message("[user] [user.attacktext] [src]!") - user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + user.create_attack_log("attacked [src.name]") return /obj/spacepod/attack_alien(mob/user as mob) diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index 2595d9bf95d..ba772007b62 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -24,14 +24,13 @@ return 0 var/dental_implants = 0 - for(var/obj/item/weapon/reagent_containers/food/pill in target.internal_organs) // Can't give them more than 4 dental implants. + for(var/obj/item/weapon/reagent_containers/food/pill in target.contents) // Can't give them more than 4 dental implants. dental_implants++ if(dental_implants >= 4) user.visible_message("[user] pulls \the [tool] back out of [target]'s [parse_zone(target_zone)]!", "You pull \the [tool] back out of [target]'s [parse_zone(target_zone)], there wans't enough room...") return 0 user.drop_item() - target.internal_organs += tool tool.forceMove(target) var/datum/action/item_action/hands_free/activate_pill/P = new diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 88f8078a2ba..153f169efca 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -164,7 +164,7 @@ desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." icon_state = "chest_implant" implant_color = "#00AA00" - var/hunger_threshold = 150 + var/hunger_threshold = NUTRITION_LEVEL_STARVING var/synthesizing = 0 var/poison_amount = 5 slot = "stomach" @@ -195,7 +195,7 @@ desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." icon_state = "chest_implant" implant_color = "#006607" - hunger_threshold = 300 + hunger_threshold = NUTRITION_LEVEL_HUNGRY poison_amount = 10 origin_tech = "materials=5;programming=3;biotech=5" diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index f71e9bff0be..d1a36f2c4a3 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -66,7 +66,7 @@ if(mind) //Handles vampires "eating" blood that isn't their own. if(mind in ticker.mode.vampires) for(var/datum/reagent/blood/BL in vessel.reagent_list) - if(nutrition >= 450) + if(nutrition >= NUTRITION_LEVEL_WELL_FED) break //We don't want blood tranfusions making vampires fat. if(BL.data["donor"] != src) nutrition += (15 * REAGENTS_METABOLISM) @@ -186,6 +186,16 @@ temp_chem += R.id temp_chem[R.id] = R.volume B.data["trace_chem"] = list2params(temp_chem) + if(mind) + B.data["mind"] = mind + if(ckey) + B.data["ckey"] = ckey + + if(!suiciding) + B.data["cloneable"] = 1 + B.data["gender"] = gender + B.data["real_name"] = real_name + B.data["factions"] = faction return B //For humans, blood does not appear from blue, it comes from vessels. diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 66436d22b64..16a22ea81f6 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -228,10 +228,10 @@ var/list/organ_cache = list() /obj/item/organ/proc/take_damage(amount, var/silent=0) if(tough) return - if(src.status & ORGAN_ROBOT) - src.damage = between(0, src.damage + (amount * 0.8), max_damage) + if(status & ORGAN_ROBOT) + damage = between(0, damage + (amount * 0.8), max_damage) else - src.damage = between(0, src.damage + amount, max_damage) + damage = between(0, damage + amount, max_damage) //only show this if the organ is not robotic if(owner && parent_organ && amount > 0) @@ -241,18 +241,18 @@ var/list/organ_cache = list() /obj/item/organ/proc/robotize() //Being used to make robutt hearts, etc robotic = 2 - src.status &= ~ORGAN_BROKEN - src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED - src.status &= ~ORGAN_CUT_AWAY - src.status &= ~ORGAN_ATTACHABLE - src.status &= ~ORGAN_DESTROYED - src.status |= ORGAN_ROBOT - src.status |= ORGAN_ASSISTED + status &= ~ORGAN_BROKEN + status &= ~ORGAN_BLEEDING + status &= ~ORGAN_SPLINTED + status &= ~ORGAN_CUT_AWAY + status &= ~ORGAN_ATTACHABLE + status &= ~ORGAN_DESTROYED + status |= ORGAN_ROBOT + status |= ORGAN_ASSISTED /obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc - robotize() - src.status &= ~ORGAN_ROBOT + robotize(1) //Skip the icon/name setting that occurs in robotize to avoid having to reset the icon file. + status &= ~ORGAN_ROBOT robotic = 1 min_bruised_damage = 15 min_broken_damage = 35 @@ -309,8 +309,8 @@ var/list/organ_cache = list() if(owner && vital && is_primary_organ()) // I'd do another check for species or whatever so that you couldn't "kill" an IPC by removing a human head from them, but it doesn't matter since they'll come right back from the dead if(user) - user.attack_log += "\[[time_stamp()]\] removed a vital organ ([src]) from [key_name(owner)] (INTENT: [uppertext(user.a_intent)])" - owner.attack_log += "\[[time_stamp()]\] had a vital organ ([src]) removed by [key_name(user)] (INTENT: [uppertext(user.a_intent)])" + user.create_attack_log(" removed a vital organ ([src]) from [key_name(owner)] (INTENT: [uppertext(user.a_intent)])") + owner.create_attack_log(" had a vital organ ([src]) removed by [key_name(user)] (INTENT: [uppertext(user.a_intent)])") msg_admin_attack("[key_name_admin(user)] removed a vital organ ([src]) from [key_name_admin(owner)]") owner.death() owner = null @@ -325,7 +325,7 @@ var/list/organ_cache = list() affected.internal_organs |= src if(!target.get_int_organ(src)) target.internal_organs += src - src.loc = target + loc = target if(robotic) status |= ORGAN_ROBOT diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 5dd4d570ee2..8de7cccd2d6 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -201,7 +201,7 @@ /obj/item/organ/internal/heart/prepare_eat() var/obj/S = ..() - S.icon_state = "heart-off" + S.icon_state = dead_icon return S /obj/item/organ/internal/heart/cursed @@ -343,16 +343,47 @@ parent_organ = "head" slot = "eyes" var/list/eye_colour = list(0,0,0) + var/list/colourmatrix = null + var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white. + var/colourblind_darkview = null + var/dependent_disabilities = null //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation. + var/dark_view = 2 //Default dark_view for Humans. + var/weld_proof = null //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will. /obj/item/organ/internal/eyes/proc/update_colour() dna.write_eyes_attributes(src) -/obj/item/organ/internal/eyes/insert(mob/living/carbon/M, special = 0) +/obj/item/organ/internal/eyes/proc/get_colourmatrix() //Returns a special colour matrix if the eyes are organic and the mob is colourblind, otherwise it uses the current one. + if(!robotic && owner.disabilities & COLOURBLIND) + return colourblind_matrix + else + return colourmatrix + +/obj/item/organ/internal/eyes/proc/get_dark_view() //Returns dark_view (if the eyes are organic) for see_invisible handling in species.dm to be autoprocessed by life(). + if(!robotic && colourblind_darkview && owner.disabilities & COLOURBLIND) //Returns special darkview value if colourblind and it exists, otherwise reuse current. + return colourblind_darkview + else + return dark_view + +/obj/item/organ/internal/eyes/insert(mob/living/carbon/human/M, special = 0) ..() if(istype(M) && eye_colour) - var/mob/living/carbon/human/H = M - // Apply our eye colour to the target. - H.update_body() + M.update_body() //Apply our eye colour to the target. + + if(!(M.disabilities & COLOURBLIND) && (dependent_disabilities & COLOURBLIND)) //If the eyes are colourblind and we're not, carry over the gene. + dependent_disabilities &= ~COLOURBLIND + M.dna.SetSEState(COLOURBLINDBLOCK,1) + genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) + else + M.update_client_colour() //If we're here, that means the mob acquired the colourblindness gene while they didn't have eyes. Better handle it. + +/obj/item/organ/internal/eyes/remove(mob/living/carbon/human/M, special = 0) + if(!special && (M.disabilities & COLOURBLIND)) //If special is set, that means these eyes are getting deleted (i.e. during set_species()) + if(!(dependent_disabilities & COLOURBLIND)) //We only want to change COLOURBLINDBLOCK and such it the eyes are being surgically removed. + dependent_disabilities |= COLOURBLIND + M.dna.SetSEState(COLOURBLINDBLOCK,0) + genemutcheck(M,COLOURBLINDBLOCK,null,MUTCHK_FORCED) + . = ..() /obj/item/organ/internal/eyes/surgeryize() if(!owner) @@ -362,6 +393,38 @@ owner.SetEyeBlurry(0) owner.SetEyeBlind(0) +/obj/item/organ/internal/robotize(var/icon_bypass) //If icon bypass isn't null, skip the processing here and go straight to the parent call. + if(!icon_bypass && !(status & ORGAN_ROBOT)) //Don't override the icons for the already-mechanical IPC organs. + var/list/states = icon_states('icons/obj/surgery.dmi') //Insensitive to specially-defined icon files for species like the Drask or whomever else. Everyone gets the same robotic heart. + if(slot == "heart" && ("[slot]-prosthetic-on" in states) && ("[slot]-prosthetic-off" in states)) //Give the robotic heart its robotic heart icons if they exist. + var/obj/item/organ/internal/heart/H = src + H.icon = icon('icons/obj/surgery.dmi') + H.icon_base = "[slot]-prosthetic" + H.dead_icon = "[slot]-prosthetic-off" + H.update_icon() + else if("[slot]-prosthetic" in states) //Give the robotic organ its robotic organ icons if they exist. + icon = icon('icons/obj/surgery.dmi') + icon_state = "[slot]-prosthetic" + name = "mechanical [slot]" + ..() //Go apply all the organ flags/robotic statuses. + +/obj/item/organ/internal/eyes/robotize() + colourmatrix = null + dark_view = 2 + ..() //Make sure the organ's got the robotic status indicators before updating the client colour. + owner.update_client_colour(0) //Since both mechassisted and mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine as mechassist() will call it anyway. + +/obj/item/organ/internal/mechassist() + ..() //Go back, call robotize(), adjust the robotic status indicators and the organ damage parameters. + var/list/states = icon_states(icon) //Sensitive to specially-defined icon files since the organs are not fully synthetic. + if(slot == "heart" && ("[organ_tag]-assisted-on" in states) && ("[organ_tag]-assisted-off" in states)) //Give the mechassisted heart its mechassisted heart icons if they exist. + var/obj/item/organ/internal/heart/H = src + H.icon_base = "[organ_tag]-assisted" + H.dead_icon = "[organ_tag]-assisted-off" + H.update_icon() + else if("[organ_tag]-assisted" in states) //Give the mechassisted organ its mechassisted organ icons if they exist. + icon_state = "[organ_tag]-assisted" + name = "mechanically assisted [initial(name)]" //Avoid setting the organ's name to something like "mechanically assisted mechanical eyes". /obj/item/organ/internal/liver name = "liver" @@ -372,7 +435,6 @@ var/alcohol_intensity = 1 /obj/item/organ/internal/liver/process() - ..() if(!owner) @@ -526,7 +588,7 @@ /obj/item/organ/internal/honktumor/process() if(isturf(loc)) visible_message("[src] honks in on itself!") - new /obj/item/weapon/bananapeel(get_turf(loc)) + new /obj/item/weapon/grown/bananapeel(get_turf(loc)) qdel(src) diff --git a/code/modules/surgery/organs/subtypes/abductor.dm b/code/modules/surgery/organs/subtypes/abductor.dm new file mode 100644 index 00000000000..6fd234bc501 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/abductor.dm @@ -0,0 +1,4 @@ +/obj/item/organ/internal/eyes/abductor + name = "abductor eyeballs" + dark_view = 3 + species = "Abductor" diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index a4b0d8fb92b..c7044f92fb9 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -1,22 +1,3 @@ -/*/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ) - if(!istype(organ)) - return 0 - - //This is a terrible hack and I should be ashamed. - var/datum/seed/diona = plant_controller.seeds["diona"] - if(!diona) - return 0 - - spawn(1) // So it has time to be thrown about by the gib() proc. - var/mob/living/simple_animal/diona/D = new(get_turf(organ)) - var/datum/ghosttrap/plant/P = get_ghost_trap("living plant") - P.request_player(D, "A diona nymph has split off from its gestalt. ") - spawn(60) - if(D) - if(!D.ckey || !D.client) - D.death() - return 1 */ - /obj/item/organ/external/chest/diona name = "core trunk" max_damage = 200 @@ -116,74 +97,42 @@ /obj/item/organ/diona/process() return -/obj/item/organ/internal/heart/diona +/obj/item/organ/internal/heart/diona // Turns into a nymph instantly, no transplanting possible. name = "neural strata" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - organ_tag = "heart" // Turns into a nymph instantly, no transplanting possible. - origin_tech = "biotech=3" - parent_organ = "chest" - slot = "heart" species = "Diona" -/obj/item/organ/internal/brain/diona +/obj/item/organ/internal/brain/diona // Turns into a nymph instantly, no transplanting possible. name = "gas bladder" - parent_organ = "head" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - organ_tag = "brain" // Turns into a nymph instantly, no transplanting possible. - origin_tech = "biotech=3" - slot = "brain" species = "Diona" -/obj/item/organ/internal/kidneys/diona +/obj/item/organ/internal/kidneys/diona // Turns into a nymph instantly, no transplanting possible. name = "polyp segment" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - organ_tag = "kidneys" // Turns into a nymph instantly, no transplanting possible. - origin_tech = "biotech=3" - parent_organ = "groin" - slot = "kidneys" species = "Diona" -/obj/item/organ/internal/appendix/diona +/obj/item/organ/internal/appendix/diona // Turns into a nymph instantly, no transplanting possible. name = "anchoring ligament" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - organ_tag = "appendix" // Turns into a nymph instantly, no transplanting possible. - origin_tech = "biotech=3" - parent_organ = "groin" - slot = "appendix" species = "Diona" -/obj/item/organ/internal/diona_receptor +/obj/item/organ/internal/eyes/diona // Turns into a nymph instantly, no transplanting possible. name = "receptor node" - organ_tag = "eyes" icon = 'icons/mob/alien.dmi' icon_state = "claw" - origin_tech = "biotech=3" - parent_organ = "head" - slot = "eyes" species = "Diona" -/obj/item/organ/internal/diona_receptor/surgeryize() - if(!owner) - return - owner.CureNearsighted() - owner.CureBlind() - owner.SetEyeBlurry(0) - owner.SetEyeBlind(0) - - //TODO:Make absorb rads on insert -/obj/item/organ/internal/liver/diona +/obj/item/organ/internal/liver/diona // Turns into a nymph instantly, no transplanting possible. name = "nutrient vessel" - parent_organ = "chest" - organ_tag = "liver" icon = 'icons/mob/alien.dmi' icon_state = "claw" - slot = "liver" alcohol_intensity = 0.5 species = "Diona" diff --git a/code/modules/surgery/organs/subtypes/drask.dm b/code/modules/surgery/organs/subtypes/drask.dm index b3b260a28a0..6e1e6662d0a 100644 --- a/code/modules/surgery/organs/subtypes/drask.dm +++ b/code/modules/surgery/organs/subtypes/drask.dm @@ -9,51 +9,29 @@ /obj/item/organ/internal/heart/drask name = "drask heart" icon = 'icons/obj/surgery_drask.dmi' - icon_state = "heart-on" - dead_icon = "heart-off" - organ_tag = "heart" parent_organ = "head" - slot = "heart" species = "Drask" /obj/item/organ/internal/lungs/drask - name = "lungs" icon = 'icons/obj/surgery_drask.dmi' - icon_state = "lungs" - gender = PLURAL - organ_tag = "lungs" - parent_organ = "chest" - slot = "lungs" species = "Drask" /obj/item/organ/internal/liver/drask name = "metabolic strainer" icon = 'icons/obj/surgery_drask.dmi' - icon_state = "kidneys" - gender = PLURAL - organ_tag = "kidneys" - parent_organ = "groin" - slot = "kidneys" alcohol_intensity = 0.8 species = "Drask" /obj/item/organ/internal/brain/drask - name = "brain" icon = 'icons/obj/surgery_drask.dmi' icon_state = "brain2" - organ_tag = "brain" - slot = "brain" mmi_icon = 'icons/obj/surgery_drask.dmi' mmi_icon_state = "mmi_full" species = "Drask" /obj/item/organ/internal/eyes/drask - name = "eyes" + name = "drask eyeballs" icon = 'icons/obj/surgery_drask.dmi' - icon_state = "eyes" - gender = PLURAL - organ_tag = "eyes" - parent_organ = "head" - slot = "eyes" desc = "Drask eyes. They look even stranger disembodied" + dark_view = 5 species = "Drask" diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm index a47ab801d6f..6c06da373b7 100644 --- a/code/modules/surgery/organs/subtypes/grey.dm +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -14,3 +14,8 @@ /obj/item/organ/internal/brain/grey/remove(var/mob/living/carbon/M, var/special = 0) . = ..() M.remove_language("Psionic Communication") + +/obj/item/organ/internal/eyes/grey + name = "grey eyeballs" + dark_view = 5 + species = "Grey" diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm index 0f402a42e5d..b3bb3f61e07 100644 --- a/code/modules/surgery/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -117,37 +117,26 @@ robotize() ..() -/obj/item/organ/internal/optical_sensor +/obj/item/organ/internal/eyes/optical_sensor name = "optical sensor" - organ_tag = "eyes" - parent_organ = "head" icon = 'icons/obj/robot_component.dmi' icon_state = "camera" - slot = "eyes" status = ORGAN_ROBOT species = "Machine" // dead_icon = "camera_broken" + weld_proof = 1 -/obj/item/organ/internal/optical_sensor/New() +/obj/item/organ/internal/eyes/optical_sensor/New() robotize() ..() -/obj/item/organ/internal/optical_sensor/remove(var/mob/living/user,special = 0) +/obj/item/organ/internal/eyes/optical_sensor/remove(var/mob/living/user,special = 0) if(!special) to_chat(owner, "Error 404:Optical Sensors not found.") . = ..() -/obj/item/organ/internal/optical_sensor/surgeryize() - if(!owner) - return - owner.CureNearsighted() - owner.CureBlind() - owner.SetEyeBlurry(0) - owner.SetEyeBlind(0) - - // Used for an MMI or posibrain being installed into a human. /obj/item/organ/internal/brain/mmi_holder name = "brain" @@ -160,7 +149,6 @@ species = "Machine" var/obj/item/device/mmi/stored_mmi - /obj/item/organ/internal/brain/mmi_holder/Destroy() if(stored_mmi) qdel(stored_mmi) diff --git a/code/modules/surgery/organs/subtypes/nucleation.dm b/code/modules/surgery/organs/subtypes/nucleation.dm index d234b666ae3..4223834501d 100644 --- a/code/modules/surgery/organs/subtypes/nucleation.dm +++ b/code/modules/surgery/organs/subtypes/nucleation.dm @@ -26,8 +26,6 @@ icon_state = "crystal-eyes" organ_tag = "luminescent eyes" light_color = "#1C1C00" - parent_organ = "head" - slot = "eyes" species = "Nucleation" /obj/item/organ/internal/eyes/luminescent_crystal/New() @@ -35,8 +33,7 @@ ..() /obj/item/organ/internal/brain/crystal - name = "crystalized brain" + name = "crystallized brain" icon_state = "crystal-brain" - organ_tag = "crystalized brain" - slot = "brain" + organ_tag = "crystallized brain" species = "Nucleation" diff --git a/code/modules/surgery/organs/subtypes/shadow.dm b/code/modules/surgery/organs/subtypes/shadow.dm new file mode 100644 index 00000000000..f81fc54bfb1 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/shadow.dm @@ -0,0 +1,4 @@ +/obj/item/organ/internal/eyes/shadow + name = "dark orbs" + dark_view = 8 + species = "Shadow" diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index faa6c403355..62ae8c78d66 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -103,7 +103,7 @@ can_stand = 1 /obj/item/organ/external/foot/remove() - if(owner.shoes) owner.unEquip(owner.shoes) + if(owner && owner.shoes) owner.unEquip(owner.shoes) . = ..() /obj/item/organ/external/foot/right @@ -128,12 +128,13 @@ can_grasp = 1 /obj/item/organ/external/hand/remove() - if(owner.gloves) - owner.unEquip(owner.gloves) - if(owner.l_hand) - owner.unEquip(owner.l_hand,1) - if(owner.r_hand) - owner.unEquip(owner.r_hand,1) + if(owner) + if(owner.gloves) + owner.unEquip(owner.gloves) + if(owner.l_hand) + owner.unEquip(owner.l_hand,1) + if(owner.r_hand) + owner.unEquip(owner.r_hand,1) . = ..() diff --git a/code/modules/surgery/organs/subtypes/tajaran.dm b/code/modules/surgery/organs/subtypes/tajaran.dm index e37686a05ca..746abd6e601 100644 --- a/code/modules/surgery/organs/subtypes/tajaran.dm +++ b/code/modules/surgery/organs/subtypes/tajaran.dm @@ -1,3 +1,16 @@ /obj/item/organ/internal/liver/tajaran alcohol_intensity = 1.4 species = "Tajaran" + +/obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ + name = "tajaran eyeballs" + species = "Tajaran" + colourblind_matrix = MATRIX_TAJ_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability. + colourblind_darkview = 8 + +/obj/item/organ/internal/eyes/tajaran/farwa //Being the lesser form of Tajara, Farwas have an utterly incurable version of their colourblindness. + name = "farwa eyeballs" + species = "Farwa" + colourmatrix = MATRIX_TAJ_CBLIND + dark_view = 8 diff --git a/code/modules/surgery/organs/subtypes/unathi.dm b/code/modules/surgery/organs/subtypes/unathi.dm index a769bce7a02..0fb45319ce5 100644 --- a/code/modules/surgery/organs/subtypes/unathi.dm +++ b/code/modules/surgery/organs/subtypes/unathi.dm @@ -1,3 +1,8 @@ /obj/item/organ/internal/liver/unathi alcohol_intensity = 0.8 species = "Unathi" + +/obj/item/organ/internal/eyes/unathi + name = "unathi eyeballs" + dark_view = 3 + species = "Unathi" diff --git a/code/modules/surgery/organs/subtypes/vulpkanin.dm b/code/modules/surgery/organs/subtypes/vulpkanin.dm index ca47ac83ddd..af3d9deab09 100644 --- a/code/modules/surgery/organs/subtypes/vulpkanin.dm +++ b/code/modules/surgery/organs/subtypes/vulpkanin.dm @@ -1,3 +1,16 @@ /obj/item/organ/internal/liver/vulpkanin alcohol_intensity = 1.4 species = "Vulpkanin" + +/obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2) + unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/ + name = "vulpkanin eyeballs" + species = "Vulpkanin" + colourblind_matrix = MATRIX_VULP_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability. + colourblind_darkview = 8 + +/obj/item/organ/internal/eyes/vulpkanin/wolpin //Being the lesser form of Vulpkanin, Wolpins have an utterly incurable version of their colourblindness. + name = "wolpin eyeballs" + species = "Wolpin" + colourmatrix = MATRIX_VULP_CBLIND + dark_view = 8 diff --git a/code/modules/surgery/organs/subtypes/wryn.dm b/code/modules/surgery/organs/subtypes/wryn.dm index f51adb6054e..ee1a12fd1ab 100644 --- a/code/modules/surgery/organs/subtypes/wryn.dm +++ b/code/modules/surgery/organs/subtypes/wryn.dm @@ -7,3 +7,7 @@ parent_organ = "head" slot = "hivenode" species = "Wryn" + +/obj/item/organ/internal/eyes/wryn + dark_view = 3 + species = "Wryn" diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm new file mode 100644 index 00000000000..63fe8fc81bc --- /dev/null +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -0,0 +1,455 @@ +var/static/regex/stun_words = regex("stop|wait|stand still|hold on|halt") +var/static/regex/weaken_words = regex("drop|fall|trip") +var/static/regex/sleep_words = regex("sleep|slumber") +var/static/regex/vomit_words = regex("vomit|throw up") +var/static/regex/silence_words = regex("shut up|silence|ssh|quiet|hush") +var/static/regex/hallucinate_words = regex("see the truth|hallucinate") +var/static/regex/wakeup_words = regex("wake up|awaken") +var/static/regex/heal_words = regex("live|heal|survive|mend|heroes never die") +var/static/regex/hurt_words = regex("die|suffer") +var/static/regex/bleed_words = regex("bleed") +var/static/regex/burn_words = regex("burn|ignite") +var/static/regex/repulse_words = regex("shoo|go away|leave me alone|begone|flee|fus ro dah") +var/static/regex/whoareyou_words = regex("who are you|say your name|state your name|identify") +var/static/regex/saymyname_words = regex("say my name") +var/static/regex/knockknock_words = regex("knock knock") +var/static/regex/statelaws_words = regex("state laws|state your laws") +var/static/regex/move_words = regex("move") +var/static/regex/walk_words = regex("walk|slow down") +var/static/regex/run_words = regex("run") +var/static/regex/helpintent_words = regex("help") +var/static/regex/disarmintent_words = regex("disarm") +var/static/regex/grabintent_words = regex("grab") +var/static/regex/harmintent_words = regex("harm|fight") +var/static/regex/throwmode_words = regex("throw|catch") +var/static/regex/flip_words = regex("flip|rotate|revolve|roll|somersault") +var/static/regex/rest_words = regex("rest") +var/static/regex/getup_words = regex("get up") +var/static/regex/sit_words = regex("sit") +var/static/regex/stand_words = regex("stand") +var/static/regex/dance_words = regex("dance") +var/static/regex/jump_words = regex("jump") +var/static/regex/salute_words = regex("salute") +var/static/regex/deathgasp_words = regex("play dead") +var/static/regex/clap_words = regex("clap|applaud") +var/static/regex/honk_words = regex("ho+nk") //hooooooonk +var/static/regex/multispin_words = regex("like a record baby") + +/obj/item/organ/internal/vocal_cords //organs that are activated through speech with the :x channel + name = "vocal cords" + icon_state = "appendix" + zone = "mouth" + slot = "vocal_cords" + parent_organ = "mouth" + var/spans = null + +/obj/item/organ/internal/vocal_cords/proc/can_speak_with() //if there is any limitation to speaking with these cords + return TRUE + +/obj/item/organ/internal/vocal_cords/proc/speak_with(message) //do what the organ does + return + +/obj/item/organ/internal/vocal_cords/proc/handle_speech(message) //change the message + return message + +//Colossus drop, forces the listeners to obey certain commands +/obj/item/organ/internal/vocal_cords/colossus + name = "divine vocal cords" + desc = "They carry the voice of an ancient god." + icon_state = "voice_of_god" + actions_types = list(/datum/action/item_action/organ_action/colossus) + var/next_command = 0 + var/cooldown_stun = 1200 + var/cooldown_damage = 600 + var/cooldown_meme = 300 + var/cooldown_none = 150 + var/base_multiplier = 1 + spans = "colossus yell" + +/datum/action/item_action/organ_action/colossus + name = "Voice of God" + var/obj/item/organ/internal/vocal_cords/colossus/cords = null + +/datum/action/item_action/organ_action/colossus/New() + ..() + cords = target + +/datum/action/item_action/organ_action/colossus/IsAvailable() + if(world.time < cords.next_command) + return FALSE + if(!owner) + return FALSE + if(!owner.can_speak()) + return FALSE + if(check_flags & AB_CHECK_CONSCIOUS) + if(owner.stat) + return FALSE + return TRUE + +/datum/action/item_action/organ_action/colossus/Trigger() + . = ..() + if(!IsAvailable()) + if(world.time < cords.next_command) + to_chat(owner, "You must wait [(cords.next_command - world.time)/10] seconds before Speaking again.") + return + var/command = input(owner, "Speak with the Voice of God", "Command") + if(!command) + return + owner.say(".x[command]") + +/obj/item/organ/internal/vocal_cords/colossus/can_speak_with() + if(world.time < next_command) + to_chat(owner, "You must wait [(next_command - world.time)/10] seconds before Speaking again.") + return FALSE + if(!owner) + return FALSE + if(!owner.can_speak()) + to_chat(owner, "You are unable to speak!") + return FALSE + if(owner.stat) + return FALSE + return TRUE + +/obj/item/organ/internal/vocal_cords/colossus/handle_speech(message) + spans = "colossus yell" //reset spans, just in case someone gets deculted or the cords change owner + if(iscultist(owner)) + spans += " narsiesmall" + return "[uppertext(message)]" + +/obj/item/organ/internal/vocal_cords/colossus/speak_with(message) + var/log_message = uppertext(message) + message = lowertext(message) + playsound(get_turf(owner), 'sound/magic/invoke_general.ogg', 300, 1, 5) + + var/mob/living/list/listeners = list() + for(var/mob/living/L in get_mobs_in_view(8, owner, TRUE)) + if(!L.ear_deaf && !L.null_rod_check() && L != owner && L.stat != DEAD) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) + continue + listeners += L + + if(!listeners.len) + next_command = world.time + cooldown_none + return + + var/power_multiplier = base_multiplier + + if(owner.mind) + //Chaplains are very good at speaking with the voice of god + if(owner.mind.assigned_role == "Chaplain") + power_multiplier *= 2 + //Command staff has authority + if(owner.mind.assigned_role in command_positions) + power_multiplier *= 1.4 + //Why are you speaking + if(owner.mind.assigned_role == "Mime") + power_multiplier *= 0.5 + + //Cultists are closer to their gods and are more powerful, but they'll give themselves away + if(iscultist(owner)) + power_multiplier *= 2 + + //Try to check if the speaker specified a name or a job to focus on + var/list/specific_listeners = list() + var/found_string = null + + for(var/V in listeners) + var/mob/living/L = V + /*if(L.mind && L.mind.devilinfo && findtext(message, L.mind.devilinfo.truename)) + var/start = findtext(message, L.mind.devilinfo.truename) + listeners = list(L) //let's be honest you're never going to find two devils with the same name + power_multiplier *= 5 //if you're a devil and god himself addressed you, you fucked up + //Cut out the name so it doesn't trigger commands + message = copytext(message, 0, start)+copytext(message, start + length(L.mind.devilinfo.truename), length(message) + 1) + break*/ + if(findtext(message, L.real_name) == 1) + specific_listeners += L //focus on those with the specified name + //Cut out the name so it doesn't trigger commands + found_string = L.real_name + + else if(L.mind && findtext(message, L.mind.assigned_role) == 1) + specific_listeners += L //focus on those with the specified job + //Cut out the job so it doesn't trigger commands + found_string = L.mind.assigned_role + + if(specific_listeners.len) + listeners = specific_listeners + power_multiplier *= (1 + (1/specific_listeners.len)) //2x on a single guy, 1.5x on two and so on + message = copytext(message, 0, 1)+copytext(message, 1 + length(found_string), length(message) + 1) + + //STUN + if(findtext(message, stun_words)) + for(var/V in listeners) + var/mob/living/L = V + L.Stun(3 * power_multiplier) + next_command = world.time + cooldown_stun + + //WEAKEN + else if(findtext(message, weaken_words)) + for(var/V in listeners) + var/mob/living/L = V + L.Weaken(3 * power_multiplier) + next_command = world.time + cooldown_stun + + //SLEEP + else if((findtext(message, sleep_words))) + for(var/V in listeners) + var/mob/living/L = V + L.Sleeping(2 * power_multiplier) + next_command = world.time + cooldown_stun + + //VOMIT + else if((findtext(message, vomit_words))) + for(var/mob/living/carbon/C in listeners) + C.vomit(10 * power_multiplier) + next_command = world.time + cooldown_stun + + //SILENCE + else if((findtext(message, silence_words))) + for(var/mob/living/carbon/C in listeners) + if(owner.mind && (owner.mind.assigned_role == "Librarian" || owner.mind.assigned_role == "Mime")) + power_multiplier *= 3 + C.silent += (10 * power_multiplier) + next_command = world.time + cooldown_stun + + //HALLUCINATE + else if((findtext(message, hallucinate_words))) + for(var/V in listeners) + var/mob/living/L = V + new /obj/effect/hallucination/delusion(get_turf(L),L,duration=150 * power_multiplier,skip_nearby=0) + next_command = world.time + cooldown_meme + + //WAKE UP + else if((findtext(message, wakeup_words))) + for(var/V in listeners) + var/mob/living/L = V + L.SetSleeping(0) + next_command = world.time + cooldown_damage + + //HEAL + else if((findtext(message, heal_words))) + for(var/V in listeners) + var/mob/living/L = V + L.heal_overall_damage(10 * power_multiplier, 10 * power_multiplier, 0, 0) + next_command = world.time + cooldown_damage + + //BRUTE DAMAGE + else if((findtext(message, hurt_words))) + for(var/V in listeners) + var/mob/living/L = V + L.apply_damage(15 * power_multiplier, def_zone = "chest") + next_command = world.time + cooldown_damage + + //BLEED + else if((findtext(message, bleed_words))) + for(var/mob/living/carbon/human/H in listeners) + H.drip(100 * power_multiplier) + next_command = world.time + cooldown_damage + + //FIRE + else if((findtext(message, burn_words))) + for(var/V in listeners) + var/mob/living/L = V + L.adjust_fire_stacks(1 * power_multiplier) + L.IgniteMob() + next_command = world.time + cooldown_damage + + //REPULSE + else if((findtext(message, repulse_words))) + for(var/V in listeners) + var/mob/living/L = V + var/throwtarget = get_edge_target_turf(owner, get_dir(owner, get_step_away(L, owner))) + L.throw_at(throwtarget, 3 * power_multiplier, 1) + next_command = world.time + cooldown_damage + + //WHO ARE YOU? + else if((findtext(message, whoareyou_words))) + for(var/V in listeners) + var/mob/living/L = V + /*if(L.mind && L.mind.devilinfo) + L.say("[L.mind.devilinfo.truename]") + else*/ + L.say("[L.real_name]") + next_command = world.time + cooldown_meme + + //SAY MY NAME + else if((findtext(message, saymyname_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("[owner.name]!") //"Unknown!" + next_command = world.time + cooldown_meme + + //KNOCK KNOCK + else if((findtext(message, knockknock_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("Who's there?") + next_command = world.time + cooldown_meme + + //STATE LAWS + else if((findtext(message, statelaws_words))) + for(var/mob/living/silicon/S in listeners) + S.statelaws(S.laws) + next_command = world.time + cooldown_stun + + //MOVE + else if((findtext(message, move_words))) + for(var/V in listeners) + var/mob/living/L = V + step(L, pick(cardinal)) + next_command = world.time + cooldown_meme + + //WALK + else if((findtext(message, walk_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.m_intent != "walk") + L.m_intent = "walk" + if(L.hud_used) + L.hud_used.move_intent.icon_state = "walking" + next_command = world.time + cooldown_meme + + //RUN + else if((findtext(message, run_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.m_intent != "run") + L.m_intent = "run" + if(L.hud_used) + L.hud_used.move_intent.icon_state = "running" + next_command = world.time + cooldown_meme + + //HELP INTENT + else if((findtext(message, helpintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_HELP) + next_command = world.time + cooldown_meme + + //DISARM INTENT + else if((findtext(message, disarmintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_DISARM) + next_command = world.time + cooldown_meme + + //GRAB INTENT + else if((findtext(message, grabintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_GRAB) + next_command = world.time + cooldown_meme + + //HARM INTENT + else if((findtext(message, harmintent_words))) + for(var/mob/living/carbon/human/H in listeners) + H.a_intent_change(I_HARM) + next_command = world.time + cooldown_meme + + //THROW/CATCH + else if((findtext(message, throwmode_words))) + for(var/mob/living/carbon/C in listeners) + C.throw_mode_on() + next_command = world.time + cooldown_meme + + //FLIP + else if((findtext(message, flip_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("flip") + next_command = world.time + cooldown_meme + + //REST + else if((findtext(message, rest_words))) + for(var/V in listeners) + var/mob/living/L = V + if(!L.resting) + L.lay_down() + next_command = world.time + cooldown_meme + + //GET UP + else if((findtext(message, getup_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.resting) + L.lay_down() //aka get up + L.SetStunned(0) + L.SetWeakened(0) + L.SetParalysis(0) //i said get up i don't care if you're being tazed + next_command = world.time + cooldown_damage + + //SIT + else if((findtext(message, sit_words))) + for(var/V in listeners) + var/mob/living/L = V + for(var/obj/structure/stool/bed/chair/chair in get_turf(L)) + chair.buckle_mob(L) + break + next_command = world.time + cooldown_meme + + //STAND UP + else if((findtext(message, stand_words))) + for(var/V in listeners) + var/mob/living/L = V + if(L.buckled && istype(L.buckled, /obj/structure/stool/bed/chair)) + L.buckled.unbuckle_mob(L) + next_command = world.time + cooldown_meme + + //DANCE + else if((findtext(message, dance_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("dance") + next_command = world.time + cooldown_meme + + //JUMP + else if((findtext(message, jump_words))) + for(var/V in listeners) + var/mob/living/L = V + L.say("HOW HIGH?!!") + L.emote("jump") + next_command = world.time + cooldown_meme + + //SALUTE + else if((findtext(message, salute_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("salute") + next_command = world.time + cooldown_meme + + //PLAY DEAD + else if((findtext(message, deathgasp_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("deathgasp") + next_command = world.time + cooldown_meme + + //PLEASE CLAP + else if((findtext(message, clap_words))) + for(var/V in listeners) + var/mob/living/L = V + L.emote("clap") + next_command = world.time + cooldown_meme + + //HONK + else if((findtext(message, honk_words))) + spawn(25) + playsound(get_turf(owner), "sound/items/bikehorn.ogg", 300, 1) + if(owner.mind && owner.mind.assigned_role == "Clown") + for(var/mob/living/carbon/C in listeners) + C.slip(0,7 * power_multiplier) + next_command = world.time + cooldown_stun + else + next_command = world.time + cooldown_meme + + //RIGHT ROUND + else if((findtext(message, multispin_words))) + for(var/V in listeners) + var/mob/living/L = V + L.SpinAnimation(speed = 10, loops = 5) + next_command = world.time + cooldown_meme + + else + next_command = world.time + cooldown_none + + message_admins("[key_name_admin(owner)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") + log_game("[key_name(owner)] has said '[log_message]' with a Voice of God, affecting [english_list(listeners)], with a power multiplier of [power_multiplier].") \ No newline at end of file diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index f86cf41bcd0..73416045624 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -182,7 +182,7 @@ H.custom_pain("The pain in your [affected.name] is living hell!", 1) else if(istype(tool, /obj/item/weapon/reagent_containers/food/snacks/organ)) - to_chat(user, "[tool] was biten by someone! It's too damaged to use!") + to_chat(user, "[tool] was bitten by someone! It's too damaged to use!") return -1 ..() @@ -244,6 +244,8 @@ thing.forceMove(get_turf(target)) else user.put_in_hands(thing) + + target.update_icons() else user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", "You can't extract anything from [target]'s [parse_zone(target_zone)]!") diff --git a/code/modules/surgery/rig_removal.dm b/code/modules/surgery/rig_removal.dm new file mode 100644 index 00000000000..4e0403e43a4 --- /dev/null +++ b/code/modules/surgery/rig_removal.dm @@ -0,0 +1,58 @@ +//Procedures in this file: Unsealing a Rig. + +/datum/surgery/rigsuit + name = "Rig Unsealing" + steps = list(/datum/surgery_step/rigsuit) + possible_locs = list("chest") + +/datum/surgery/rigsuit/can_start(mob/user, mob/living/carbon/target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + var/obj/item/backitem = H.get_item_by_slot(slot_back) + if(istype(backitem,/obj/item/weapon/rig)) //Check if we have a rig to operate on + if(backitem.flags&NODROP) //Check if the rig is sealed, if not, we don't need to operate + return 1 + return 0 + +//Bay12 removal +/datum/surgery_step/rigsuit + name="Cut Seals" + allowed_tools = list( + /obj/item/weapon/weldingtool = 80, + /obj/item/weapon/circular_saw = 60, + /obj/item/weapon/gun/energy/plasmacutter = 100 + ) + + can_infect = 0 + blood_level = 0 + + time = 50 + +/datum/surgery_step/hardsuit/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + if(!istype(target)) + return 0 + if(istype(tool,/obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/welder = tool + if(!welder.isOn() || !welder.remove_fuel(1,user)) + return 0 + return (target_zone == "chest") && istype(target.back, /obj/item/weapon/rig) && (target.back.flags&NODROP) + +/datum/surgery_step/rigsuit/begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] starts cutting through the support systems of [target]'s [target.back] with \the [tool]." , \ + "You start cutting through the support systems of [target]'s [target.back] with \the [tool].") + ..() + +/datum/surgery_step/rigsuit/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + + var/obj/item/weapon/rig/rig = target.back + if(!istype(rig)) + return + rig.reset() + user.visible_message("[user] has cut through the support systems of [target]'s [rig] with \the [tool].", \ + "You have cut through the support systems of [target]'s [rig] with \the [tool].") + return 1 + +/datum/surgery_step/rigsuit/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user]'s [tool] can't quite seem to get through the metal...", \ + "Your [tool] can't quite seem to get through the metal. It's weakening, though - try again.") + return 0 diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index 2d99a538244..7558fd602ee 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -10,6 +10,7 @@ var/list/GPS_list = list() var/gpstag = "COM0" var/emped = 0 var/turf/locked_location + var/tracking = TRUE /obj/item/device/gps/New() ..() @@ -25,13 +26,32 @@ var/list/GPS_list = list() emped = 1 overlays -= "working" overlays += "emp" - spawn(300) - emped = 0 - overlays -= "emp" + addtimer(src, "reboot", 300) + +/obj/item/device/gps/proc/reboot() + emped = FALSE + overlays -= "emp" + overlays += "working" + +/obj/item/device/gps/AltClick(mob/user) + if(CanUseTopic(user, inventory_state) != STATUS_INTERACTIVE) + return 1 //user not valid to use gps + if(emped) + to_chat(user, "It's busted!") + if(tracking) + overlays -= "working" + to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.") + tracking = FALSE + else overlays += "working" + to_chat(user, "[src] is now tracking, and visible to other GPS devices.") + tracking = TRUE /obj/item/device/gps/attack_self(mob/user as mob) - + if(!tracking) + to_chat(user, "[src] is turned off. Use alt+click to toggle it back on.") + return + var/obj/item/device/gps/t = "" var/gps_window_height = 110 + GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show if(emped) @@ -49,8 +69,10 @@ var/list/GPS_list = list() var/tracked_gpstag = G.gpstag if(G.emped == 1) t += "
[tracked_gpstag]: ERROR" - else + else if(G.tracking) t += "
[tracked_gpstag]: [format_text(gps_area.name)] ([pos.x], [pos.y], [pos.z])" + else + continue var/datum/browser/popup = new(user, "GPS", name, 360, min(gps_window_height, 800)) popup.set_content(t) @@ -58,9 +80,14 @@ var/list/GPS_list = list() popup.open() /obj/item/device/gps/Topic(href, href_list) - ..() + if(..(state = inventory_state)) + return 1 + if(href_list["tag"] ) - var/a = input("Please enter desired tag.", name, gpstag) as text + var/a = input("Please enter desired tag.", name, gpstag) as text|null + if(!a || ..(state = inventory_state)) + return 1 + a = uppertext(sanitize(copytext(a, 1, 5))) if(src.loc == usr) gpstag = a @@ -84,4 +111,55 @@ var/list/GPS_list = list() icon_state = "gps-b" gpstag = "BORG0" desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams." - flags = NODROP \ No newline at end of file + flags = NODROP + +/obj/item/device/gps/internal + icon_state = null + flags = ABSTRACT + gpstag = "Eerie Signal" + desc = "Report to a coder immediately." + invisibility = INVISIBILITY_MAXIMUM + +/obj/item/device/gps/internal/mining + icon_state = "gps-m" + gpstag = "MINER" + desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life." + +/obj/item/device/gps/internal/base + gpstag = "NT_AUX" + desc = "A homing signal from Nanotrasen's mining base." + +/obj/item/device/gps/visible_debug + name = "visible GPS" + gpstag = "ADMIN" + desc = "This admin-spawn GPS unit leaves the coordinates visible \ + on any turf that it passes over, for debugging. Especially useful \ + for marking the area around the transition edges." + var/list/turf/tagged + +/obj/item/device/gps/visible_debug/New() + . = ..() + tagged = list() + fast_processing.Add(src) + +/obj/item/device/gps/visible_debug/process() + var/turf/T = get_turf(src) + if(T) + // I assume it's faster to color,tag and OR the turf in, rather + // then checking if its there + T.color = RANDOM_COLOUR + T.maptext = "[T.x],[T.y],[T.z]" + tagged |= T + +/obj/item/device/gps/visible_debug/proc/clear() + while(tagged.len) + var/turf/T = pop(tagged) + T.color = initial(T.color) + T.maptext = initial(T.maptext) + +/obj/item/device/gps/visible_debug/Destroy() + if(tagged) + clear() + tagged = null + fast_processing.Remove(src) + . = ..() \ No newline at end of file diff --git a/code/modules/tram/tram.dm b/code/modules/tram/tram.dm index 42b219bb92d..32b39bbe06f 100644 --- a/code/modules/tram/tram.dm +++ b/code/modules/tram/tram.dm @@ -255,7 +255,7 @@ if(prob(M.melee_damage_upper)) qdel(src) src.visible_message("[M] has [M.attacktext] [src]!") - M.attack_log += text("\[[time_stamp()]\] attacked [src.name]") + M.create_attack_log("attacked [src.name]") /obj/tram/bullet_act(var/obj/item/projectile/proj) if(prob(proj.damage)) diff --git a/code/modules/vehicle/atv.dm b/code/modules/vehicle/atv.dm index d4a843b80bf..a67310c8874 100644 --- a/code/modules/vehicle/atv.dm +++ b/code/modules/vehicle/atv.dm @@ -9,45 +9,39 @@ vehicle_move_delay = 1 var/static/image/atvcover = null - /obj/vehicle/atv/New() ..() if(!atvcover) atvcover = image("icons/vehicles/4wheeler.dmi", "4wheeler_north") atvcover.layer = MOB_LAYER + 0.1 - -obj/vehicle/atv/post_buckle_mob(mob/living/M) +/obj/vehicle/atv/post_buckle_mob(mob/living/M) if(buckled_mob) overlays += atvcover else overlays -= atvcover - /obj/vehicle/atv/handle_vehicle_layer() if(dir == SOUTH) layer = MOB_LAYER+0.1 else layer = OBJ_LAYER - //TURRETS! /obj/vehicle/atv/turret - var/obj/machinery/gun_turret/vehicle_turret/turret = null + var/obj/machinery/porta_turret/syndicate/vehicle_turret/turret = null - -/obj/machinery/gun_turret/vehicle_turret +/obj/machinery/porta_turret/syndicate/vehicle_turret name = "mounted turret" scan_range = 7 + emp_vulnerable = 1 density = 0 - /obj/vehicle/atv/turret/New() ..() turret = new(loc) //turret.base = src - /obj/vehicle/atv/turret/handle_vehicle_layer() if(dir == SOUTH) layer = MOB_LAYER+0.1 @@ -60,7 +54,6 @@ obj/vehicle/atv/post_buckle_mob(mob/living/M) else turret.layer = OBJ_LAYER - /obj/vehicle/atv/turret/handle_vehicle_offsets() ..() if(turret) diff --git a/code/world.dm b/code/world.dm index 08430bc0475..c33b41388f4 100644 --- a/code/world.dm +++ b/code/world.dm @@ -49,7 +49,6 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG . = ..() - plant_controller = new() // Create robolimbs for chargen. populate_robolimb_list() diff --git a/config/example/config.txt b/config/example/config.txt index 4a948a39c1c..5bcd469be87 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -325,3 +325,13 @@ DISABLE_SPACE_RUINS # and still qualify for re-entering the round. Defaults to 30. # Setting this to 0 will disable the penalty period #ROUND_ABANDON_PENALTY_PERIOD 30 + +## Hub address for tracking stats +## example: Hubmakerckey.Hubname +#MEDAL_HUB_ADDRESS + +## Password for the hub page +#MEDAL_HUB_PASSWORD + +## Uncomment this if you want to disable usage of emoji in OOC +#DISABLE_OOC_EMOJI \ No newline at end of file diff --git a/config/names/mime.txt b/config/names/mime.txt new file mode 100644 index 00000000000..520d3affce9 --- /dev/null +++ b/config/names/mime.txt @@ -0,0 +1,24 @@ +Invisible Man +Lemon Mime +Marcel +Marcel Mime +Mime +Mr Beret +Mr Mime +Mr Mute +Mute +Omerta +Oui Oui +Pantomime +Quiet +Quiet Riot +Silence +Silencio +Silent Knight +Silent Majority +Silent Night +Silent Sorrow +Transparency +Unspeakable +Untouchable +Wall Runner \ No newline at end of file diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index c5c0e8e93d2..970e94bb3b4 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -239,6 +239,7 @@ em {font-style: normal; font-weight: bold;} .playerreply {color: #8800bb; font-weight: bold;} .name { font-weight: bold;} .say {} +.yell { font-weight: bold;} .siliconsay {font-family: 'Courier New', Courier, monospace;} .deadsay {color: #5c00e6;} .radio {color: #008000;} @@ -323,8 +324,9 @@ h1.alert, h2.alert {color: #000000;} .cult {color: #800080; font-weight: bold; font-style: italic;} .cultspeech {color: #7F0000; font-style: italic;} .cultitalic {color: #960000; font-style: italic;} -.cultlarge {color: #960000; font-weight: bold; font-size: 3;} -.narsie {color: #960000; font-weight: bold; font-size: 15;} +.cultlarge {color: #960000; font-weight: bold; font-size: 120%;} +.narsie {color: #960000; font-weight: bold; font-size: 300%;} +.narsiesmall {color: #960000; font-weight: bold; font-size: 200%;} .interface {color: #330033;} .big {font-size: 150%;} .reallybig {font-size: 175%;} @@ -341,10 +343,10 @@ h1.alert, h2.alert {color: #000000;} .revennotice {color: #1d2953;} .revenboldnotice {color: #1d2953; font-weight: bold;} -.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 120%;} .revenminor {color: #823abb} .revenwarning {color: #760fbb; font-style: italic;} -.revendanger {color: #760fbb; font-weight: bold; font-size: 3;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 120%;} /* /vg/ */ .good {color: green;} @@ -358,7 +360,7 @@ h1.alert, h2.alert {color: #000000;} "} .memo {color: #638500; text-align: center;} -.memoedit {text-align: center; font-size: 2;} +.memoedit {text-align: center; font-size: 75%;} .connectionClosed, .fatalError {background: red; color: white; padding: 5px;} .connectionClosed.restored {background: green;} @@ -367,3 +369,11 @@ h1.alert, h2.alert {color: #000000;} /* HELPER CLASSES */ .text-normal {font-weight: normal; font-style: normal;} .hidden {display: none; visibility: hidden;} + +/* MEGAFAUNA */ +.colossus {color: #7F282A; font-size: 175%;} +.hierophant {color: #660099; font-weight: bold; font-size: 150%;} +.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;} + +/* EMOJI STUFF */ +.emoji {max-height: 16px; max-width: 16px} \ No newline at end of file diff --git a/goon/browserassets/html/browserOutput.html b/goon/browserassets/html/browserOutput.html index feaa5f0ecda..4bcd05f4cb0 100644 --- a/goon/browserassets/html/browserOutput.html +++ b/goon/browserassets/html/browserOutput.html @@ -16,6 +16,8 @@ + + @@ -29,8 +31,8 @@
Loading...

- If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
- If it still doesn't work, use the bug report button at the top right of the window. + If this takes longer than 10 seconds, it will automatically reload, multiple times if necessary.
+ If it still doesn't work, please adminhelp (F1) and tell us your operating system and Internet Explorer version.
diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js index 271d7872d46..538452dc472 100644 --- a/goon/browserassets/js/browserOutput.js +++ b/goon/browserassets/js/browserOutput.js @@ -62,7 +62,10 @@ var opts = { 'clientData': [], // List of macros in the 'hotkeymode' macro set. - 'macros': {} + 'macros': {}, + + // Emoji toggle + 'enableEmoji': true }; function outerHTML(el) { @@ -86,7 +89,7 @@ if (typeof String.prototype.trim !== 'function') { //Shit fucking piece of crap that doesn't work god fuckin damn it function linkify(text) { - var rex = /((?:'+$0+''; @@ -97,6 +100,32 @@ function linkify(text) { }); } +function emojiparse(el) { + + if ((typeof UNICODE_9_EMOJI === 'undefined') || (typeof twemoji === 'undefined')) { + return; //something didn't load right, probably IE8 + } + + var $el = $(el); + + var $emojiZone = $el.find(".emoji_enabled"); + + if ($emojiZone.length) { + $emojiZone.each(function () { + var html = $(this).html(); + html = html.replace(/\:(.*?)\:/g, function (match, p1, offset, s) { + var unicode_entity = UNICODE_9_EMOJI[p1]; + if (unicode_entity) { + return unicode_entity; + } + return match; + }); + html = $.parseHTML(twemoji.parse(html, {size: "svg", ext: ".svg"})); + $(this).html(html); + }); + } +} + // Colorizes the highlight spans function setHighlightColor(match) { match.style.background = opts.highlightColor @@ -127,6 +156,12 @@ function output(message, flag) { if (flag !== 'internal') opts.lastPang = Date.now(); + // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8. + // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b. + // Marvelous. + message = message.replace(/\+/g, "%20"); + message = decoder(message); + //The behemoth of filter-code (for Admin message filters) //Note: This is proooobably hella inefficient var filteredOut = false; @@ -215,7 +250,7 @@ function output(message, flag) { message = linkify(message); } - opts.messageCount++; + opts.messageCount++; //Actually append the message var entry = document.createElement('div'); @@ -227,6 +262,13 @@ function output(message, flag) { } entry.innerHTML = message; + + // emoji! + if (opts.enableEmoji) { + emojiparse(entry); + } + + $messages[0].appendChild(entry); //Actually do the snap @@ -240,6 +282,11 @@ function output(message, flag) { } } +function internalOutput(message, flag) +{ + output(escaper(message), flag); +} + //Runs a route within byond, client or server side. Consider this "ehjax" for byond. function runByond(uri) { window.location = uri; @@ -339,7 +386,7 @@ function ehjaxCallback(data) { $('#pingDot').css('color', '#'+hex); } else if (data == 'roundrestart') { opts.restarting = true; - output('
The connection has been closed because the server is restarting. Please wait while you automatically reconnect.
', 'internal'); + internalOutput('
The connection has been closed because the server is restarting. Please wait while you automatically reconnect.
', 'internal'); } else if (data == 'stopaudio') { $('.dectalk').remove(); } else { @@ -374,9 +421,9 @@ function ehjaxCallback(data) { changeMode(data.modeChange); } else if (data.firebug) { if (data.trigger) { - output('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); + internalOutput('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); } else { - output('Loading firebug console...', 'internal'); + internalOutput('Loading firebug console...', 'internal'); } var firebugEl = document.createElement('script'); firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; @@ -387,7 +434,7 @@ function ehjaxCallback(data) { message = ' '+ 'You hear a strange robotic voice...' + message; } - output(message, 'preventLink'); + internalOutput(message, 'preventLink'); } } } @@ -451,7 +498,7 @@ $(function() { if (!opts.noResponse) { //Only actually append a message if the previous ping didn't also fail (to prevent spam) opts.noResponse = true; opts.noResponseCount++; - output('
You are either AFK, experiencing lag or the connection has closed.
', 'internal'); + internalOutput('
You are either AFK, experiencing lag or the connection has closed.
', 'internal'); } } else if (opts.noResponse) { //Previous ping attempt failed ohno $('.connectionClosed[data-count="'+opts.noResponseCount+'"]:not(.restored)').addClass('restored').text('Your connection has been restored (probably)!'); @@ -490,18 +537,18 @@ $(function() { if (savedConfig.sfontSize) { $messages.css('font-size', savedConfig.sfontSize); - output('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); + internalOutput('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); } if (savedConfig.sfontType) { $messages.css('font-family', savedConfig.sfontType); - output('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal'); + internalOutput('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal'); } if (savedConfig.spingDisabled) { if (savedConfig.spingDisabled == 'true') { opts.pingDisabled = true; $('#ping').hide(); } - output('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); + internalOutput('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); } if (savedConfig.shighlightTerms) { var savedTerms = $.parseJSON(savedConfig.shighlightTerms); @@ -513,13 +560,13 @@ $(function() { } if (actualTerms) { actualTerms = actualTerms.substring(0, actualTerms.length - 2); - output('Loaded highlight strings of: ' + actualTerms+'', 'internal'); + internalOutput('Loaded highlight strings of: ' + actualTerms+'', 'internal'); opts.highlightTerms = savedTerms; } } if (savedConfig.shighlightColor) { opts.highlightColor = savedConfig.shighlightColor; - output('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); + internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); } (function() { @@ -606,14 +653,14 @@ $(function() { } e.preventDefault() - + var k = e.which; var command; // Command to execute through winset. // Hardcoded because else there would be no feedback message. if (k == 113) { // F2 runByond('byond://winset?screenshot=auto'); - output('Screenshot taken', 'internal'); + internalOutput('Screenshot taken', 'internal'); } var c = ""; @@ -747,7 +794,7 @@ $(function() { fontSize = fontSize - 1 + 'px'; $messages.css({'font-size': fontSize}); setCookie('fontsize', fontSize, 365); - output('Font size set to '+fontSize+'', 'internal'); + internalOutput('Font size set to '+fontSize+'', 'internal'); }); $('#increaseFont').click(function(e) { @@ -755,7 +802,7 @@ $(function() { fontSize = fontSize + 1 + 'px'; $messages.css({'font-size': fontSize}); setCookie('fontsize', fontSize, 365); - output('Font size set to '+fontSize+'', 'internal'); + internalOutput('Font size set to '+fontSize+'', 'internal'); }); $('#chooseFont').click(function(e) { @@ -821,7 +868,7 @@ $(function() { $('#highlightTerm').click(function(e) { if(!($().mark)) { - output('Highlighting is disabled. You are probably using Internet Explorer 8 and need to update.', 'internal'); + internalOutput('Highlighting is disabled. You are probably using Internet Explorer 8 and need to update.', 'internal'); return; } if ($('.popup .highlightTerm').is(':visible')) {return;} diff --git a/goon/browserassets/js/twemoji.min.js b/goon/browserassets/js/twemoji.min.js new file mode 100644 index 00000000000..b6f0f3eda50 --- /dev/null +++ b/goon/browserassets/js/twemoji.min.js @@ -0,0 +1,2 @@ +/*! Copyright Twitter Inc. and other contributors. Licensed under MIT */ +var twemoji=function(){"use strict";var twemoji={base:"https://twemoji.maxcdn.com/2/",ext:".png",size:"72x72",className:"emoji",convert:{fromCodePoint:fromCodePoint,toCodePoint:toCodePoint},onerror:function onerror(){if(this.parentNode){this.parentNode.replaceChild(createText(this.alt),this)}},parse:parse,replace:replace,test:test},escaper={"&":"&","<":"<",">":">","'":"'",'"':"""},re=/\ud83d[\udc68-\udc69](?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92])|(?:\ud83c[\udfcb\udfcc]|\ud83d\udd75|\u26f9)(?:\ufe0f|\ud83c[\udffb-\udfff])\u200d[\u2640\u2642]\ufe0f|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd37-\udd39\udd3d\udd3e])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|(?:[\u0023\u002a\u0030-\u0039])\ufe0f?\u20e3|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd18-\udd1c\udd1e\udd26\udd30\udd33-\udd39\udd3d\udd3e]|[\u270a\u270b])(?:\ud83c[\udffb-\udfff]|)|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud800\udc00|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a-\udc6d\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\udeeb\udeec\udef4-\udef6]|\ud83e[\udd10-\udd17\udd1d\udd20-\udd25\udd27\udd3a\udd3c\udd40-\udd45\udd47-\udd4b\udd50-\udd5e\udd80-\udd91\uddc0]|[\u23e9-\u23ec\u23f0\u23f3\u2640\u2642\u2695\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a]|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u00a9\u00ae\u203c\u2049\u2122\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2694\u2696\u2697\u2699\u269b\u269c\u26a0\u26a1\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))/g,UFE0Fg=/\uFE0F/g,U200D=String.fromCharCode(8205),rescaper=/[&<>'"]/g,shouldntBeParsed=/IFRAME|NOFRAMES|NOSCRIPT|SCRIPT|SELECT|STYLE|TEXTAREA|[a-z]/,fromCharCode=String.fromCharCode;return twemoji;function createText(text){return document.createTextNode(text)}function escapeHTML(s){return s.replace(rescaper,replacer)}function defaultImageSrcGenerator(icon,options){return"".concat(options.base,options.size,"/",icon,options.ext)}function grabAllTextNodes(node,allText){var childNodes=node.childNodes,length=childNodes.length,subnode,nodeType;while(length--){subnode=childNodes[length];nodeType=subnode.nodeType;if(nodeType===3){allText.push(subnode)}else if(nodeType===1&&!shouldntBeParsed.test(subnode.nodeName)){grabAllTextNodes(subnode,allText)}}return allText}function grabTheRightIcon(rawText){return toCodePoint(rawText.indexOf(U200D)<0?rawText.replace(UFE0Fg,""):rawText)}function parseNode(node,options){var allText=grabAllTextNodes(node,[]),length=allText.length,attrib,attrname,modified,fragment,subnode,text,match,i,index,img,rawText,iconId,src;while(length--){modified=false;fragment=document.createDocumentFragment();subnode=allText[length];text=subnode.nodeValue;i=0;while(match=re.exec(text)){index=match.index;if(index!==i){fragment.appendChild(createText(text.slice(i,index)))}rawText=match[0];iconId=grabTheRightIcon(rawText);i=index+rawText.length;src=options.callback(iconId,options);if(src){img=new Image;img.onerror=options.onerror;img.setAttribute("draggable","false");attrib=options.attributes(rawText,iconId);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&!img.hasAttribute(attrname)){img.setAttribute(attrname,attrib[attrname])}}img.className=options.className;img.alt=rawText;img.src=src;modified=true;fragment.appendChild(img)}if(!img)fragment.appendChild(createText(rawText));img=null}if(modified){if(i")}return ret})}function replacer(m){return escaper[m]}function returnNull(){return null}function toSizeSquaredAsset(value){return typeof value==="number"?value+"x"+value:value}function fromCodePoint(codepoint){var code=typeof codepoint==="string"?parseInt(codepoint,16):codepoint;if(code<65536){return fromCharCode(code)}code-=65536;return fromCharCode(55296+(code>>10),56320+(code&1023))}function parse(what,how){if(!how||typeof how==="function"){how={callback:how}}return(typeof what==="string"?parseString:parseNode)(what,{callback:how.callback||defaultImageSrcGenerator,attributes:typeof how.attributes==="function"?how.attributes:returnNull,base:typeof how.base==="string"?how.base:twemoji.base,ext:how.ext||twemoji.ext,size:how.folder||toSizeSquaredAsset(how.size||twemoji.size),className:how.className||twemoji.className,onerror:how.onerror||twemoji.onerror})}function replace(text,callback){return String(text).replace(re,callback)}function test(text){re.lastIndex=0;var result=re.test(text);re.lastIndex=0;return result}function toCodePoint(unicodeSurrogates,sep){var r=[],c=0,p=0,i=0;while(i
+

10 February 2017

+

Fox McCloud updated:

+
    +
  • Fixes not being able to bloodcrawl in most sources of blood
  • +
  • Fixes slaughter demon whisper not working at all
  • +
  • Drying rack drying now properly uses NanoUI instead of a right-click verb
  • +
  • Fixes produce appearing stuck in a drying rack when it was empty
  • +
  • Fixes a few failed icon updates with the drying rack
  • +
+

KasparoVy, Krausus updated:

+
    +
  • Adds the colourblindness gene. It is eye-dependent, and can be transferred from person-to-person with the eye organ.
  • +
  • Colourblindness can be detected by the advanced medical scanner just like blindness and short-sightedness.
  • +
  • Vulpkanin and Tajara can now choose to be uniquely colourblind in exchange for fantastic darksight. The default option is colour vision but low darksight.
  • +
  • Selecting mechanical or mechanically assisted eyes at character creation grants full colour vision, but standard Human darksight. This overrides the colour vision preference.
  • +
  • Mechanical(ly assisted) internal organs such as hearts and eyes are now appropriately named, and have appropriate sprites.
  • +
  • Vulpkanin and Tajara monkey-forms (Wolpins and Farwas) are incurably colourblind but have excellent darksight as they get nearly the same organs as their greater forms.
  • +
  • Increases reliability of turning into a monkey.
  • +
  • Fixes a bug with changelings lesser-forming, transforming and humanforming into a different identity.
  • +
+

Markolie updated:

+
    +
  • Firelocks can now be constructed and deconstructed.
  • +
  • Firelocks no longer show a confirmation message when being opened.
  • +
  • Various map fixes (vents, scrubbers, firelocks and intercoms). Also removes the firelocks covering the windows in escape/cargo.
  • +
+

tigercat2000 updated:

+
    +
  • Ported Goonstation slash /vg/ lighting. Pretty.
  • +
+

uraniummeltdown updated:

+
    +
  • Quantum Pads are now buildable in R&D!
  • +
  • Quantum Pads, once built, can be linked to other Quantum Pads using a multitool. Using a Pad which has been linked will teleport everything on the sending pad to the linked pad!
  • +
  • Pads do not need to be linked in pairs: Pad A can lead to Pad B which can lead to pad C.
  • +
  • Upgrading a Quantum Pad will reduce the cooldown, charge-up time, and power consumption.
  • +
  • Quantum Pads require a bluespace crystal, a micro manipulator, a capacitor and a cable piece.
  • +
  • Events now scale better with population.
  • +
  • Enabled immovable rod, slaughter demon and morph events.
  • +
+ +

08 February 2017

+

Fox McCloud updated:

+
    +
  • Grinding wheat and other products produces the proper reagents again
  • +
+ +

07 February 2017

+

Fox MCCloud updated:

+
    +
  • Tank transfer valves have in-hand icons
  • +
  • Tank transfer valves with large tanks (ie: jetpacks) cannot fit in backpacks
  • +
+

Fox McCloud updated:

+
    +
  • fixes xeno eggs taking damgae from disablers
  • +
  • adjusts most botany plant reagents to have "plantmatter" as opposed to nutriment
  • +
  • Blumpkins now have plasma in them
  • +
  • Fixes plant grown diona not being allied with plants and vines
  • +
  • Water coolers now dispense cups when clicking on them with a free hand
  • +
  • reagent tank dispensing amount based on the container instead of the tank
  • +
  • Fixes beaker spilling when placing a beaker into an ice cream machine
  • +
  • Adds in 100,000 unit water tanks to cargo for 12 points
  • +
  • regular water tank cost reduced from 8 to 6 points
  • +
  • Monkey cubes in boxes no longer start off wrapped
  • +
  • All monkey cube boxes at cargo are the same price
  • +
  • Fixes Nymphs not being able to cross over top of hydroponics trays
  • +
  • Diona fertilizing and weed eating is handled by clicking on the tray as a nymph rather than verbs
  • +
+

KasparoVy updated:

+
    +
  • Storage implants are now checked for steal objective items.
  • +
+

Kyep updated:

+
    +
  • AI holograms now transfer between holopads as the AI moves around.
  • +
+

uraniummeltdown updated:

+
    +
  • Engineering and Science crates now have new sprites
  • +
  • Changelings can recall the memories of an absorb victim
  • +
  • Changelings will recall some speech of their absorb victims
  • +
  • You can now create floor tiles from minerals. Be careful around plasma and uranium floors though.
  • +
+ +

06 February 2017

+

Fox McCloud updated:

+
    +
  • Fixes traitor banana peels having no sprite
  • +
  • Stunprods are constructed with igniters instead of wirecutters
  • +
  • Stunprods will spark when you stun someone with them
  • +
  • Expands the amount of cryodorm pods
  • +
+

KasparoVy updated:

+
    +
  • IPC names with numbers now load correctly from SQL.
  • +
+

Kyep updated:

+
    +
  • Autoprocess cloners will no longer clone people who cryo and ghost out, or otherwise deliberately remove themselves from the round.
  • +
  • Dead miners in UO45 away mission are no longer naked.
  • +
  • ERT and SST shuttle consoles now require the appropriate access to use.
  • +
+

uraniummeltdown updated:

+
    +
  • You can interact with an ore box by using an advanced mining scanner on it.
  • +
  • Xenobiology Console is now constructible, board has been added to the Circuit Imprinter.
  • +
  • Plasmaman IAA/Lawyers now have a unique suit.
  • +
  • AI control beacons are a new item created from the exosuit fabricator. When installed into a mech, it allows AIs to jump to and from that mech freely. Note that malfunctioning AIs with the domination power unlocked will instead be forced to dominate the mech.
  • +
  • Changelings have a new default ability: Hivemind Link. This lets you bring a neck-grabbed victim into the hivemind for a few minutes. You can talk to your victims and perhaps persuade them to help you, give you intel, or even a PDA code. Victims in crit will be stabilized.
  • +
  • Added new AI core sprites from TG
  • +
  • Added Vox rad suit, bombsuit hood, paramedic EVA suit sprites from /vg/
  • +
  • You can click AI displays as an AI to change them
  • +
+ +

05 February 2017

+

Fethas updated:

+
    +
  • Brings unholy water in line with its description.
  • +
+

Fox McCloud and Core0verload updated:

+
    +
  • Dramatically overhauls the botany system; features more user friendly gene modification methods, more control over attributes and reagents in your plants, and more
  • +
  • Adds in drying rack for drying growns for smoking with rolled papers
  • +
  • Store spare seeds in the seed extractor
  • +
  • Adds in cloth; make clothing, satchels, backpacks, duffelbags and more.
  • +
  • Upgrading hydroponics trays impacts how quickly plants degrade
  • +
  • Bees slightly more effective at increasing plant yields
  • +
  • Overall growth rate of plants dramatically increased
  • +
  • Adds in the ability to construct bonfires with wooden logs; perfect for keeping you our your fellow spessman warm---forever
  • +
  • Adds in a few new bartender drinks and recipes, such as chocolate pudding, vanilla pudding, and pumpkin spice
  • +
  • Can now wear some flowers/ambrosia in your hair
  • +
  • Combining genes form different plants has unique effects (For instance, the battery gene with the recharging gene allows you to make insanely potent batteries)
  • +
  • Vines are now purely handled by the Kudzu plant
  • +
  • Botanists have been given morgue access
  • +
+

Ported by Markolie, developed by KorPhaeron and others from /tg/. The Hierophant was developed by ChangelingRain. updated:

+
    +
  • Megafauna and their rewards have been added to the code. These are not on the map yet.
  • +
  • Fireball is now a targeted spell instead of a dumbfire spell.
  • +
  • Most spells, wands and staffs now have unique spell sounds.
  • +
  • Added a new nullrod type, the "spellblade".
  • +
  • Added bows, arrows and quivers. Currently only available for admins.
  • +
  • Added cockroaches. Currently only available for admins.
  • +
  • Added support for BYOND medals. Currently disabled.
  • +
  • Added a number of Lavaland objects (flora, basalt, food and stacks). Currently only available for admins.
  • +
  • Earmuffs can now be produced in autolathes.
  • +
  • Syndicate gun turrets are now subtypes of regular turrets: this makes them controllable with Syndicate ID's and improves their targeting.
  • +
  • Diona and Shadow People now receive a warning when they're not exposed/exposed to light.
  • +
  • The sniper AP rounds that Nuke Ops can purchase now have a chance of dismembering limbs.
  • +
  • Shadow People can now switch their night vision properly.
  • +
  • Certain messages in chat weren't showing up in their proper (large) size, such as the Nar'Sie spawned message. This has been resolved.
  • +
+

uraniummeltdown updated:

+
    +
  • Supply ID skin is now selectable in the Agent ID and ID Computer
  • +
+ +

03 February 2017

+

DrunkDwarf updated:

+
    +
  • Set the Mr Chang's vending machine to be refillable
  • +
  • Added a Supply Crate to the Vending section of the Cargo Request Console for Chinese Refill Canisters
  • +
+ +

02 February 2017

+

Alexshreds updated:

+
    +
  • Deconstructing closets yields the proper amount of metal
  • +
+

Kyep updated:

+
    +
  • Using the 'summon narsie' rune as cult, when you don't have the objective to do so, is now punished by the cult's god. Just as using the 'call forth the slaughter' rune, when you don't have the objective to do that, is already punished.
  • +
+

uraniummeltdown updated:

+
    +
  • Engineering Cyborgs now have a digital copy of the station blueprints.
  • +
+ +

31 January 2017

+

Ar3nn updated:

+
    +
  • cursed cluwne mask now allows internals to be fed through it
  • +
+

FalseIncarnate updated:

+
    +
  • All requests consoles can print off a single-use, pre-tagged Shipping Package for sending a single item via disposals to a destination of your choosing.
  • +
  • Shipping Packages can be used to tag packages wrapped with wrapping paper, in case you don't have access to cargo's destination tagger.
  • +
  • Requests Consoles log the printer and destination of all shipping labels printed from that particular console. There currently is no way to clear your mailing history, so mail responsibly.
  • +
+

Fethas updated:

+
    +
  • Fixes a rune runtime.
  • +
+

FlattestGuitar updated:

+
    +
  • adds an admin-only laser carbine
  • +
+

uraniummeltdown updated:

+
    +
  • Your game window will now flash on receiving Admin PMs, being revived, and ghost roles. You can disable this in Game Preferences.
  • +
+ +

30 January 2017

+

Alexshreds updated:

+
    +
  • No more double traitor 241 Special
  • +
+ +

29 January 2017

+

uraniummeltdown updated:

+
    +
  • You can now take items directly out of a storage item in your backpack.
  • +
+ +

27 January 2017

+

Alffd updated:

+
    +
  • Adds missing hat and shoe sprites that were inadvertently deleted.
  • +
+

Fox McCloud updated:

+
    +
  • Adds in stungloves (inaccessible to players)
  • +
+

uraniummeltdown updated:

+
    +
  • Injecting a rainbow slime extract with blood will create a consciousness transference potion.
  • +
  • Injecting a metal slime extract with water will create 15 sheets of glass and 5 sheets of reinforced glass.
  • +
  • Slime potions now check for proximity.
  • +
+ +

26 January 2017

+

FalseIncarnate updated:

+
    +
  • Plasma dust can now be used to rig lights and power cells, like the plasma reagent, with explosive results.
  • +
+

Fethas updated:

+
    +
  • Adds two new holy weapon skins for people who belive in ghosts and worshipers of the silentfather.
  • +
+

FreeStylaLT updated:

+
    +
  • AI sat transport tubes are no longer misaligned
  • +
+ +

25 January 2017

+

FlattestGuitar updated:

+
    +
  • Fixes shadowlings thrall scaling
  • +
+

scrubmcnoob updated:

+
    +
  • Shadowling Thrall count now scales to a max of 25.
  • +
  • Shadowling Thralls lose lesser glare
  • +
+ +

23 January 2017

+

FalseIncarnate updated:

+
    +
  • Returns the ability to remove vacant soil with shovels and spades, and adds the ability to dig up plants in soil to remove them instantly.
  • +
+

Stratus updated:

+
    +
  • NT Enforcer .45 pistol.
  • +
  • .45 and 9mm rubber bullets.
  • +
  • New shotgun ammo boxes.
  • +
+ +

18 January 2017

+

AndriiYukhymchak updated:

+
    +
  • multitool can now be used to swap directions of TEG's circulator
  • +
+

Fethas updated:

+
    +
  • Adds in the check numbers proc to converting, I missed it from VG.
  • +
  • Removed a redundent sacrefice objective check AND fixed the sacrfice objective check so it actually PICKs on mode start.
  • +
  • changed the color of manfested ghost humans to grey...huehuehuehuehue(serously it helps tell them apart better).
  • +
  • mass convert objective now picks between 9 and 15 as a target instead of based on round pop..cuase 30 MIGHT be a bit much.
  • +
  • adds admin cult tools Bypass phase (missed this off vg) and cult mind speak(YOUR GOD IS DISPLEASED GIT GUD). Might be better in secret panel but it confuses me.
  • +
  • Removes errent invisaible animals from the narnar escape shuttle template.
  • +
+

KasparoVy updated:

+
    +
  • Characters with the obese disability are now fat beneath their clothes.
  • +
+

Markolie updated:

+
    +
  • Admin announcements are no longer sent to player in the lobby.
  • +
  • Regular announcements can now only be heard if you the player is alive, not deaf and in range of an enabled radio.
  • +
+ +

17 January 2017

+

Crazylemon64 updated:

+
    +
  • Joined Souls works now
  • +
  • Scribing the end rune now no longer is impossible
  • +
+

Krausus updated:

+
    +
  • Fixed the exciting new emoji breaking chat entirely for IE8 users. :clap:
  • +
+ +

16 January 2017

+

Alexshreds updated:

+
    +
  • Revenants can now breathe in space.
  • +
  • Can no longer exploit RCDs for metal
  • +
+

Krausus updated:

+
    +
  • You can now use pills and patches on people with full bellies.
  • +
  • The Randomized Character Slot option now actually works.
  • +
+ +

15 January 2017

+

Funce updated:

+
    +
  • dual-port air vents can now be unwrenched
  • +
+

TullyBurnalot updated:

+
    +
  • Broken and Burned bulbs are no longer forced on with every overload.
  • +
  • Only non-broken and non-burned bulbs actually break and spark on an overload.
  • +
  • Fixes a single syntax error in the Shadowling Ascendant descriptive text.
  • +
+ +

14 January 2017

+

Crazylemon64 updated:

+
    +
  • Bibles can now reveal runes as they did before
  • +
+

Krausus updated:

+
    +
  • Players will no longer be informed of what cult may or may not exist on round start.
  • +
+ +

13 January 2017

+

DarkPyrolord updated:

+
    +
  • Removes the joy mask
  • +
+

TullyBurnalot updated:

+
    +
  • Cyborg tools (and other non-droppable tools) cannot be transferred to an open, empty Display Case
  • +
  • Jobs receive links to SOP and their Department SOP at roundstart. Space Law and Legal SOP links added to Security members, Magistrate and IAAs
  • +
+

uraniummeltdown updated:

+
    +
  • You can see what sting you have equipped as changeling.
  • +
  • All species except IPCs can now be changelings and be affected by their genetic abilities.
  • +
  • Arm Blade can now pry open powered airlocks
  • +
  • Transformation Sting now costs 3 points and requires 50 chemicals
  • +
  • You can no longer transform people into Vox with Transformation Sting.
  • +
  • Removed Engorged Chemical Glands, Changelings now have the ability by default
  • +
+ +

12 January 2017

+

TullyBurnalot updated:

+
    +
  • Graffiti now have hidden (Admin-only) fingerprints added to them
  • +
+ +

11 January 2017

+

Crazylemon64 updated:

+
    +
  • Ghosts can now see if they're allowed to respawn or not at a glance
  • +
  • Cyborg sight modes are now actions, instead of items
  • +
  • Mining drones can now use meson sight again
  • +
  • It's no longer opposite day for the karma reminder preference
  • +
+

Lady Luck updated:

+
    +
  • office laptops are now traversable
  • +
+

Markolie updated:

+
    +
  • simple_animals now have an attack cooldown when attacking mechas.
  • +
+

uraniummeltdown updated:

+
    +
  • Atmos Console Boards now show in Computer Boards of Circuit Imprinter
  • +
+ +

10 January 2017

+

Crazylemon updated:

+
    +
  • Giant spiders now have their own role pref
  • +
+

Crazylemon64 updated:

+
    +
  • pAIs can now adjust their radios
  • +
  • pAIs can now more reliably hear nearby whispers
  • +
  • pAIs can now whisper while inside a PDA
  • +
  • pAIs can no longer change their icon from being dead, while dead
  • +
  • Non-respawnable players are no longer prompted to submit a pAI when the opportunity is available
  • +
  • Borg sight modules work again
  • +
+

Fox McCloud updated:

+
    +
  • different alert levels for how full you are from starving all the way to fat
  • +
  • There is now satiety and nutrition; being satisfied and full has a number of positive benefits; being unsatisfied and hungry has negative side effects
  • +
  • Some foods have vitamins in them which provide little nutrition, but greatly increase your satisfaction
  • +
  • Some food reagents have had their nutritional values tweaked
  • +
  • reagent numbers tweaked on most food items
  • +
  • Fixes the floral gun not properly working on Diona
  • +
+

TullyBurnalot updated:

+
    +
  • Wand of Death now reliably kills people by adding 300 Burn Damage. This includes self-casting
  • +
  • Minor flavour text visible on impact of target
  • +
  • pAI HUDs are now visual-only, restricting their access to editable records
  • +
+

pinatacolada updated:

+
    +
  • IV drips now have adjustable rates
  • +
+

uraniummeltdown updated:

+
    +
  • Mimes can now choose name on entry just like Clowns
  • +
  • Added many new costumes to the Autodrobe!
  • +
+ +

09 January 2017

+

Crazylemon64 updated:

+
    +
  • The operating table now checks for both either `lying` or `resting` - so surgery will work no matter what on unconscious people lying on your table.
  • +
+

Kyep updated:

+
    +
  • Antags should no longer get bounced to lobby at round start in certain rare situations.
  • +
+ +

07 January 2017

+

Markolie updated:

+
    +
  • False walls now block atmospherics, unless it's open.
  • +
+

06 January 2017

Crazylemon64 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index d800b0af963..4403a0c594d 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -3280,3 +3280,349 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Kyep: - bugfix: Mobs in vents no longer see vents/scrubbers as unwelded when they are welded, and vice versa. +2017-01-07: + Markolie: + - bugfix: False walls now block atmospherics, unless it's open. +2017-01-09: + Crazylemon64: + - tweak: The operating table now checks for both either `lying` or `resting` - so + surgery will work no matter what on unconscious people lying on your table. + Kyep: + - bugfix: Antags should no longer get bounced to lobby at round start in certain + rare situations. +2017-01-10: + Crazylemon: + - tweak: Giant spiders now have their own role pref + Crazylemon64: + - bugfix: pAIs can now adjust their radios + - bugfix: pAIs can now more reliably hear nearby whispers + - bugfix: pAIs can now whisper while inside a PDA + - bugfix: pAIs can no longer change their icon from being dead, while dead + - bugfix: Non-respawnable players are no longer prompted to submit a pAI when the + opportunity is available + - bugfix: Borg sight modules work again + Fox McCloud: + - rscadd: different alert levels for how full you are from starving all the way + to fat + - rscadd: There is now satiety and nutrition; being satisfied and full has a number + of positive benefits; being unsatisfied and hungry has negative side effects + - rscadd: Some foods have vitamins in them which provide little nutrition, but greatly + increase your satisfaction + - tweak: Some food reagents have had their nutritional values tweaked + - tweak: reagent numbers tweaked on most food items + - bugfix: Fixes the floral gun not properly working on Diona + TullyBurnalot: + - bugfix: Wand of Death now reliably kills people by adding 300 Burn Damage. This + includes self-casting + - rscadd: Minor flavour text visible on impact of target + - tweak: pAI HUDs are now visual-only, restricting their access to editable records + pinatacolada: + - tweak: IV drips now have adjustable rates + uraniummeltdown: + - rscadd: Mimes can now choose name on entry just like Clowns + - rscadd: Added many new costumes to the Autodrobe! +2017-01-11: + Crazylemon64: + - rscadd: Ghosts can now see if they're allowed to respawn or not at a glance + - rscadd: Cyborg sight modes are now actions, instead of items + - bugfix: Mining drones can now use meson sight again + - bugfix: It's no longer opposite day for the karma reminder preference + Lady Luck: + - tweak: office laptops are now traversable + Markolie: + - bugfix: simple_animals now have an attack cooldown when attacking mechas. + uraniummeltdown: + - bugfix: Atmos Console Boards now show in Computer Boards of Circuit Imprinter +2017-01-12: + TullyBurnalot: + - bugfix: Graffiti now have hidden (Admin-only) fingerprints added to them +2017-01-13: + DarkPyrolord: + - rscdel: Removes the joy mask + TullyBurnalot: + - bugfix: Cyborg tools (and other non-droppable tools) cannot be transferred to + an open, empty Display Case + - rscadd: Jobs receive links to SOP and their Department SOP at roundstart. Space + Law and Legal SOP links added to Security members, Magistrate and IAAs + uraniummeltdown: + - bugfix: You can see what sting you have equipped as changeling. + - tweak: All species except IPCs can now be changelings and be affected by their + genetic abilities. + - tweak: Arm Blade can now pry open powered airlocks + - tweak: Transformation Sting now costs 3 points and requires 50 chemicals + - tweak: You can no longer transform people into Vox with Transformation Sting. + - rscdel: Removed Engorged Chemical Glands, Changelings now have the ability by + default +2017-01-14: + Crazylemon64: + - bugfix: Bibles can now reveal runes as they did before + Krausus: + - tweak: Players will no longer be informed of what cult may or may not exist on + round start. +2017-01-15: + Funce: + - bugfix: dual-port air vents can now be unwrenched + TullyBurnalot: + - bugfix: Broken and Burned bulbs are no longer forced on with every overload. + - tweak: Only non-broken and non-burned bulbs actually break and spark on an overload. + - bugfix: Fixes a single syntax error in the Shadowling Ascendant descriptive text. +2017-01-16: + Alexshreds: + - bugfix: Revenants can now breathe in space. + - bugfix: Can no longer exploit RCDs for metal + Krausus: + - bugfix: You can now use pills and patches on people with full bellies. + - bugfix: The Randomized Character Slot option now actually works. +2017-01-17: + Crazylemon64: + - bugfix: Joined Souls works now + - bugfix: Scribing the end rune now no longer is impossible + Krausus: + - bugfix: 'Fixed the exciting new emoji breaking chat entirely for IE8 users. :clap:' +2017-01-18: + AndriiYukhymchak: + - tweak: multitool can now be used to swap directions of TEG's circulator + Fethas: + - bugfix: Adds in the check numbers proc to converting, I missed it from VG. + - bugfix: Removed a redundent sacrefice objective check AND fixed the sacrfice objective + check so it actually PICKs on mode start. + - tweak: changed the color of manfested ghost humans to grey...huehuehuehuehue(serously + it helps tell them apart better). + - tweak: mass convert objective now picks between 9 and 15 as a target instead of + based on round pop..cuase 30 MIGHT be a bit much. + - rscadd: adds admin cult tools Bypass phase (missed this off vg) and cult mind + speak(YOUR GOD IS DISPLEASED GIT GUD). Might be better in secret panel but it + confuses me. + - tweak: Removes errent invisaible animals from the narnar escape shuttle template. + KasparoVy: + - bugfix: Characters with the obese disability are now fat beneath their clothes. + Markolie: + - tweak: Admin announcements are no longer sent to player in the lobby. + - tweak: Regular announcements can now only be heard if you the player is alive, + not deaf and in range of an enabled radio. +2017-01-23: + FalseIncarnate: + - rscadd: Returns the ability to remove vacant soil with shovels and spades, and + adds the ability to dig up plants in soil to remove them instantly. + Stratus: + - rscadd: NT Enforcer .45 pistol. + - rscadd: .45 and 9mm rubber bullets. + - imageadd: New shotgun ammo boxes. +2017-01-25: + FlattestGuitar: + - tweak: Fixes shadowlings thrall scaling + scrubmcnoob: + - tweak: Shadowling Thrall count now scales to a max of 25. + - tweak: Shadowling Thralls lose lesser glare +2017-01-26: + FalseIncarnate: + - tweak: Plasma dust can now be used to rig lights and power cells, like the plasma + reagent, with explosive results. + Fethas: + - rscadd: Adds two new holy weapon skins for people who belive in ghosts and worshipers + of the silentfather. + FreeStylaLT: + - tweak: AI sat transport tubes are no longer misaligned +2017-01-27: + Alffd: + - bugfix: Adds missing hat and shoe sprites that were inadvertently deleted. + Fox McCloud: + - rscadd: Adds in stungloves (inaccessible to players) + uraniummeltdown: + - rscadd: Injecting a rainbow slime extract with blood will create a consciousness + transference potion. + - rscadd: Injecting a metal slime extract with water will create 15 sheets of glass + and 5 sheets of reinforced glass. + - bugfix: Slime potions now check for proximity. +2017-01-29: + uraniummeltdown: + - tweak: You can now take items directly out of a storage item in your backpack. +2017-01-30: + Alexshreds: + - bugfix: No more double traitor 241 Special +2017-01-31: + Ar3nn: + - tweak: cursed cluwne mask now allows internals to be fed through it + FalseIncarnate: + - rscadd: All requests consoles can print off a single-use, pre-tagged Shipping + Package for sending a single item via disposals to a destination of your choosing. + - rscadd: Shipping Packages can be used to tag packages wrapped with wrapping paper, + in case you don't have access to cargo's destination tagger. + - rscadd: Requests Consoles log the printer and destination of all shipping labels + printed from that particular console. There currently is no way to clear your + mailing history, so mail responsibly. + Fethas: + - bugfix: Fixes a rune runtime. + FlattestGuitar: + - rscadd: adds an admin-only laser carbine + uraniummeltdown: + - rscadd: Your game window will now flash on receiving Admin PMs, being revived, + and ghost roles. You can disable this in Game Preferences. +2017-02-02: + Alexshreds: + - bugfix: Deconstructing closets yields the proper amount of metal + Kyep: + - tweak: Using the 'summon narsie' rune as cult, when you don't have the objective + to do so, is now punished by the cult's god. Just as using the 'call forth the + slaughter' rune, when you don't have the objective to do that, is already punished. + uraniummeltdown: + - rscadd: Engineering Cyborgs now have a digital copy of the station blueprints. +2017-02-03: + DrunkDwarf: + - tweak: Set the Mr Chang's vending machine to be refillable + - rscadd: Added a Supply Crate to the Vending section of the Cargo Request Console + for Chinese Refill Canisters +2017-02-05: + Fethas: + - tweak: Brings unholy water in line with its description. + Fox McCloud and Core0verload: + - rscadd: Dramatically overhauls the botany system; features more user friendly + gene modification methods, more control over attributes and reagents in your + plants, and more + - rscadd: Adds in drying rack for drying growns for smoking with rolled papers + - tweak: Store spare seeds in the seed extractor + - rscadd: Adds in cloth; make clothing, satchels, backpacks, duffelbags and more. + - tweak: Upgrading hydroponics trays impacts how quickly plants degrade + - tweak: Bees slightly more effective at increasing plant yields + - tweak: Overall growth rate of plants dramatically increased + - rscadd: Adds in the ability to construct bonfires with wooden logs; perfect for + keeping you our your fellow spessman warm---forever + - rscadd: Adds in a few new bartender drinks and recipes, such as chocolate pudding, + vanilla pudding, and pumpkin spice + - tweak: Can now wear some flowers/ambrosia in your hair + - tweak: Combining genes form different plants has unique effects (For instance, + the battery gene with the recharging gene allows you to make insanely potent + batteries) + - tweak: Vines are now purely handled by the Kudzu plant + - tweak: Botanists have been given morgue access + Ported by Markolie, developed by KorPhaeron and others from /tg/. The Hierophant was developed by ChangelingRain.: + - rscadd: Megafauna and their rewards have been added to the code. These are not + on the map yet. + - rscadd: Fireball is now a targeted spell instead of a dumbfire spell. + - rscadd: Most spells, wands and staffs now have unique spell sounds. + - rscadd: Added a new nullrod type, the "spellblade". + - rscadd: Added bows, arrows and quivers. Currently only available for admins. + - rscadd: Added cockroaches. Currently only available for admins. + - rscadd: Added support for BYOND medals. Currently disabled. + - rscadd: Added a number of Lavaland objects (flora, basalt, food and stacks). Currently + only available for admins. + - rscadd: Earmuffs can now be produced in autolathes. + - tweak: 'Syndicate gun turrets are now subtypes of regular turrets: this makes + them controllable with Syndicate ID''s and improves their targeting.' + - tweak: Diona and Shadow People now receive a warning when they're not exposed/exposed + to light. + - tweak: The sniper AP rounds that Nuke Ops can purchase now have a chance of dismembering + limbs. + - bugfix: Shadow People can now switch their night vision properly. + - bugfix: Certain messages in chat weren't showing up in their proper (large) size, + such as the Nar'Sie spawned message. This has been resolved. + uraniummeltdown: + - bugfix: Supply ID skin is now selectable in the Agent ID and ID Computer +2017-02-06: + Fox McCloud: + - bugfix: Fixes traitor banana peels having no sprite + - tweak: Stunprods are constructed with igniters instead of wirecutters + - tweak: Stunprods will spark when you stun someone with them + - rscadd: Expands the amount of cryodorm pods + KasparoVy: + - bugfix: IPC names with numbers now load correctly from SQL. + Kyep: + - bugfix: Autoprocess cloners will no longer clone people who cryo and ghost out, + or otherwise deliberately remove themselves from the round. + - tweak: Dead miners in UO45 away mission are no longer naked. + - bugfix: ERT and SST shuttle consoles now require the appropriate access to use. + uraniummeltdown: + - tweak: You can interact with an ore box by using an advanced mining scanner on + it. + - rscadd: Xenobiology Console is now constructible, board has been added to the + Circuit Imprinter. + - rscadd: Plasmaman IAA/Lawyers now have a unique suit. + - rscadd: AI control beacons are a new item created from the exosuit fabricator. + When installed into a mech, it allows AIs to jump to and from that mech freely. + Note that malfunctioning AIs with the domination power unlocked will instead + be forced to dominate the mech. + - rscadd: 'Changelings have a new default ability: Hivemind Link. This lets you + bring a neck-grabbed victim into the hivemind for a few minutes. You can talk + to your victims and perhaps persuade them to help you, give you intel, or even + a PDA code. Victims in crit will be stabilized.' + - rscadd: Added new AI core sprites from TG + - rscadd: Added Vox rad suit, bombsuit hood, paramedic EVA suit sprites from /vg/ + - tweak: You can click AI displays as an AI to change them +2017-02-07: + Fox MCCloud: + - tweak: Tank transfer valves have in-hand icons + - tweak: 'Tank transfer valves with large tanks (ie: jetpacks) cannot fit in backpacks' + Fox McCloud: + - bugfix: fixes xeno eggs taking damgae from disablers + - tweak: adjusts most botany plant reagents to have "plantmatter" as opposed to + nutriment + - tweak: Blumpkins now have plasma in them + - bugfix: Fixes plant grown diona not being allied with plants and vines + - rscadd: Water coolers now dispense cups when clicking on them with a free hand + - tweak: reagent tank dispensing amount based on the container instead of the tank + - bugfix: Fixes beaker spilling when placing a beaker into an ice cream machine + - rscadd: Adds in 100,000 unit water tanks to cargo for 12 points + - tweak: regular water tank cost reduced from 8 to 6 points + - tweak: Monkey cubes in boxes no longer start off wrapped + - tweak: All monkey cube boxes at cargo are the same price + - bugfix: Fixes Nymphs not being able to cross over top of hydroponics trays + - tweak: Diona fertilizing and weed eating is handled by clicking on the tray as + a nymph rather than verbs + KasparoVy: + - rscadd: Storage implants are now checked for steal objective items. + Kyep: + - tweak: AI holograms now transfer between holopads as the AI moves around. + uraniummeltdown: + - rscadd: Engineering and Science crates now have new sprites + - bugfix: Changelings can recall the memories of an absorb victim + - rscadd: Changelings will recall some speech of their absorb victims + - rscadd: You can now create floor tiles from minerals. Be careful around plasma + and uranium floors though. +2017-02-08: + Fox McCloud: + - bugfix: Grinding wheat and other products produces the proper reagents again +2017-02-10: + Fox McCloud: + - bugfix: Fixes not being able to bloodcrawl in most sources of blood + - bugfix: Fixes slaughter demon whisper not working at all + - tweak: Drying rack drying now properly uses NanoUI instead of a right-click verb + - bugfix: Fixes produce appearing stuck in a drying rack when it was empty + - bugfix: Fixes a few failed icon updates with the drying rack + KasparoVy, Krausus: + - rscadd: Adds the colourblindness gene. It is eye-dependent, and can be transferred + from person-to-person with the eye organ. + - rscadd: Colourblindness can be detected by the advanced medical scanner just like + blindness and short-sightedness. + - rscadd: Vulpkanin and Tajara can now choose to be uniquely colourblind in exchange + for fantastic darksight. The default option is colour vision but low darksight. + - rscadd: Selecting mechanical or mechanically assisted eyes at character creation + grants full colour vision, but standard Human darksight. This overrides the + colour vision preference. + - rscadd: Mechanical(ly assisted) internal organs such as hearts and eyes are now + appropriately named, and have appropriate sprites. + - tweak: Vulpkanin and Tajara monkey-forms (Wolpins and Farwas) are incurably colourblind + but have excellent darksight as they get nearly the same organs as their greater + forms. + - bugfix: Increases reliability of turning into a monkey. + - bugfix: Fixes a bug with changelings lesser-forming, transforming and humanforming + into a different identity. + Markolie: + - rscadd: Firelocks can now be constructed and deconstructed. + - tweak: Firelocks no longer show a confirmation message when being opened. + - tweak: Various map fixes (vents, scrubbers, firelocks and intercoms). Also removes + the firelocks covering the windows in escape/cargo. + tigercat2000: + - rscadd: Ported Goonstation slash /vg/ lighting. Pretty. + uraniummeltdown: + - rscadd: Quantum Pads are now buildable in R&D! + - rscadd: Quantum Pads, once built, can be linked to other Quantum Pads using a + multitool. Using a Pad which has been linked will teleport everything on the + sending pad to the linked pad! + - rscadd: 'Pads do not need to be linked in pairs: Pad A can lead to Pad B which + can lead to pad C.' + - rscadd: Upgrading a Quantum Pad will reduce the cooldown, charge-up time, and + power consumption. + - rscadd: Quantum Pads require a bluespace crystal, a micro manipulator, a capacitor + and a cable piece. + - tweak: Events now scale better with population. + - tweak: Enabled immovable rod, slaughter demon and morph events. diff --git a/html/changelogs/AutoChangeLog-pr-6350.yml b/html/changelogs/AutoChangeLog-pr-6350.yml new file mode 100644 index 00000000000..68f62df5826 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-6350.yml @@ -0,0 +1,5 @@ +author: "Markolie" +delete-after: True +changes: + - rscadd: "Ports over the remaining Lavaland loot items from /tg/ (most developed by KorPhaeron)." + - rscadd: "Refactors the kinetic accelerator to use modkits instead of subtypes: these unique mods (such as more range or shorter cooldown) can be purchased from the mining vendor or built by R&D or robotics (developed by KorPhaeron)." diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 4061ac44a96..9111297a266 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 657a2d43418..67da41362f8 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index 1c971f8d3f4..28e2fd791ff 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/effects/bubblegum.dmi b/icons/effects/bubblegum.dmi new file mode 100644 index 00000000000..a53dd7d563a Binary files /dev/null and b/icons/effects/bubblegum.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 95d8f86e425..a7962c37ec1 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/effects/lighting_overlay.dmi b/icons/effects/lighting_overlay.dmi deleted file mode 100644 index a5bee534b3d..00000000000 Binary files a/icons/effects/lighting_overlay.dmi and /dev/null differ diff --git a/icons/effects/lighting_overlay.png b/icons/effects/lighting_overlay.png new file mode 100644 index 00000000000..b317268b702 Binary files /dev/null and b/icons/effects/lighting_overlay.png differ diff --git a/icons/effects/spacevines.dmi b/icons/effects/spacevines.dmi index a140679d3d8..ee612f345e6 100644 Binary files a/icons/effects/spacevines.dmi and b/icons/effects/spacevines.dmi differ diff --git a/icons/effects/tomatodecal.dmi b/icons/effects/tomatodecal.dmi index d96401461d9..abbee9e0f2b 100644 Binary files a/icons/effects/tomatodecal.dmi and b/icons/effects/tomatodecal.dmi differ diff --git a/icons/goonstation/objects/hydroponics.dmi b/icons/goonstation/objects/hydroponics.dmi new file mode 100644 index 00000000000..5fb5d4ed8dd Binary files /dev/null and b/icons/goonstation/objects/hydroponics.dmi differ diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index 4c879d066b1..8146e8c6a86 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index fcdd79b3741..9bf1a315131 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 4b839a4bf66..db8191aed53 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 9cf930476d5..a05e783b307 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/clothing/paranormal_hardsuit.dmi b/icons/mob/clothing/paranormal_hardsuit.dmi new file mode 100644 index 00000000000..f06e81ab1e7 Binary files /dev/null and b/icons/mob/clothing/paranormal_hardsuit.dmi differ diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi index 3b75d6f2201..709a6e2f0da 100644 Binary files a/icons/mob/custom-synthetic.dmi and b/icons/mob/custom-synthetic.dmi differ diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index f74ebda9d34..97966c61dac 100644 Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index 85f9b1e25a6..1a4810c7fbc 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index b3af414cde5..93d81f6923e 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 74a0ddef98b..1de6fc4ac1d 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/human_races/r_def_vulpkanin.dmi b/icons/mob/human_races/r_def_vulpkanin.dmi new file mode 100644 index 00000000000..8c7f804ae03 Binary files /dev/null and b/icons/mob/human_races/r_def_vulpkanin.dmi differ diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index 3088c274007..cc5330db825 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index ea22f2728b1..359045c25e0 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 1003b7f7585..cecb8427e84 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 927a56bdaa3..fe42152fb5f 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/lavaland/96x96megafauna.dmi b/icons/mob/lavaland/96x96megafauna.dmi new file mode 100644 index 00000000000..e13419532df Binary files /dev/null and b/icons/mob/lavaland/96x96megafauna.dmi differ diff --git a/icons/mob/lavaland/dragon.dmi b/icons/mob/lavaland/dragon.dmi new file mode 100644 index 00000000000..7e44b775de8 Binary files /dev/null and b/icons/mob/lavaland/dragon.dmi differ diff --git a/icons/mob/lavaland/hierophant.dmi b/icons/mob/lavaland/hierophant.dmi new file mode 100644 index 00000000000..d05bc3bd62d Binary files /dev/null and b/icons/mob/lavaland/hierophant.dmi differ diff --git a/icons/mob/lavaland/lavaland_monsters.dmi b/icons/mob/lavaland/lavaland_monsters.dmi new file mode 100644 index 00000000000..8cf32385df3 Binary files /dev/null and b/icons/mob/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/lavaland/legion.dmi b/icons/mob/lavaland/legion.dmi new file mode 100644 index 00000000000..9cc19c4558f Binary files /dev/null and b/icons/mob/lavaland/legion.dmi differ diff --git a/icons/mob/lavaland/watcher.dmi b/icons/mob/lavaland/watcher.dmi new file mode 100644 index 00000000000..23960478b39 Binary files /dev/null and b/icons/mob/lavaland/watcher.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 23b8c76b7c2..8e37ab08a84 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 9cadad8834f..99359f5b079 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 1957a0aa1e0..8ca8456ea39 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi index d8a5beaf448..8e2965371c0 100644 Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 37d312d3133..49f209387bf 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/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index 46b11152ba7..c84122e9571 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi index 062c1b86db3..f30cb9facef 100644 Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ diff --git a/icons/mob/species/vox/head.dmi b/icons/mob/species/vox/head.dmi index 21ed6e38001..bca96cddb8f 100644 Binary files a/icons/mob/species/vox/head.dmi and b/icons/mob/species/vox/head.dmi differ diff --git a/icons/mob/species/vox/helmet.dmi b/icons/mob/species/vox/helmet.dmi index 05c31e1e1d6..869d98223cf 100644 Binary files a/icons/mob/species/vox/helmet.dmi and b/icons/mob/species/vox/helmet.dmi differ diff --git a/icons/mob/species/vox/suit.dmi b/icons/mob/species/vox/suit.dmi index 12be5447f34..311bc31623a 100644 Binary files a/icons/mob/species/vox/suit.dmi and b/icons/mob/species/vox/suit.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index de27e629ee8..d56a42ca099 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 74ef949dd10..f2c1c3a1311 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index a7db164c0fc..1fd541fbc7d 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/apiary_bees.dmi b/icons/obj/apiary_bees.dmi deleted file mode 100644 index df4cb0a0ac3..00000000000 Binary files a/icons/obj/apiary_bees.dmi and /dev/null differ diff --git a/icons/obj/biogenerator.dmi b/icons/obj/biogenerator.dmi index 471b99acfa6..02cf868a31f 100644 Binary files a/icons/obj/biogenerator.dmi and b/icons/obj/biogenerator.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 500f0f29141..9e0eb73a992 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 1006b5c5536..902bb2452ef 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi index 98d2257ff4f..28c03c8b574 100644 Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ diff --git a/icons/obj/cloning.dmi b/icons/obj/cloning.dmi index 8699f6edca8..69abac9ee4f 100644 Binary files a/icons/obj/cloning.dmi and b/icons/obj/cloning.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 938d810a612..fd2947d7d69 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 63af8386202..f12fcf3d86c 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index 84f4e2b4b70..8faec500e7b 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi index 1fefc0259e5..1fbcc049e6b 100644 Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index 2016309aaff..b98c786872a 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 08a739ba702..40f4c4c2b07 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 4380c3a34bb..27e4ffc2c61 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/doors/Doorfire.dmi b/icons/obj/doors/Doorfire.dmi index 6686844372a..1f3999b774e 100644 Binary files a/icons/obj/doors/Doorfire.dmi and b/icons/obj/doors/Doorfire.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index b1c332e6d75..730c5d5632c 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 4e6e07de79a..f08feb413f3 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/guns/magic.dmi b/icons/obj/guns/magic.dmi index 2f3fc52957a..b057d644918 100644 Binary files a/icons/obj/guns/magic.dmi and b/icons/obj/guns/magic.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index cd1eed09f02..84aa0490569 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/hacktool.dmi b/icons/obj/hacktool.dmi deleted file mode 100644 index fb5be360e0e..00000000000 Binary files a/icons/obj/hacktool.dmi and /dev/null differ diff --git a/icons/obj/harvest.dmi b/icons/obj/harvest.dmi deleted file mode 100644 index 0b7045cc64c..00000000000 Binary files a/icons/obj/harvest.dmi and /dev/null differ diff --git a/icons/obj/hydroponics.dmi b/icons/obj/hydroponics.dmi deleted file mode 100644 index 3683f3f6267..00000000000 Binary files a/icons/obj/hydroponics.dmi and /dev/null differ diff --git a/icons/obj/hydroponics/equipment.dmi b/icons/obj/hydroponics/equipment.dmi new file mode 100644 index 00000000000..a81ead53edc Binary files /dev/null and b/icons/obj/hydroponics/equipment.dmi differ diff --git a/icons/obj/hydroponics/growing.dmi b/icons/obj/hydroponics/growing.dmi new file mode 100644 index 00000000000..5b63f0553bd Binary files /dev/null and b/icons/obj/hydroponics/growing.dmi differ diff --git a/icons/obj/hydroponics/growing_flowers.dmi b/icons/obj/hydroponics/growing_flowers.dmi new file mode 100644 index 00000000000..e1f308c87b4 Binary files /dev/null and b/icons/obj/hydroponics/growing_flowers.dmi differ diff --git a/icons/obj/hydroponics/growing_fruits.dmi b/icons/obj/hydroponics/growing_fruits.dmi new file mode 100644 index 00000000000..ac8adc5a069 Binary files /dev/null and b/icons/obj/hydroponics/growing_fruits.dmi differ diff --git a/icons/obj/hydroponics/growing_mushrooms.dmi b/icons/obj/hydroponics/growing_mushrooms.dmi new file mode 100644 index 00000000000..eb4405bf8bf Binary files /dev/null and b/icons/obj/hydroponics/growing_mushrooms.dmi differ diff --git a/icons/obj/hydroponics/growing_vegetables.dmi b/icons/obj/hydroponics/growing_vegetables.dmi new file mode 100644 index 00000000000..070d3531a21 Binary files /dev/null and b/icons/obj/hydroponics/growing_vegetables.dmi differ diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi new file mode 100644 index 00000000000..0adedb879e9 Binary files /dev/null and b/icons/obj/hydroponics/harvest.dmi differ diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi new file mode 100644 index 00000000000..5e28a475cf3 Binary files /dev/null and b/icons/obj/hydroponics/seeds.dmi differ diff --git a/icons/obj/hydroponics_growing.dmi b/icons/obj/hydroponics_growing.dmi deleted file mode 100644 index 695a29b9951..00000000000 Binary files a/icons/obj/hydroponics_growing.dmi and /dev/null differ diff --git a/icons/obj/hydroponics_machines.dmi b/icons/obj/hydroponics_machines.dmi deleted file mode 100644 index cb3d548a6d9..00000000000 Binary files a/icons/obj/hydroponics_machines.dmi and /dev/null differ diff --git a/icons/obj/hydroponics_products.dmi b/icons/obj/hydroponics_products.dmi deleted file mode 100644 index 028bb4b9113..00000000000 Binary files a/icons/obj/hydroponics_products.dmi and /dev/null differ diff --git a/icons/obj/hydroponics_unused.dmi b/icons/obj/hydroponics_unused.dmi deleted file mode 100644 index b3a05b03861..00000000000 Binary files a/icons/obj/hydroponics_unused.dmi and /dev/null differ diff --git a/icons/obj/hydroponics_vines.dmi b/icons/obj/hydroponics_vines.dmi deleted file mode 100644 index cecca3058a0..00000000000 Binary files a/icons/obj/hydroponics_vines.dmi and /dev/null differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index 0d503c324e3..1e8b80b314e 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi index 301a990639e..fde65f1c949 100644 Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi new file mode 100644 index 00000000000..45927256e35 Binary files /dev/null and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/icons/obj/lavaland/ash_flora.dmi b/icons/obj/lavaland/ash_flora.dmi new file mode 100644 index 00000000000..d58541612d2 Binary files /dev/null and b/icons/obj/lavaland/ash_flora.dmi differ diff --git a/icons/obj/lavaland/dragonboat.dmi b/icons/obj/lavaland/dragonboat.dmi new file mode 100644 index 00000000000..13b6509fcd7 Binary files /dev/null and b/icons/obj/lavaland/dragonboat.dmi differ diff --git a/icons/obj/lavaland/spawners.dmi b/icons/obj/lavaland/spawners.dmi new file mode 100644 index 00000000000..42fdc988add Binary files /dev/null and b/icons/obj/lavaland/spawners.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 5404c91b3b9..81c5c39ddf8 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi index 779903709c9..06afc67979c 100644 Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi index ef7ea2ddac7..d6cb7a676c4 100644 Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index 6d5a5b70d41..0a269e0d8b7 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/narsie.dmi b/icons/obj/narsie.dmi index ac11a2730cb..55ab046eb42 100644 Binary files a/icons/obj/narsie.dmi and b/icons/obj/narsie.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index ea68e3dbdbd..c02603ecd25 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi index 850411d79e9..5977cd3cb66 100644 Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 5a780217109..316790998c5 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/rune.dmi b/icons/obj/rune.dmi index 901b7466d57..5df6a842ad5 100644 Binary files a/icons/obj/rune.dmi and b/icons/obj/rune.dmi differ diff --git a/icons/obj/seeds.dmi b/icons/obj/seeds.dmi deleted file mode 100644 index 2a8bac86a9d..00000000000 Binary files a/icons/obj/seeds.dmi and /dev/null differ diff --git a/icons/obj/seeds_OLD.dmi b/icons/obj/seeds_OLD.dmi deleted file mode 100644 index b090ba6cbe9..00000000000 Binary files a/icons/obj/seeds_OLD.dmi and /dev/null differ diff --git a/icons/obj/stock_parts.dmi b/icons/obj/stock_parts.dmi index 47600bcfba3..8fe85835d64 100644 Binary files a/icons/obj/stock_parts.dmi and b/icons/obj/stock_parts.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index bd09b38dcd4..bd45f38cd00 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 88161a20b5c..2f055a0c491 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/telescience.dmi b/icons/obj/telescience.dmi index b692f566df1..dfc41198913 100644 Binary files a/icons/obj/telescience.dmi and b/icons/obj/telescience.dmi differ diff --git a/icons/obj/terminals.dmi b/icons/obj/terminals.dmi index 16d8bbcae7a..45baaf3f7ba 100644 Binary files a/icons/obj/terminals.dmi and b/icons/obj/terminals.dmi differ diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi new file mode 100644 index 00000000000..3de478d728d Binary files /dev/null and b/icons/obj/tiles.dmi differ diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi index 63515f5b2e5..2f528c44c77 100644 Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 1164d5c5363..83276e5ec57 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index c51a531b2f8..8cf3b48100c 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 86a544fa278..66bd1893196 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/icons/turf/floors/ash.dmi b/icons/turf/floors/ash.dmi new file mode 100644 index 00000000000..718cd120194 Binary files /dev/null and b/icons/turf/floors/ash.dmi differ diff --git a/icons/turf/floors/lava.dmi b/icons/turf/floors/lava.dmi index 1017a60b73a..29afb2cc869 100644 Binary files a/icons/turf/floors/lava.dmi and b/icons/turf/floors/lava.dmi differ diff --git a/icons/turf/walls/hierophant_wall.dmi b/icons/turf/walls/hierophant_wall.dmi new file mode 100644 index 00000000000..8482970eaf0 Binary files /dev/null and b/icons/turf/walls/hierophant_wall.dmi differ diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl index 51b74a12fda..e88db47456a 100644 --- a/nano/templates/adv_med.tmpl +++ b/nano/templates/adv_med.tmpl @@ -52,10 +52,13 @@ Used In File(s): \code\game\machinery\adv_med.dm Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
    {{/if}} {{if data.occupant.blind}} - Pupils unresponsive.
    + Cataracts detected.
    + {{/if}} + {{if data.occupant.colourblind}} + Photoreceptor abnormalities detected.
    {{/if}} {{if data.occupant.nearsighted}} - Retinal misalignment detected
    + Retinal misalignment detected.
    {{/if}}
    diff --git a/nano/templates/request_console.tmpl b/nano/templates/request_console.tmpl index 1005f583ec8..aaa8726f50a 100644 --- a/nano/templates/request_console.tmpl +++ b/nano/templates/request_console.tmpl @@ -3,8 +3,8 @@ Title: Request Console Used In File(s): \code\game\machinery\requests_console.dm #define RCS_MAINMENU 0 // Main men -#define RCS_RQASSIST 1 // Request supplies -#define RCS_RQSUPPLY 2 // Request assistance +#define RCS_RQSUPPLY 1 // Request supplies +#define RCS_RQASSIST 2 // Request assistance #define RCS_SENDINFO 3 // Relay information #define RCS_SENTPASS 4 // Message sent successfully #define RCS_SENTFAIL 5 // Message sent unsuccessfully @@ -102,6 +102,33 @@ Used In File(s): \code\game\machinery\requests_console.dm {{:helper.link('Announce', 'signal', { 'sendAnnouncement' : 1 }, (data.announceAuth && data.message) ? null : 'disabled' )}} {{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
+{{else data.screen == 9}} +

Print a Shipping Label.

+
+
Destination: {{:data.shipDest}}
+
Validated by: {{:data.msgVerified}}
+
{{:helper.link('Print Label', null, { 'printLabel' : 1 })}}
+
+ + {{for data.ship_dept}} + + + + + {{empty}} + + {{/for}} +
{{:value}} -
{{:helper.link('Select', null, { 'shipSelect' : value })}}
There are no available shipping destinations.

+
{{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
+{{else data.screen == 10}} +
+ {{for data.shipping_log}} +
{{:value}}
+ {{empty}} +
No shipping labels have been printed.
+ {{/for}} +
+
{{:helper.link('Back', 'arrow-left', { 'setScreen' : 0 })}}
{{else}} {{if data.newmessagepriority == 1}}
There are new messages
@@ -114,9 +141,12 @@ Used In File(s): \code\game\machinery\requests_console.dm
{{:helper.link('Request Supplies', 'gear', { 'setScreen' : 2 })}}
{{:helper.link('Relay Anonymous Information', 'gear', { 'setScreen' : 3})}}

+
{{:helper.link('Print Shipping Label', 'gear', { 'setScreen' : 9})}}
+
{{:helper.link('View Shipping Logs', 'gear', { 'setScreen' : 10})}}
+
{{if data.announcementConsole}}
{{:helper.link('Send Station-wide Announcement', 'signal', { 'setScreen' : 8})}}

{{/if}} -
{{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-on', { 'toggleSilent' : 1})}}
+
{{:helper.link(data.silent ? 'Speaker OFF' : 'Speaker ON', data.silent ? 'volume-off' : 'volume-up', { 'toggleSilent' : 1})}}
{{/if}} \ No newline at end of file diff --git a/nano/templates/smartfridge.tmpl b/nano/templates/smartfridge.tmpl index 873487454dc..3c59892486d 100644 --- a/nano/templates/smartfridge.tmpl +++ b/nano/templates/smartfridge.tmpl @@ -10,6 +10,16 @@ {{/if}}
+
+ {{if data.can_dry}} +
+ Drying: +
+
+ {{:helper.link('On', 'power-off', {'dryingOn' : 1}, data.drying ? 'selected' : null)}}{{:helper.link('Off', 'close', {'dryingOff' : 1}, data.drying ? null : 'selected')}} +
+ {{/if}} +
{{if data.contents}} {{for data.contents}} diff --git a/nano/templates/turret_control.tmpl b/nano/templates/turret_control.tmpl index 25e3c2a592c..50f733ea80f 100644 --- a/nano/templates/turret_control.tmpl +++ b/nano/templates/turret_control.tmpl @@ -23,7 +23,7 @@
{{/if}} - {{if data.is_lethal}} + {{if data.lethal_control}}
Lethal Mode: diff --git a/paradise.dme b/paradise.dme index 3012b8503cd..15ba163910a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -29,8 +29,10 @@ #include "code\__DEFINES\genetics.dm" #include "code\__DEFINES\hud.dm" #include "code\__DEFINES\hydroponics.dm" +#include "code\__DEFINES\inventory.dm" #include "code\__DEFINES\is_helpers.dm" #include "code\__DEFINES\language.dm" +#include "code\__DEFINES\layers.dm" #include "code\__DEFINES\lighting.dm" #include "code\__DEFINES\machines.dm" #include "code\__DEFINES\math.dm" @@ -40,6 +42,7 @@ #include "code\__DEFINES\preferences.dm" #include "code\__DEFINES\process_scheduler.dm" #include "code\__DEFINES\qdel.dm" +#include "code\__DEFINES\reagents.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\rolebans.dm" #include "code\__DEFINES\sight.dm" @@ -87,7 +90,6 @@ #include "code\_globalvars\lists\names.dm" #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\reagents.dm" -#include "code\_onclick\_defines.dm" #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" #include "code\_onclick\click.dm" @@ -304,6 +306,7 @@ #include "code\datums\spells\mind_transfer.dm" #include "code\datums\spells\projectile.dm" #include "code\datums\spells\rathens.dm" +#include "code\datums\spells\shapeshift.dm" #include "code\datums\spells\summonitem.dm" #include "code\datums\spells\touch_attacks.dm" #include "code\datums\spells\trigger.dm" @@ -393,7 +396,6 @@ #include "code\game\gamemodes\changeling\powers\epinephrine.dm" #include "code\game\gamemodes\changeling\powers\fakedeath.dm" #include "code\game\gamemodes\changeling\powers\fleshmend.dm" -#include "code\game\gamemodes\changeling\powers\glands.dm" #include "code\game\gamemodes\changeling\powers\headcrab.dm" #include "code\game\gamemodes\changeling\powers\hivemind.dm" #include "code\game\gamemodes\changeling\powers\humanform.dm" @@ -491,7 +493,6 @@ #include "code\game\machinery\atmo_control.dm" #include "code\game\machinery\autolathe.dm" #include "code\game\machinery\Beacon.dm" -#include "code\game\machinery\biogenerator.dm" #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" #include "code\game\machinery\chiller.dm" @@ -526,12 +527,12 @@ #include "code\game\machinery\portable_tag_turret.dm" #include "code\game\machinery\portable_turret.dm" #include "code\game\machinery\programmable_unloader.dm" +#include "code\game\machinery\quantum_pad.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" #include "code\game\machinery\recycler.dm" #include "code\game\machinery\requests_console.dm" #include "code\game\machinery\robot_fabricator.dm" -#include "code\game\machinery\seed_extractor.dm" #include "code\game\machinery\shieldgen.dm" #include "code\game\machinery\Sleeper.dm" #include "code\game\machinery\slotmachine.dm" @@ -545,7 +546,6 @@ #include "code\game\machinery\transformer.dm" #include "code\game\machinery\turntable.dm" #include "code\game\machinery\turret_control.dm" -#include "code\game\machinery\turrets.dm" #include "code\game\machinery\vending.dm" #include "code\game\machinery\washing_machine.dm" #include "code\game\machinery\wishgranter.dm" @@ -711,7 +711,6 @@ #include "code\game\objects\items\devices\autopsy.dm" #include "code\game\objects\items\devices\camera_bug.dm" #include "code\game\objects\items\devices\chameleonproj.dm" -#include "code\game\objects\items\devices\debugger.dm" #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\floor_painter.dm" @@ -1169,6 +1168,7 @@ #include "code\modules\clothing\spacesuits\syndi.dm" #include "code\modules\clothing\spacesuits\void.dm" #include "code\modules\clothing\spacesuits\rig\rig.dm" +#include "code\modules\clothing\spacesuits\rig\rig_armormod.dm" #include "code\modules\clothing\spacesuits\rig\rig_attackby.dm" #include "code\modules\clothing\spacesuits\rig\rig_pieces.dm" #include "code\modules\clothing\spacesuits\rig\rig_verbs.dm" @@ -1364,30 +1364,51 @@ #include "code\modules\garbage_collection\gc_testing.dm" #include "code\modules\holiday\christmas.dm" #include "code\modules\holiday\holiday.dm" +#include "code\modules\hydroponics\biogenerator.dm" +#include "code\modules\hydroponics\gene_modder.dm" #include "code\modules\hydroponics\grown.dm" -#include "code\modules\hydroponics\grown_inedible.dm" -#include "code\modules\hydroponics\grown_predefined.dm" -#include "code\modules\hydroponics\hydro_reagents.dm" -#include "code\modules\hydroponics\seed.dm" -#include "code\modules\hydroponics\seed_controller.dm" -#include "code\modules\hydroponics\seed_datums.dm" -#include "code\modules\hydroponics\seed_machines.dm" -#include "code\modules\hydroponics\seed_mobs.dm" -#include "code\modules\hydroponics\seed_packets.dm" -#include "code\modules\hydroponics\seed_storage.dm" +#include "code\modules\hydroponics\growninedible.dm" +#include "code\modules\hydroponics\hydroitemdefines.dm" +#include "code\modules\hydroponics\hydroponics.dm" +#include "code\modules\hydroponics\plant_genes.dm" +#include "code\modules\hydroponics\sample.dm" +#include "code\modules\hydroponics\seed_extractor.dm" +#include "code\modules\hydroponics\seeds.dm" #include "code\modules\hydroponics\beekeeping\beebox.dm" #include "code\modules\hydroponics\beekeeping\beekeeper_suit.dm" #include "code\modules\hydroponics\beekeeping\honey_frame.dm" #include "code\modules\hydroponics\beekeeping\honeycomb.dm" -#include "code\modules\hydroponics\spreading\spreading.dm" -#include "code\modules\hydroponics\spreading\spreading_growth.dm" -#include "code\modules\hydroponics\spreading\spreading_response.dm" -#include "code\modules\hydroponics\trays\tray.dm" -#include "code\modules\hydroponics\trays\tray_process.dm" -#include "code\modules\hydroponics\trays\tray_reagents.dm" -#include "code\modules\hydroponics\trays\tray_soil.dm" -#include "code\modules\hydroponics\trays\tray_tools.dm" -#include "code\modules\hydroponics\trays\tray_update_icons.dm" +#include "code\modules\hydroponics\grown\ambrosia.dm" +#include "code\modules\hydroponics\grown\apple.dm" +#include "code\modules\hydroponics\grown\banana.dm" +#include "code\modules\hydroponics\grown\beans.dm" +#include "code\modules\hydroponics\grown\berries.dm" +#include "code\modules\hydroponics\grown\cannabis.dm" +#include "code\modules\hydroponics\grown\cereals.dm" +#include "code\modules\hydroponics\grown\chili.dm" +#include "code\modules\hydroponics\grown\citrus.dm" +#include "code\modules\hydroponics\grown\cocoa_vanilla.dm" +#include "code\modules\hydroponics\grown\corn.dm" +#include "code\modules\hydroponics\grown\eggplant.dm" +#include "code\modules\hydroponics\grown\flowers.dm" +#include "code\modules\hydroponics\grown\grass_carpet.dm" +#include "code\modules\hydroponics\grown\herbals.dm" +#include "code\modules\hydroponics\grown\kudzu.dm" +#include "code\modules\hydroponics\grown\melon.dm" +#include "code\modules\hydroponics\grown\misc.dm" +#include "code\modules\hydroponics\grown\mushrooms.dm" +#include "code\modules\hydroponics\grown\nettle.dm" +#include "code\modules\hydroponics\grown\nymph.dm" +#include "code\modules\hydroponics\grown\peanut.dm" +#include "code\modules\hydroponics\grown\potato.dm" +#include "code\modules\hydroponics\grown\pumpkin.dm" +#include "code\modules\hydroponics\grown\random.dm" +#include "code\modules\hydroponics\grown\replicapod.dm" +#include "code\modules\hydroponics\grown\root.dm" +#include "code\modules\hydroponics\grown\tea_coffee.dm" +#include "code\modules\hydroponics\grown\tobacco.dm" +#include "code\modules\hydroponics\grown\tomato.dm" +#include "code\modules\hydroponics\grown\towercap.dm" #include "code\modules\karma\karma.dm" #include "code\modules\library\admin.dm" #include "code\modules\library\lib_items.dm" @@ -1397,12 +1418,14 @@ #include "code\modules\library\computers\checkout.dm" #include "code\modules\library\computers\public.dm" #include "code\modules\lighting\__lighting_docs.dm" -#include "code\modules\lighting\light_source.dm" +#include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm" +#include "code\modules\lighting\lighting_corner.dm" #include "code\modules\lighting\lighting_overlay.dm" -#include "code\modules\lighting\lighting_process.dm" -#include "code\modules\lighting\lighting_system.dm" +#include "code\modules\lighting\lighting_setup.dm" +#include "code\modules\lighting\lighting_source.dm" #include "code\modules\lighting\lighting_turf.dm" +#include "code\modules\lighting\~lighting_undefs.dm" #include "code\modules\logic\converter.dm" #include "code\modules\logic\dual_input.dm" #include "code\modules\logic\logic_base.dm" @@ -1433,6 +1456,14 @@ #include "code\modules\mining\laborcamp\laborminerals.dm" #include "code\modules\mining\laborcamp\laborshuttle.dm" #include "code\modules\mining\laborcamp\laborstacker.dm" +#include "code\modules\mining\lavaland\ash_flora.dm" +#include "code\modules\mining\lavaland\necropolis_chests.dm" +#include "code\modules\mining\lavaland\loot\ashdragon_loot.dm" +#include "code\modules\mining\lavaland\loot\bubblegum_loot.dm" +#include "code\modules\mining\lavaland\loot\colossus_loot.dm" +#include "code\modules\mining\lavaland\loot\hierophant_loot.dm" +#include "code\modules\mining\lavaland\loot\legion_loot.dm" +#include "code\modules\mining\lavaland\loot\tendril_loot.dm" #include "code\modules\mob\abilities.dm" #include "code\modules\mob\death.dm" #include "code\modules\mob\emote.dm" @@ -1541,6 +1572,7 @@ #include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\npcs.dm" #include "code\modules\mob\living\carbon\human\say.dm" +#include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\whisper.dm" #include "code\modules\mob\living\carbon\human\interactive\functions.dm" @@ -1610,6 +1642,7 @@ #include "code\modules\mob\living\silicon\robot\robot.dm" #include "code\modules\mob\living\silicon\robot\robot_damage.dm" #include "code\modules\mob\living\silicon\robot\robot_items.dm" +#include "code\modules\mob\living\silicon\robot\robot_module_actions.dm" #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\update_status.dm" @@ -1642,6 +1675,7 @@ #include "code\modules\mob\living\simple_animal\bot\secbot.dm" #include "code\modules\mob\living\simple_animal\friendly\butterfly.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm" +#include "code\modules\mob\living\simple_animal\friendly\cockroach.dm" #include "code\modules\mob\living\simple_animal\friendly\corgi.dm" #include "code\modules\mob\living\simple_animal\friendly\corgi_powers.dm" #include "code\modules\mob\living\simple_animal\friendly\crab.dm" @@ -1679,7 +1713,16 @@ #include "code\modules\mob\living\simple_animal\hostile\statue.dm" #include "code\modules\mob\living\simple_animal\hostile\syndicate.dm" #include "code\modules\mob\living\simple_animal\hostile\tree.dm" +#include "code\modules\mob\living\simple_animal\hostile\venus_human_trap.dm" #include "code\modules\mob\living\simple_animal\hostile\winter_mobs.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\hierophant.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm" +#include "code\modules\mob\living\simple_animal\hostile\megafauna\megafauna.dm" +#include "code\modules\mob\living\simple_animal\hostile\mining\goldgrub.dm" +#include "code\modules\mob\living\simple_animal\hostile\mining\hivelord.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\drone.dm" #include "code\modules\mob\living\simple_animal\hostile\retaliate\fish.dm" @@ -1766,7 +1809,6 @@ #include "code\modules\pda\radio.dm" #include "code\modules\pda\utilities.dm" #include "code\modules\persistence\persistence.dm" -#include "code\modules\pooling\pool.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" #include "code\modules\power\cable_heavyduty.dm" @@ -1832,6 +1874,7 @@ #include "code\modules\projectiles\guns\rocket.dm" #include "code\modules\projectiles\guns\syringe_gun.dm" #include "code\modules\projectiles\guns\throw.dm" +#include "code\modules\projectiles\guns\energy\kinetic_accelerator.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\nuclear.dm" #include "code\modules\projectiles\guns\energy\pulse.dm" @@ -1841,6 +1884,7 @@ #include "code\modules\projectiles\guns\magic\staff.dm" #include "code\modules\projectiles\guns\magic\wand.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" +#include "code\modules\projectiles\guns\projectile\bow.dm" #include "code\modules\projectiles\guns\projectile\launchers.dm" #include "code\modules\projectiles\guns\projectile\pistol.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" @@ -1920,6 +1964,7 @@ #include "code\modules\research\server.dm" #include "code\modules\research\designs\AI_module_designs.dm" #include "code\modules\research\designs\autolathe_designs.dm" +#include "code\modules\research\designs\biogenerator_designs.dm" #include "code\modules\research\designs\bluespace_designs.dm" #include "code\modules\research\designs\comp_board_designs.dm" #include "code\modules\research\designs\equipment_designs.dm" @@ -2044,6 +2089,7 @@ #include "code\modules\surgery\limb_reattach.dm" #include "code\modules\surgery\organs_internal.dm" #include "code\modules\surgery\other.dm" +#include "code\modules\surgery\rig_removal.dm" #include "code\modules\surgery\robotics.dm" #include "code\modules\surgery\slime.dm" #include "code\modules\surgery\surgery.dm" @@ -2063,7 +2109,9 @@ #include "code\modules\surgery\organs\parasites.dm" #include "code\modules\surgery\organs\robolimbs.dm" #include "code\modules\surgery\organs\skeleton.dm" +#include "code\modules\surgery\organs\vocal_cords.dm" #include "code\modules\surgery\organs\wound.dm" +#include "code\modules\surgery\organs\subtypes\abductor.dm" #include "code\modules\surgery\organs\subtypes\diona.dm" #include "code\modules\surgery\organs\subtypes\drask.dm" #include "code\modules\surgery\organs\subtypes\grey.dm" @@ -2071,6 +2119,7 @@ #include "code\modules\surgery\organs\subtypes\machine.dm" #include "code\modules\surgery\organs\subtypes\misc.dm" #include "code\modules\surgery\organs\subtypes\nucleation.dm" +#include "code\modules\surgery\organs\subtypes\shadow.dm" #include "code\modules\surgery\organs\subtypes\skrell.dm" #include "code\modules\surgery\organs\subtypes\standard.dm" #include "code\modules\surgery\organs\subtypes\tajaran.dm" diff --git a/sound/machines/airlock_alien_prying.ogg b/sound/machines/airlock_alien_prying.ogg new file mode 100644 index 00000000000..470e86eb259 Binary files /dev/null and b/sound/machines/airlock_alien_prying.ogg differ diff --git a/sound/magic/Blind.ogg b/sound/magic/Blind.ogg new file mode 100644 index 00000000000..ded32a594e4 Binary files /dev/null and b/sound/magic/Blind.ogg differ diff --git a/sound/magic/CastSummon.ogg b/sound/magic/CastSummon.ogg new file mode 100644 index 00000000000..493fb239764 Binary files /dev/null and b/sound/magic/CastSummon.ogg differ diff --git a/sound/magic/Disable_Tech.ogg b/sound/magic/Disable_Tech.ogg new file mode 100644 index 00000000000..478dd042b53 Binary files /dev/null and b/sound/magic/Disable_Tech.ogg differ diff --git a/sound/magic/Ethereal_Enter.ogg b/sound/magic/Ethereal_Enter.ogg new file mode 100644 index 00000000000..a0c7222c167 Binary files /dev/null and b/sound/magic/Ethereal_Enter.ogg differ diff --git a/sound/magic/Ethereal_Exit.ogg b/sound/magic/Ethereal_Exit.ogg new file mode 100644 index 00000000000..bd60ca8c695 Binary files /dev/null and b/sound/magic/Ethereal_Exit.ogg differ diff --git a/sound/magic/Fireball.ogg b/sound/magic/Fireball.ogg new file mode 100644 index 00000000000..b9f6937f06b Binary files /dev/null and b/sound/magic/Fireball.ogg differ diff --git a/sound/magic/ForceWall.ogg b/sound/magic/ForceWall.ogg new file mode 100644 index 00000000000..4fbca3f42b7 Binary files /dev/null and b/sound/magic/ForceWall.ogg differ diff --git a/sound/magic/HorseHead_curse.ogg b/sound/magic/HorseHead_curse.ogg new file mode 100644 index 00000000000..598d096036b Binary files /dev/null and b/sound/magic/HorseHead_curse.ogg differ diff --git a/sound/magic/Knock.ogg b/sound/magic/Knock.ogg new file mode 100644 index 00000000000..fe2f54f97ac Binary files /dev/null and b/sound/magic/Knock.ogg differ diff --git a/sound/magic/MAGIC_MISSILE.ogg b/sound/magic/MAGIC_MISSILE.ogg new file mode 100644 index 00000000000..9d0799d82e9 Binary files /dev/null and b/sound/magic/MAGIC_MISSILE.ogg differ diff --git a/sound/magic/MM_Hit.ogg b/sound/magic/MM_Hit.ogg new file mode 100644 index 00000000000..4f09ef46d51 Binary files /dev/null and b/sound/magic/MM_Hit.ogg differ diff --git a/sound/magic/MindSwap.ogg b/sound/magic/MindSwap.ogg new file mode 100644 index 00000000000..2f4848becb0 Binary files /dev/null and b/sound/magic/MindSwap.ogg differ diff --git a/sound/magic/Repulse.ogg b/sound/magic/Repulse.ogg new file mode 100644 index 00000000000..ed010370754 Binary files /dev/null and b/sound/magic/Repulse.ogg differ diff --git a/sound/magic/Smoke.ogg b/sound/magic/Smoke.ogg new file mode 100644 index 00000000000..ca50a349676 Binary files /dev/null and b/sound/magic/Smoke.ogg differ diff --git a/sound/magic/Staff_Change.ogg b/sound/magic/Staff_Change.ogg new file mode 100644 index 00000000000..9e6eb72ae06 Binary files /dev/null and b/sound/magic/Staff_Change.ogg differ diff --git a/sound/magic/Staff_Door.ogg b/sound/magic/Staff_Door.ogg new file mode 100644 index 00000000000..220f8124825 Binary files /dev/null and b/sound/magic/Staff_Door.ogg differ diff --git a/sound/magic/Staff_Healing.ogg b/sound/magic/Staff_Healing.ogg new file mode 100644 index 00000000000..af2a56049c8 Binary files /dev/null and b/sound/magic/Staff_Healing.ogg differ diff --git a/sound/magic/Staff_animation.ogg b/sound/magic/Staff_animation.ogg new file mode 100644 index 00000000000..8abd7faa60f Binary files /dev/null and b/sound/magic/Staff_animation.ogg differ diff --git a/sound/magic/SummonItems_generic.ogg b/sound/magic/SummonItems_generic.ogg new file mode 100644 index 00000000000..80cc412a4a8 Binary files /dev/null and b/sound/magic/SummonItems_generic.ogg differ diff --git a/sound/magic/Summon_Karp.ogg b/sound/magic/Summon_Karp.ogg new file mode 100644 index 00000000000..d3890776f6d Binary files /dev/null and b/sound/magic/Summon_Karp.ogg differ diff --git a/sound/magic/Summon_Magic.ogg b/sound/magic/Summon_Magic.ogg new file mode 100644 index 00000000000..86b33032826 Binary files /dev/null and b/sound/magic/Summon_Magic.ogg differ diff --git a/sound/magic/Summon_guns.ogg b/sound/magic/Summon_guns.ogg new file mode 100644 index 00000000000..b9b5394a4ed Binary files /dev/null and b/sound/magic/Summon_guns.ogg differ diff --git a/sound/magic/Tail_swing.ogg b/sound/magic/Tail_swing.ogg new file mode 100644 index 00000000000..d39462fae30 Binary files /dev/null and b/sound/magic/Tail_swing.ogg differ diff --git a/sound/magic/Teleport_app.ogg b/sound/magic/Teleport_app.ogg new file mode 100644 index 00000000000..dd9222ae0c3 Binary files /dev/null and b/sound/magic/Teleport_app.ogg differ diff --git a/sound/magic/Teleport_diss.ogg b/sound/magic/Teleport_diss.ogg new file mode 100644 index 00000000000..edc0c55ed00 Binary files /dev/null and b/sound/magic/Teleport_diss.ogg differ diff --git a/sound/magic/WandODeath.ogg b/sound/magic/WandODeath.ogg new file mode 100644 index 00000000000..4412609657c Binary files /dev/null and b/sound/magic/WandODeath.ogg differ diff --git a/sound/magic/Wand_Teleport.ogg b/sound/magic/Wand_Teleport.ogg new file mode 100644 index 00000000000..8a300d7763f Binary files /dev/null and b/sound/magic/Wand_Teleport.ogg differ diff --git a/sound/magic/blink.ogg b/sound/magic/blink.ogg new file mode 100644 index 00000000000..58b7cc8562c Binary files /dev/null and b/sound/magic/blink.ogg differ diff --git a/sound/magic/invoke_general.ogg b/sound/magic/invoke_general.ogg new file mode 100644 index 00000000000..6f0c0dd097a Binary files /dev/null and b/sound/magic/invoke_general.ogg differ diff --git a/sound/magic/narsie_attack.ogg b/sound/magic/narsie_attack.ogg new file mode 100644 index 00000000000..89fac778058 Binary files /dev/null and b/sound/magic/narsie_attack.ogg differ diff --git a/sound/magic/ratvar_attack.ogg b/sound/magic/ratvar_attack.ogg new file mode 100644 index 00000000000..1c17fe10510 Binary files /dev/null and b/sound/magic/ratvar_attack.ogg differ diff --git a/sound/misc/desceration-01.ogg b/sound/misc/desceration-01.ogg new file mode 100644 index 00000000000..29bc568c575 Binary files /dev/null and b/sound/misc/desceration-01.ogg differ diff --git a/sound/misc/desceration-02.ogg b/sound/misc/desceration-02.ogg new file mode 100644 index 00000000000..761a73a7b9f Binary files /dev/null and b/sound/misc/desceration-02.ogg differ diff --git a/sound/misc/desceration-03.ogg b/sound/misc/desceration-03.ogg new file mode 100644 index 00000000000..876de18de50 Binary files /dev/null and b/sound/misc/desceration-03.ogg differ diff --git a/sound/misc/e1m1.ogg b/sound/misc/e1m1.ogg new file mode 100644 index 00000000000..e611e154ae6 Binary files /dev/null and b/sound/misc/e1m1.ogg differ diff --git a/sound/weapons/ZapBang.ogg b/sound/weapons/ZapBang.ogg new file mode 100644 index 00000000000..4e14e30a11b Binary files /dev/null and b/sound/weapons/ZapBang.ogg differ diff --git a/sound/weapons/bulletflyby.ogg b/sound/weapons/bulletflyby.ogg new file mode 100644 index 00000000000..ce9405a5776 Binary files /dev/null and b/sound/weapons/bulletflyby.ogg differ diff --git a/sound/weapons/bulletflyby2.ogg b/sound/weapons/bulletflyby2.ogg new file mode 100644 index 00000000000..63956534ba3 Binary files /dev/null and b/sound/weapons/bulletflyby2.ogg differ diff --git a/sound/weapons/bulletflyby3.ogg b/sound/weapons/bulletflyby3.ogg new file mode 100644 index 00000000000..e8afd28b06d Binary files /dev/null and b/sound/weapons/bulletflyby3.ogg differ diff --git a/sound/weapons/draw_bow.ogg b/sound/weapons/draw_bow.ogg new file mode 100644 index 00000000000..01f1393bc84 Binary files /dev/null and b/sound/weapons/draw_bow.ogg differ diff --git a/sound/weapons/rapierhit.ogg b/sound/weapons/rapierhit.ogg new file mode 100644 index 00000000000..6e214d2821f Binary files /dev/null and b/sound/weapons/rapierhit.ogg differ diff --git a/tools/map_conflict_fixer/README.md b/tools/map_conflict_fixer/README.md new file mode 100644 index 00000000000..5af8d3aadf0 --- /dev/null +++ b/tools/map_conflict_fixer/README.md @@ -0,0 +1,29 @@ +#Map Conflict Fixer/Helper# +The map conflict fixer is a script that can help you fix map conflicts easier and faster. Here's how it works: + +###Before using### +You need git for this, of course. +Make sure your development branch is up to date before starting a map edit to ensure the script outputs a correct fix. + +##Dictionary mode## +Dictionary conflicts are the easiest to fix, you simply need to create more models to accommodate your changes and everyone elses. + +When you run in this mode, if the script finishes successfuly the map should be ready to be commited. + +If the script fails in dictionary mode, you can run it again in full fix mode. + +##Full Fix mode## +When you and someone else edit the same coordinate, there is no easy way to fix the conflict. You need to get your hands dirty. + +The script will mark every tile with a marker type to help you identify what needs fixing in the map editor. + +After you edit and fix a marked map, you should run it through the map merger. The .backup file should be the same you used before. + +###Priorities### +In Full Fix mode, the script needs to know which map version has higher priority, yours or someone elses. This important so tiles with multiple area and turf types aren't created. + +Your version has priority - In each conflicted coordinate, your floor type and your area type will be used +Their version has priority - In each conflicted coordinate, your floor type and your area type will not be used + +##IMPORTANT## +This script is in a testing phase and you should not consider any output to be safe. Always verify the maps this script produced to make sure nothing is out of place. diff --git a/tools/map_conflict_fixer/Run Map Conflict Fixer - DMM.bat b/tools/map_conflict_fixer/Run Map Conflict Fixer - DMM.bat new file mode 100644 index 00000000000..d66102a3295 --- /dev/null +++ b/tools/map_conflict_fixer/Run Map Conflict Fixer - DMM.bat @@ -0,0 +1,4 @@ +@echo off +SET RELATIVEROOT="../../" +python map_conflict_fixer.py %1 %RELATIVEROOT% 0 +pause diff --git a/tools/map_conflict_fixer/map_conflict_fixer.py b/tools/map_conflict_fixer/map_conflict_fixer.py new file mode 100644 index 00000000000..5e64657ad89 --- /dev/null +++ b/tools/map_conflict_fixer/map_conflict_fixer.py @@ -0,0 +1,111 @@ +import map_helpers +import sys +import os +import time + +# Credits to tg for this + +def main(relative_root, tgm=0): + git_version = map_helpers.run_shell_command("git version") + if not git_version: + print("ERROR: Failed to run git. Make sure it is installed and in your PATH.") + return False + + print("--- DISCLAIMER ---") + print("This script is in a testing phase. Verify all the results yourself to make sure you got what you expected. Make sure to read the readme to learn how to use this.") + input("Press Enter to GO\n") + + file_conflicts = map_helpers.run_shell_command("git diff --name-only --diff-filter=U").split("\n") + map_conflicts = [path for path in file_conflicts if path[len(path)-3::] == "dmm"] + + for i in range(0, len(map_conflicts)): + print("[{}]: {}".format(i, map_conflicts[i])) + selection = input("Choose maps you want to fix (example: 1,3-5,12):\n") + selection = selection.replace(" ", "") + selection = selection.split(",") + + #shamelessly copied from mapmerger cli + valid_indices = list() + for m in selection: + index_range = m.split("-") + if len(index_range) == 1: + index = map_helpers.string_to_num(index_range[0]) + if index >= 0 and index < len(map_conflicts): + valid_indices.append(index) + elif len(index_range) == 2: + index0 = map_helpers.string_to_num(index_range[0]) + index1 = map_helpers.string_to_num(index_range[1]) + if index0 >= 0 and index0 <= index1 and index1 < len(map_conflicts): + valid_indices.extend(range(index0, index1 + 1)) + + if not len(valid_indices): + print("No map selected, exiting.") + sys.exit() + + print("Attempting to fix the following maps:") + for i in valid_indices: + print(map_conflicts[i]) + + + marker = None + priority = 0 + print("\nFixing modes:") + print("[{}]: Dictionary conflict fixing mode".format(map_helpers.MAP_FIX_DICTIONARY)) + print("[{}]: Full map conflict fixing mode".format(map_helpers.MAP_FIX_FULL)) + mode = map_helpers.string_to_num(input("Select fixing mode [Dictionary]: ")) + if mode != map_helpers.MAP_FIX_FULL: + mode = map_helpers.MAP_FIX_DICTIONARY + print("DICTIONARY mode selected.") + else: + marker = input("FULL mode selected. Input a marker [/obj/effect/debugging/mapfix_marker]: ") + if not marker: + marker = "/obj/effect/debugging/mapfix_marker" + print("Marker selected: {}".format(marker)) + + print("\nVersion priorities:") + print("[{}]: Your version".format(map_helpers.MAP_FIX_PRIORITY_OURS)) + print("[{}]: Their version".format(map_helpers.MAP_FIX_PRIORITY_THEIRS)) + priority = map_helpers.string_to_num(input("Select priority [Yours]: ")) + if priority != map_helpers.MAP_FIX_PRIORITY_THEIRS: + priority = map_helpers.MAP_FIX_PRIORITY_OURS + print("Your version will be prioritized.") + else: + print("Their version will be prioritized.") + + ed = "FIXED" if mode == map_helpers.MAP_FIX_DICTIONARY else "MARKED" + ing = "FIXING" if mode == map_helpers.MAP_FIX_DICTIONARY else "MARKING" + + print("\nMaps will be converted to TGM.") + print("Writing maps to 'file_path/file_name.fixed.dmm'. Please verify the results before commiting.") + if mode == map_helpers.MAP_FIX_FULL: + print("After editing the marked maps, run them through the map merger!") + input("Press Enter to start.") + + print(".") + time.sleep(0.3) + print(".") + + for i in valid_indices: + path = map_conflicts[i] + print("{}: {}".format(ing, path)) + ours_map_raw_text = map_helpers.run_shell_command("git show HEAD:{}".format(path)) + theirs_map_raw_text = map_helpers.run_shell_command("git show MERGE_HEAD:{}".format(path)) + + common_ancestor_hash = map_helpers.run_shell_command("git merge-base HEAD MERGE_HEAD").strip() + base_map_raw_text = map_helpers.run_shell_command("git show {}:{}".format(common_ancestor_hash, path)) + + ours_map = map_helpers.parse_map(ours_map_raw_text) + theirs_map = map_helpers.parse_map(theirs_map_raw_text) + base_map = map_helpers.parse_map(base_map_raw_text) + + if map_helpers.fix_map_git_conflicts(base_map, ours_map, theirs_map, mode, marker, priority, relative_root+path, tgm): + print("{}: {}".format(ed, path)) + print(".") + +output_tgm = None +try: + output_tgm = int(sys.argv[2]) +except ValueError: + output_tgm = 0 + +main(sys.argv[1], output_tgm) diff --git a/tools/map_conflict_fixer/map_helpers.py b/tools/map_conflict_fixer/map_helpers.py new file mode 100644 index 00000000000..45f27e8c92c --- /dev/null +++ b/tools/map_conflict_fixer/map_helpers.py @@ -0,0 +1,687 @@ +import sys +import subprocess + +tgm_header = "//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE" + +try: + version = sys.version_info + if version.major < 3 or (version.major == 3 and version.minor < 5): + print("ERROR: You are running an incompatible version of Python. The current minimum version required is [3.5].\nYour version: {}".format(sys.version)) + sys.exit() +except: + print("ERROR: Something went wrong, you might be running an incompatible version of Python. The current minimum version required is [3.5].\nYour version: {}".format(sys.version)) + sys.exit() + +import collections + +error = {0:"OK", 1:"WARNING: Detected key length difference, not merging.", 2:"WARNING: Detected map size difference, not merging."} + +def merge_map(newfile, backupfile, tgm): + key_length = 1 + maxx = 1 + maxy = 1 + + new_map = parse_map(get_map_raw_text(newfile)) + old_map = parse_map(get_map_raw_text(backupfile)) + + if new_map["key_length"] != old_map["key_length"]: + if tgm: + write_dictionary_tgm(newfile, new_map["dictionary"]) + write_grid_coord_small(newfile, new_map["grid"]) + return 1 + else: + key_length = old_map["key_length"] + + if new_map["maxx"] != old_map["maxx"] or new_map["maxy"] != old_map["maxy"]: + if tgm: + write_dictionary_tgm(newfile, new_map["dictionary"]) + write_grid_coord_small(newfile, new_map["grid"]) + return 2 + else: + maxx = old_map["maxx"] + maxy = old_map["maxy"] + + new_dict = new_map["dictionary"] + new_grid = new_map["grid"] + old_dict = sort_dictionary(old_map["dictionary"]) #impose order; old_dict is used in the end as the merged dictionary + old_grid = old_map["grid"] + + merged_grid = dict() + known_keys = dict() + unused_keys = list(old_dict.keys()) + + #both new and old dictionary in lists, for faster key lookup by tile tuple + old_dict_keys = list(old_dict.keys()) + old_dict_values = list(old_dict.values()) + new_dict_keys = list(new_dict.keys()) + new_dict_values = list(new_dict.values()) + + #step one: parse the new version, compare it to the old version, merge both + for y in range(1, maxy+1): + for x in range(1, maxx+1): + + new_key = new_grid[x,y] + #if this key has been processed before, it can immediately be merged + if new_key in known_keys: + merged_grid[x,y] = known_keys[new_key] + continue + + old_key = old_grid[x,y] + old_tile = old_dict[old_key] + new_tile = new_dict[new_key] + + if new_tile == old_tile: #this tile is the exact same as before, so the old key is used + merged_grid[x,y] = old_key + known_keys[new_key] = old_key + unused_keys.remove(old_key) + continue + + #the tile is different here, but if it exists in the old dictionary, its old key can be used + newold_key = get_key(old_dict_keys, old_dict_values, new_tile) + if newold_key != None: + merged_grid[x,y] = newold_key + known_keys[new_key] = newold_key + try: + unused_keys.remove(newold_key) + except ValueError: + print("NOTICE: Correcting duplicate dictionary entry. ({})".format(new_key)) + + #the tile is brand new and it needs a new key, but if the old key isn't being used any longer it can be used instead + elif get_key(new_dict_keys, new_dict_values, old_tile) == None: + merged_grid[x,y] = old_key + old_dict[old_key] = new_tile + known_keys[new_key] = old_key + unused_keys.remove(old_key) + + #all other options ruled out, a brand new key is generated for the brand new tile + else: + fresh_key = generate_new_key(old_dict) + old_dict[fresh_key] = new_tile + merged_grid[x,y] = fresh_key + +## #step two: clean the dictionary if it has too many unused keys +## if len(unused_keys) > min(100, (len(old_dict) * 0.5)): +## print("NOTICE: Trimming the dictionary.") +## old_dict = trim_dictionary(old_dict) + + #step three: write the map to file + if tgm: + write_dictionary_tgm(newfile, old_dict) + write_grid_coord_small(newfile, merged_grid, maxx, maxy) + else: + write_dictionary(newfile, old_dict) + write_grid(newfile, merged_grid, maxx, maxy) + return 0 + +####################### +#write to file helpers# +def write_dictionary_tgm(filename, dictionary): #write dictionary in tgm format + with open(filename, "w") as output: + output.write("{}\n".format(tgm_header)) + for key, list_ in dictionary.items(): + output.write("\"{}\" = (\n".format(key)) + + for thing in list_: + buffer = "" + in_quote_block = False + in_varedit_block = False + for char in thing: + + if in_quote_block: + if char == "\"": + in_quote_block = False + buffer = buffer + char + continue + elif char == "\"": + in_quote_block = True + buffer = buffer + char + continue + + if not in_varedit_block: + if char == "{": + in_varedit_block = True + buffer = buffer + "{\n\t" + continue + else: + if char == ";": + buffer = buffer + ";\n\t" + continue + elif char == "}": + buffer = buffer + "\n\t}" + in_varedit_block = False + continue + + buffer = buffer + char + + if list_.index(thing) != len(list_) - 1: + buffer = buffer + ",\n" + output.write(buffer) + + output.write(")\n") + + +def write_grid_coord_small(filename, grid, maxx, maxy): #thanks to YotaXP for finding out about this one + with open(filename, "a") as output: + output.write("\n") + + for x in range(1, maxx+1): + output.write("({},{},1) = {{\"\n".format(x, 1, 1)) + for y in range(1, maxy): + output.write("{}\n".format(grid[x,y])) + output.write("{}\n\"}}\n".format(grid[x,maxy])) + + +def write_dictionary(filename, dictionary): #writes a tile dictionary the same way Dreammaker does + with open(filename, "w") as output: + for key, value in dictionary.items(): + output.write("\"{}\" = ({})\n".format(key, ",".join(value))) + + +def write_grid(filename, grid, maxx, maxy): #writes a map grid the same way Dreammaker does + with open(filename, "a") as output: + output.write("\n") + output.write("(1,1,1) = {\"\n") + + for y in range(1, maxy+1): + for x in range(1, maxx+1): + try: + output.write(grid[x,y]) + except KeyError: + print("Key error: ({},{})".format(x,y)) + output.write("\n") + output.write("\"}") + output.write("\n") + +#################### +#dictionary helpers# +def search_key(dictionary, data): + for key, value in dictionary.items(): + if value == data: + return key + return None + +def get_key(keys, values, data): + try: + return keys[values.index(data)] + except: + return None + +def trim_dictionary(dictionary): #rewrites dictionary into an ordered dictionary with no unused keys + trimmed_dict = collections.OrderedDict() + key_length = len(list(dictionary.keys())[0]) + key = "" + for tile in dictionary.values(): + key = get_next_key(key, key_length) + trimmed_dict[key] = tile + return trimmed_dict + +def sort_dictionary(dictionary): + sorted_dict = collections.OrderedDict() + keys = list(dictionary.keys()) + keys.sort(key=key_int_value) + for key in keys: + sorted_dict[key] = dictionary[key] + return sorted_dict + +############ +#map parser# +def get_map_raw_text(mapfile): + with open(mapfile, "r") as reading: + return reading.read() + +def parse_map(map_raw_text): #still does not support more than one z level per file, but should parse any format + in_quote_block = False + in_key_block = False + in_data_block = False + in_varedit_block = False + after_data_block = False + escaping = False + skip_whitespace = False + + dictionary = collections.OrderedDict() + curr_key = "" + curr_datum = "" + curr_data = list() + + in_map_block = False + in_coord_block = False + in_map_string = False + iter_x = 0 + adjust_y = True + + curr_num = "" + reading_coord = "x" + + key_length = 0 + + maxx = 0 + maxy = 0 + + curr_x = 0 + curr_y = 0 + curr_z = 1 + grid = dict() + + for char in map_raw_text: + + if not in_map_block: + + if char == "\n" or char == "\t": + continue + + if in_data_block: + + if in_varedit_block: + + if in_quote_block: + if char == "\\": + curr_datum = curr_datum + char + escaping = True + continue + + if escaping: + curr_datum = curr_datum + char + escaping = False + continue + + if char == "\"": + curr_datum = curr_datum + char + in_quote_block = False + continue + + curr_datum = curr_datum + char + continue + + if skip_whitespace and char == " ": + skip_whitespace = False + continue + skip_whitespace = False + + if char == "\"": + curr_datum = curr_datum + char + in_quote_block = True + continue + + if char == ";": + skip_whitespace = True + curr_datum = curr_datum + char + continue + + if char == "}": + curr_datum = curr_datum + char + in_varedit_block = False + continue + + curr_datum = curr_datum + char + continue + + if char == "{": + curr_datum = curr_datum + char + in_varedit_block = True + continue + + if char == ",": + curr_data.append(curr_datum) + curr_datum = "" + continue + + if char == ")": + curr_data.append(curr_datum) + dictionary[curr_key] = tuple(curr_data) + curr_data = list() + curr_datum = "" + curr_key = "" + in_data_block = False + after_data_block = True + continue + + curr_datum = curr_datum + char + continue + + if in_key_block: + if char == "\"": + in_key_block = False + key_length = len(curr_key) + else: + curr_key = curr_key + char + continue + #else we're looking for a key block, a data block or the map block + + if char == "\"": + in_key_block = True + after_data_block = False + continue + + if char == "(": + if after_data_block: + in_map_block = True + in_coord_block = True + after_data_block = False + curr_key = "" + continue + else: + in_data_block = True + after_data_block = False + continue + + else: + + if in_coord_block: + if char == ",": + if reading_coord == "x": + curr_x = string_to_num(curr_num) + if curr_x > maxx: + maxx = curr_x + iter_x = 0 + curr_num = "" + reading_coord = "y" + elif reading_coord == "y": + curr_y = string_to_num(curr_num) + if curr_y > maxy: + maxy = curr_y + curr_num = "" + reading_coord = "z" + else: + pass + continue + + if char == ")": + in_coord_block = False + reading_coord = "x" + curr_num = "" + #read z here if needed + continue + + curr_num = curr_num + char + continue + + if in_map_string: + + if char == "\"": + in_map_string = False + adjust_y = True + curr_y -= 1 + continue + + if char == "\n": + if adjust_y: + adjust_y = False + else: + curr_y += 1 + if curr_x > maxx: + maxx = curr_x + if iter_x > 1: + curr_x = 1 + iter_x = 0 + continue + + + curr_key = curr_key + char + if len(curr_key) == key_length: + iter_x += 1 + if iter_x > 1: + curr_x += 1 + + grid[curr_x, curr_y] = curr_key + curr_key = "" + continue + + + #else look for coordinate block or a map string + + if char == "(": + in_coord_block = True + continue + if char == "\"": + in_map_string = True + continue + + if curr_y > maxy: + maxy = curr_y + + data = dict() + data["dictionary"] = dictionary + data["grid"] = grid + data["key_length"] = key_length + data["maxx"] = maxx + data["maxy"] = maxy + return data + +############# +#key helpers# +def generate_new_key(dictionary): + last_key = next(reversed(dictionary)) + return get_next_key(last_key, len(last_key)) + +def get_next_key(key, key_length): + if key == "": + return "".join("a" for _ in range(key_length)) + + length = len(key) + new_key = "" + carry = 1 + for char in key[::-1]: + if carry <= 0: + new_key = new_key + char + continue + if char == 'Z': + new_key = new_key + 'a' + carry += 1 + length -= 1 + if length <= 0: + return "OVERFLOW" + elif char == 'z': + new_key = new_key + 'A' + else: + new_key = new_key + chr(ord(char) + 1) + if carry > 0: + carry -= 1 + return new_key[::-1] + +def key_int_value(key): + value = 0 + b = 0 + for digit in reversed(key): + value += base52.index(digit) * (52 ** b) + b += 1 + return value + +def key_compare(keyA, keyB): #thanks byond for not respecting ascii + pos = 0 + for a in keyA: + pos += 1 + count = pos + for b in keyB: + if(count > 1): + count -= 1 + continue + if a.islower() and b.islower(): + if(a < b): + return -1 + if(a > b): + return 1 + break + if a.islower() and b.isupper(): + return -1 + if a.isupper() and b.islower(): + return 1 + if a.isupper() and b.isupper(): + if(a < b): + return -1 + if(a > b): + return 1 + break + return 0 + + +def key_difference(keyA, keyB): #subtract keyB from keyA + if len(keyA) != len(keyB): + return "you fucked up" + + Ayek = keyA[::-1] + Byek = keyB[::-1] + + result = 0 + for i in range(0, len(keyA)): + base = 52**i + A = 26 if Ayek[i].isupper() else 0 + B = 26 if Byek[i].isupper() else 0 + result += ( (ord(Byek[i].lower()) + B) - (ord(Ayek[i].lower()) + A) ) * base + return result + +############# +#other stuff# + +#Base 52 a-z A-Z dictionary (it's a python list) for fast conversion +base52 = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', + 'p','q','r','s','t','u','v','w','x','y','z','A','B','C','D', + 'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S', + 'T','U','V','W','X','Y','Z'] + +def string_to_num(s): + try: + return int(s) + except ValueError: + return -1 + +#################### +#map conflict fixer# + +MAP_FIX_DICTIONARY = 0 +MAP_FIX_FULL = 1 +MAP_FIX_PRIORITY_OURS = 0 +MAP_FIX_PRIORITY_THEIRS = 1 + +def fix_map_git_conflicts(base_map, ours_map, theirs_map, mode, marker, priority, path, tgm): #attempts to fix git map conflicts automagically + #mode values: + # 0 - Dictionary mode, only fixes dictionary conflicts and fails at coordinate conflicts + # 1 - Full mode, fixes dictionary conflicts and will join both versions of a coordinate and adds a marker to each conflicted coordinate + + if mode == MAP_FIX_FULL and not marker: + print("ERROR: Full fix mode selected but a marker wasn't provided.") + return False + + key_length = 1 + maxx = 1 + maxy = 1 + + if ours_map["key_length"] != theirs_map["key_length"] or ours_map["key_length"] != base_map["key_length"]: + print("ERROR: Key length is different, I am not smart enough for this yet.") + return False + else: + key_length = ours_map["key_length"] + + if ours_map["maxx"] != theirs_map["maxx"] or ours_map["maxy"] != theirs_map["maxy"] or ours_map["maxx"] != base_map["maxx"] or ours_map["maxy"] != base_map["maxy"]: + print("ERROR: Map size is different, I am not smart enough for this yet.") + return False + else: + maxx = ours_map["maxx"] + maxy = ours_map["maxy"] + + base_dict = base_map["dictionary"] + base_grid = base_map["grid"] + ours_dict = ours_map["dictionary"] + ours_grid = ours_map["grid"] + theirs_dict = theirs_map["dictionary"] + theirs_grid = theirs_map["grid"] + + merged_dict = collections.OrderedDict() + merged_grid = dict() + + new_key = generate_new_key(base_dict) + + grid_conflict_counter = 0 + + for y in range(1, maxy+1): + for x in range(1, maxx+1): + base_key = base_grid[x,y] + ours_key = ours_grid[x,y] + theirs_key = theirs_grid[x,y] + + #case 1: everything is the same + if base_dict[base_key] == ours_dict[ours_key] and base_dict[base_key] == theirs_dict[theirs_key]: + merged_dict[base_key] = base_dict[base_key] + merged_grid[x,y] = base_key + continue + + #case 2: ours is unchanged, theirs is different + if base_dict[base_key] == ours_dict[ours_key]: + some_key = search_key(base_dict, theirs_dict[theirs_key]) + if some_key != None: + merged_dict[some_key] = theirs_dict[theirs_key] + merged_grid[x,y] = some_key + else: + merged_dict[new_key] = theirs_dict[theirs_key] + merged_grid[x,y] = new_key + new_key = get_next_key(new_key, key_length) + + #case 3: ours is different, theirs is unchanged + elif base_dict[base_key] == theirs_dict[theirs_key]: + some_key = search_key(base_dict, ours_dict[ours_key]) + if some_key != None: + merged_dict[some_key] = ours_dict[ours_key] + merged_grid[x,y] = some_key + else: + merged_dict[new_key] = ours_dict[ours_key] + merged_grid[x,y] = new_key + new_key = get_next_key(new_key, key_length) + + #case 4: everything is different, grid conflict + else: + if mode != MAP_FIX_FULL: + print("FAILED: Map fixing failed due to grid conflicts. Try fixing in full fix mode.") + return False + else: + combined_tile = combine_tiles(ours_dict[ours_key], theirs_dict[theirs_key], priority, marker) + merged_dict[new_key] = combined_tile + merged_grid[x,y] = new_key + new_key = get_next_key(new_key, key_length) + grid_conflict_counter += 1 + + merged_dict = sort_dictionary(merged_dict) + if tgm: + write_dictionary_tgm(path+".fixed.dmm", merged_dict) + write_grid_coord_small(path+".fixed.dmm", merged_grid, maxx, maxy) + else: + write_dictionary(path+".fixed.dmm", merged_dict) + write_grid(path+".fixed.dmm", merged_grid, maxx, maxy) + if grid_conflict_counter > 0: + print("Counted {} conflicts.".format(grid_conflict_counter)) + return True + +def combine_tiles(tile_A, tile_B, priority, marker): + new_tile = list() + turf_atom = None + area_atom = None + + low_tile = None + high_tile = None + if priority == MAP_FIX_PRIORITY_OURS: + high_tile = tile_A + low_tile = tile_B + else: + high_tile = tile_B + low_tile = tile_A + + new_tile.append(marker) + for atom in high_tile: + if atom[0:5] == "/turf": + turf_atom = atom + elif atom[0:5] == "/area": + area_atom = atom + else: + new_tile.append(atom) + + for atom in low_tile: + if atom[0:5] == "/turf" or atom[0:5] == "/area": + continue + else: + new_tile.append(atom) + + new_tile.append(turf_atom) + new_tile.append(area_atom) + return tuple(new_tile) + + +def run_shell_command(command): + return subprocess.run(command, shell=True, stdout=subprocess.PIPE, universal_newlines=True).stdout