diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index ba253b3073e..b5564f3f6b0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -523,7 +523,6 @@ responsible for properly tagging new pull requests and issues, moderating commen pull requests/issues, and merging/closing pull requests. ### Maintainer List -* [tigercat2000](https://github.com/tigercat2000) * [Fox P McCloud](https://github.com/Fox-McCloud) * [Crazy Lemon](https://github.com/Crazylemon64) diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index 514eda508c9..dd35a91f3e1 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -5510,8 +5510,8 @@ "cbX" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/starboard) "cbY" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/genetics) "cbZ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id_tag = "toxins_blastdoor"; name = "privacy shutters"; opacity = 0},/turf/simulated/floor/plating,/area/toxins/mixing{name = "\improper Toxins Lab"}) -"cca" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plasteel{dir = 9; icon_state = "caution"},/area/atmos) -"ccb" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "caution"},/area/atmos) +"cca" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/suit/space/hardsuit/atmos,/obj/item/clothing/head/helmet/space/hardsuit/atmos,/turf/simulated/floor/plasteel{dir = 9; icon_state = "caution"},/area/atmos) +"ccb" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/structure/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/suit/space/hardsuit/atmos,/obj/item/clothing/head/helmet/space/hardsuit/atmos,/turf/simulated/floor/plasteel{dir = 1; icon_state = "caution"},/area/atmos) "ccc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "caution"},/area/atmos) "ccd" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blackcorner"},/area/atmos) "cce" = (/obj/machinery/meter,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plasteel,/area/atmos) diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 69668331980..6a8a1ef134c 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -188,7 +188,7 @@ "adF" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "adG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "adH" = (/obj/structure/stool,/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) -"adI" = (/obj/structure/table,/obj/item/dice/d20,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) +"adI" = (/obj/structure/table,/obj/item/dice/d20,/obj/item/instrument/harmonica,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "adJ" = (/obj/machinery/atmospherics/unary/outlet_injector/on,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "adK" = (/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; tag = ""},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) "adL" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/permabrig) @@ -2619,7 +2619,7 @@ "aYs" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aYt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/table/reinforced,/obj/item/clipboard,/obj/item/folder/yellow,/obj/item/stamp/ce,/obj/item/book/manual/sop_engineering,/obj/item/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/storage/fancy/cigarettes,/obj/item/lighter/zippo,/obj/item/pen/multi,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) "aYu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"aYv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) +"aYv" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/reagent_dispensers/water_cooler,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/crew_quarters/fitness) "aYw" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aYx" = (/obj/structure/crematorium,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) "aYy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -2628,7 +2628,7 @@ "aYB" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "aYC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "aYD" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/escape) -"aYE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/library) +"aYE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aYF" = (/obj/structure/closet/coffin,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "aYG" = (/obj/structure/closet/coffin,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "aYH" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/escape) @@ -2891,7 +2891,7 @@ "bdE" = (/obj/machinery/camera{c_tag = "Dormitories Toilets"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "bdF" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock{name = "Bar Office"; req_access_txt = "25"},/turf/simulated/floor/plasteel,/area/crew_quarters/bar) "bdG" = (/obj/machinery/portable_atmospherics/canister/air{anchored = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"bdH" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"bdH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bdI" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/primary/central/ne) "bdJ" = (/obj/machinery/light/small{dir = 1},/obj/item/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/obj/structure/closet/chefcloset,/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "bdK" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) @@ -2975,7 +2975,7 @@ "bfk" = (/obj/machinery/requests_console{department = "Bar"; name = "Bar Requests Console"; departmentType = 2; pixel_x = 0; pixel_y = 30},/obj/structure/table/reinforced,/obj/machinery/chem_dispenser/beer,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/bar) "bfl" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/obj/machinery/light{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "bfm" = (/obj/effect/decal/warning_stripes/north,/obj/machinery/atmospherics/unary/portables_connector,/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/turret_protected/aisat_interior) -"bfn" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"bfn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; level = 1},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "bfo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bfp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bfq" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/primary/central/ne) @@ -3208,7 +3208,7 @@ "bjJ" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/escape) "bjK" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/obj/structure/table/wood,/obj/item/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "bjL" = (/obj/structure/stool/bed/chair,/obj/item/radio/intercom/locked/confessional{pixel_x = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) -"bjM" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/plasteel{icon_state = "neutral"},/area/crew_quarters/fitness) +"bjM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bjN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/carpet,/area/library) "bjO" = (/obj/structure/table/wood,/turf/simulated/floor/carpet,/area/hallway/secondary/entry) "bjP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/port) @@ -3546,6 +3546,7 @@ "bqj" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (EAST)"; icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bqk" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (WEST)"; icon_state = "wooden_chair_wings"; dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bql" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "chapel"},/area/chapel/main) +"bqm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/hardsuit/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/hardsuit/atmos,/turf/simulated/floor/plasteel,/area/atmos) "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" = (/turf/simulated/shuttle/wall{tag = "icon-swall7"; icon_state = "swall7"; dir = 2},/area/shuttle/escape) @@ -4948,7 +4949,7 @@ "bRi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bRj" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bRk" = (/obj/structure/table,/obj/item/FixOVein,/obj/item/surgicaldrill,/obj/item/bonegel,/obj/item/bonesetter,/obj/item/retractor,/obj/item/hemostat,/obj/item/cautery,/obj/item/stack/medical/bruise_pack/advanced{pixel_x = -4; pixel_y = 4},/turf/simulated/floor/plasteel,/area/assembly/robotics) -"bRl" = (/obj/effect/decal/warning_stripes/east,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/structure/table,/obj/item/mmi,/obj/item/mmi,/obj/item/mmi,/obj/item/mmi/posibrain,/obj/item/robotanalyzer,/turf/simulated/floor/plasteel,/area/assembly/robotics) +"bRl" = (/obj/effect/decal/warning_stripes/east,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"; tag = ""},/obj/structure/table,/obj/item/mmi,/obj/item/mmi,/obj/item/mmi,/obj/item/mmi/robotic_brain,/obj/item/robotanalyzer,/turf/simulated/floor/plasteel,/area/assembly/robotics) "bRm" = (/obj/structure/table,/obj/item/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/storage/firstaid/regular{empty = 1; name = "First-Aid (empty)"},/obj/item/healthanalyzer,/obj/item/healthanalyzer,/obj/item/healthanalyzer,/obj/machinery/newscaster{pixel_x = 26; pixel_y = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics) "bRn" = (/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/medical/research{name = "Research Division"}) "bRo" = (/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id_tag = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Research Hallway Entrance"; dir = 2; network = list("Research","SS13")},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/medical/research{name = "Research Division"}) @@ -8227,6 +8228,8 @@ "dcl" = (/obj/structure/closet/radiation,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel,/area/engine/engineering) "dcm" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/engine/engineering) "dcn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/turf/simulated/wall/r_wall,/area/engine/engineering) +"dco" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) +"dcp" = (/obj/machinery/porta_turret{dir = 1},/obj/structure/sign/securearea{pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "darkbluecorners"},/area/turret_protected/aisat_interior) "dcs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/decal/cleanable/fungus,/turf/simulated/wall/r_wall,/area/engine/engineering) "dct" = (/obj/machinery/portable_atmospherics/scrubber,/turf/simulated/floor/plasteel,/area/atmos) "dcv" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plasteel,/area/atmos) @@ -8816,7 +8819,6 @@ "dqw" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) "dqx" = (/obj/machinery/porta_turret{dir = 1},/obj/item/radio/intercom/locked/ai_private{broadcasting = 1; listening = 0; pixel_y = -29},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkbluecorners"},/area/turret_protected/aisat_interior) "dqy" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) -"dqz" = (/obj/machinery/porta_turret{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/obj/structure/sign/securearea{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "darkbluecorners"},/area/turret_protected/aisat_interior) "dqA" = (/obj/structure/rack,/obj/item/crowbar/red,/obj/item/wrench,/turf/simulated/floor/plating,/area/aisat{name = "\improper AI Satellite Hallway"}) "dqB" = (/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/maintenance{name = "\improper AI Satellite Service"}) "dqC" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/mob/living/simple_animal/bot/cleanbot{on = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "darkbluecorners"},/area/aisat/maintenance{name = "\improper AI Satellite Service"}) @@ -9016,15 +9018,15 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPVaSdaSdaLdaMsaPZaQaaLdaMsaPZaQaaLdaGnaLkaGnaGnaGnaGnaGnaHSaGnaHSaQbaPXaHSaHSaGnaLsaGnaPYaabaPYaGnaJYaOZaGnaQeaQcaGnaNAaKaaGnaLsaMAaMAaQgaQgaQgaQgaQgaQgaQgaQgaQgaPiaPiaPjaQhaQiaQjaQkaQlaQdaKEaKDaKFaKFaKFaKFaKFaKGaKIaKHaKFaKFaKFaKKaKKaKLaLzaKNaLBaEjaHBaLPaQzaKpaLNaLPaKuaMNaMWaNRaNSaMNaMVaMVaMVaMVaNTaMZaNdaNdaNeaMVaSQaMVaMVaMVaMVaKCaODaKQaKQaKQaKQaKQaODaQHaPMaKOaGYaVJaGYaQBaMzaQCaHOaQLaQJaHbaGXaOFaHbaGXaQKaGYaGXaQMaGYaGXaQOaQNaQPaOGaRWaMqaUgaQRaUiaUhaUiaQRaUjaMqaMzaMzaGXaGXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQXaRbaoOaSbaMcaMdaMdaRaaMdaMdaMdaRdaRcaReaReaReaReaRfaGnaHSaGnaRhaRgaRiaHSaRjaPcaLsaGnaGnaGnaGnaGnaGnaPcaGnaHSaRiaLkaHSaHSaHSaRkaRmaRlaRnaRnaRnaRnaRoaRnaRnaRpaRqaRlaRsaRraRraRraRraRraRraRraRtaRwaRwaRwaRwaRxaRwaRwaLDaRwaRwaRxaRwaRwaRwaRwaRzaLFaLKaLGaLLaLPaRDaLMaLWaLOaNVaMNaNYaNXaOeaMNaMVaMVaMVaMVaMTaRMaOpaOpaRGaMVaVLaVKaMVaMVaMVaPvaRVaKQaKQaKQaKQaKQaRVaVMaYwaVObfQaZzbafbafbafbafbbYaOGaOGaOGaOGaOGaOGaOGaKSaGYaGYaGYaGYaMnaGYaGYaMkaGYaRXaUYaUYaMqaMqaMqaMqaMqaMqaUfaQIaOFaJMaGXaabajcaMraMraabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZPaSdaSdaMBaSfaMDaMEaSiaSjaQZaSaaSjaSeaScaSjaSjaSnaGnaHSaGnaSoaHSaHSaSpaSqaGnaNIaKgaHSaHSaHSaHSaHSaHSaPcaSsaHSaGnaNxaNxaGnaSraMAaSuaSwaSvaSvaSvaSxaSvaSvaSvaSyaSuaSzaSAaSAaSAaSAaSAaSAaSAaPiaRwaSBaSCaSEaSgaSkaShaSmaSlaSJaSDaSLaSCaSMaRwaSNaFFaSOaEjaMFaLPaSRaMGaSTaSSaOqaWHaOyaOraOraPkaPBbhiaPCbgsbhhbhibhibhibhibhibhjaMVaMVaMVaMVaThaODaKQaKQaKQaKQaKQaKOaKOaKOaKOaHbaMzaMzaIEaGXaGXbBOaMzaGXaTgaMzaGXaIEaGXaMkaQIaMzaGXaIEaGXaKXaUUaMkaGYaTiaGXaHOaHbaGYaGYaVTaVhaVUaVUaWZaGYaGYaGXaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaSdaRUaSdaToaSfaSfaTpaSdaRUaSdaTqaTsaTraTtaGnaHSaPcaPcaGnaGnaGnaTuaTuaTuaIfaTuaTuaTuaTuaTuaHSaGnaGnaGnaGnaGnaGnaGnaSraKbaStaaaaabaaaaabaaaaabaaaaabaaaaSuaSzaSAaTwaTvaTyaTxaTAaSAaPiaRwaTzaTzaTCaTBaTEaTDaTFaTDaMKaTGaTIaTzaTzaRwatcaFFaTJaEjaMFaLPaOnaKpaLNaLPaPDbhkbhtbhpaPFaPEaQAbhzbitbisbiTbiubjkbjcbjXbjMbkKbkIaQEaOvaOwaKOaODaKQaKQaKQaKQaKQaKOaTXaUaaMzaGXaMzaLcaGYaGXaLcbBOaGXaTZaGYaGXaUbaGYaMzaUdaUcaGXaUeaGYaMzaIEaIEaMkaGYaXbaXaaXaaXaaXaaXaaXdaGYaGYaGYaXeaGYaGYaIFaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaMsaSdaRUaSdaToaSfaSfaTpaSdaRUaSdaTqaTsaTraTtaGnaHSaPcaPcaGnaGnaGnaTuaTuaTuaIfaTuaTuaTuaTuaTuaHSaGnaGnaGnaGnaGnaGnaGnaSraKbaStaaaaabaaaaabaaaaabaaaaabaaaaSuaSzaSAaTwaTvaTyaTxaTAaSAaPiaRwaTzaTzaTCaTBaTEaTDaTFaTDaMKaTGaTIaTzaTzaRwatcaFFaTJaEjaMFaLPaOnaKpaLNaLPaPDbhkbhtbhpaPFaPEaQAbhzbitbisbiTbiubjkbjcbjXaYvbkKbkIaQEaOvaOwaKOaODaKQaKQaKQaKQaKQaKOaTXaUaaMzaGXaMzaLcaGYaGXaLcbBOaGXaTZaGYaGXaUbaGYaMzaUdaUcaGXaUeaGYaMzaIEaIEaMkaGYaXbaXaaXaaXaaXaaXaaXdaGYaGYaGYaXeaGYaGYaIFaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaLdaLdaSdaOQaSdaUlaUkaUnaUmaSdaOQaSdaSdaLdaUoaUpaGnaHSaHSaHSaHSaHSaHSaTuaUuaUvaUqaUxaUsaUzaUuaTuaUwaUAaUyaUyaUyaUyaUyaUyaUBaNxaStaabaUEaUEaUEaUEaUEaUEaUEaabaSuaSzaSAaUFaUCaUHaUDaUFaSAaPiaRwaUJaUJaUJaUGaULaSCaUIaSCaULaUKaUJaUJaUJaRwaSNaFFaUMaEjaMFaLPaOjaKpaLNaLPaQFbuMaUQaUQaUQaUQaUQaUQaUQaNZaUQaUSaUSaUSaUSaUSaOaaGXaPGaPIaPIbJUaODaKQaKQaKQaKQaKQaKOaURaUaaMzaUTaGXaGYaGYaGXbJVbLCaMzaGYaGYaGXaGYaGYaMzaMkaGVaGXaGYaGYaMzaUWaGYaMkaGYaXgaQLbazbazbazbazbazaYPaYPaYPaQDaYPaYPaYPaYRaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdaRUaSdaSdaSdaSdaSdaSdaRUaSdaUZaLdaUVaUXaVcaVcaVcaVcaVcaVcaVaaTuaUuaVeaUqaVfaVeaVeaUuaTuaVgaVbaViaViaViaViaViaViaViaViaVjaaaaUEaVkaVdaVmaVlaVnaUEaaaaSuaSzaSAaVpaVoaVraVqaUFaSAaPiaRwaVsaVsaTCaVtaVuaTDaTFaTDaVuaVvaVwaTzaTzaRwaSNaFFaSOaEjaObaLPaOdaOcaLNaLPaQGbuMaUQaVzaVAaVCaVCaUQaVBaOfaVDaUSbxyaVFaVHaUSaOgaGXaPGaPIaPHaPJaKOaKOaKOaKOaKOaKOaKOaVNbLGaMzaMzaGXaGXaMzaMzbLHaVPaMzaGXaHPaGXaGXaMzaMzaVRaVQaGXaGXaGXaQLaUWaGYaMkaGYaRXaGYbazaXjaXoaXkaYxaYPaYAaYzaYCaYBaYGaYFaYRaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaVSaVXaVSaVSaVYaVZaVSaVSaVXaWaaVWaLdaToaWbaVcaWdaWcaWfaWeaWhaWgaTuaUuaVeaUqaWjaVeaVeaUuaTuaWkaWlaWiaWnaWmaWoaWqaWraWpaWtaVjaabaUEaWuaWsaWwaWvaWxaUEaabaSuaSzaSAaWzaWAaWyaWCaWBaSAaPiaRwaSBaSCaWEaWDaULaSCaWFaSCaULaWGaSLaSCaSMaRwaSNaFFaWJaEjaMFaLPaISaOhaLNaLPaRvbuUaUQaWKaVEaVEaVEaWLaOlaOkaOmaUSaWQaWPaOxaOtaPgaGXaRPaRQaRQaRIaGXaJMaGXaGYaQIaHPaLcaWUaWXaWWaWYaGXaNhaGYaQIbBOaGYaGXaaaaGXaGYaGYaGYbbIaYIbbIaYKaYJaYJaYJaYJaYJbamaYObapbanbarbaqbatbasbawaYPbaAbayaYCbaBbaCbaCaYRaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaWaaVSaXmaXraXsaXtaXuaXvaXwaXxaXyaXzaXpaXnaSdaToaXqaVcaXBaXAaXFaXGaXFaXCaTuaXIaVeaXDaXHaXEaXHaXJaXLaXKaXMaXQaXQaXQaXQaXQaXQaXNaXSaVjaaaaUEaXOaWsaXPaWvaXRaUEaaaaSuaSzaSAaXTaXXaXVaXUaYaaSAaPiaRwaXWaXWaTCaXYaVuaTDaXZaTDaVuaYbaTIaTzaTzaRwaYcaIraYhaEjaMFaLPaLPaLPaLPaLPaPlaRJaPnaPmaPoaUQaUQaUQaUQaUQaUQaUSaPpaZVaPqaUSaOgaGXaGXaGXaGXaGXaGXaGYaGXaGYaHPaHPaGXaGXaGXaYnaGXaGXaGXaGXaGYbBOaWVaHNaabaHNaGYaYsaYvaYuaYybaDbaEbaubauaYEbauaGXbaFaGXbazbazbazbazbazbaIbazbazbazbaybcgaXcbaMaXhaYRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXpaYMaYLaYNaXzaYZaXsaYZaXsaYZaXsaYZaXzaYVaYTaSdaToaYWaVcaYYaYXaZfaZaaZhaZbaTuaZjaUraZcaZlaZmaZnaZdaTuaZeaZgaXQaXQaXQaXQaXQaXQaXNaZraVjaabaUEaZkaZiaZpaZoaZqaUEaabaSuaSzaSAaZsaZyaZtaZAaZuaSAaPiaRwaUJaUJaUJaYpaULaSCaUIaSCaULaZvaUJaUJaUJaRwaZxaZFaZGaEjaPtaPsaPsaPsaPsaPuaPxaPvaUQaPyaPzaUQaQmaQfaQnaUQaQoaUSaZDaZVaZEaUSaQpaZKaQqaZNaZNaZKaZXaZWaZWaZWaZWaZWaQxaZYaZWbaabacbabbaebadbagbMgbaibahbajbahbalbakaGYaGXbaubaubcmbaubavbaobaxaGXbcnaHObazbcqbcwbcubcAbcxbcCbcBbazbcFbdZbdYbegbedaXlaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaZaXsaXsaVXaXzaYZaXsaYZbbaaYZaXsaYZaXzaYVaYTaSdaTobaJaVcaVcbaKaUtbaLaUtaVcaTuaTuaTuaTubaSbaPbbhbbbaTubbjbbcbblaXQaXQbbmaXQbbebbdbbpaVjaaaaUEaUEbbqbbfbbqaUEaUEaaaaSuaSzaSAbbibbgbbkaZAbbnaSAaPiaRwaSBaSCbboaWDaULaSCaUIaSCaULaWGbbxaRwaRwaRwbbrbbzbbtbbsbbCatGatGatGbbEbbFbbvbbuaUQbbwaVEaUQbbJaUQbbKaUQbbLaQrbbBbbAbbHbbGbbUbbIaQtbbNbbQbbPbbRbbQbbQbbSbbQbbIbbTbbIaXfbbUbbIbbVbbXaSGbbZaZZbcbbcabcdbccbcfbceaXibaubaubcobekbchbcibcsbcjaGXbaFbelbazbeqbetberbevbeubczbczbewbcDbfUbfSbfSbfSaYRaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXpbcrbcNaYNaXzaYZaXsaYZaXsaYZaXsaYZaXzaYVaYTaSdaTobcvbctbcEbcybcSbcSaSfbcGbcMbcVbcWbcXbcPbcOaVebcQaTubdbbcRbddbdebcTbdgbdhbdibcUbdkaVjaaaaabaaabcYbcZbcYaaaaabaaaaSuaSzaSAbdcbdabdjbdfbdraSAaPiaRwbdmbdlaTCaZwbdoaTDbdpaTDbdsaZQbdzaRwbdubdtbdvbdDbdxbdwbbDbdHaaaaaabbEbdIbdBbdAaUQbdCbdEaVEaVEbdNaVEaVEaVEbdOaUSbdFaUSbdQaUSaUSaQuaUSbdTbdUbdKbdJbdMbdLbdTbdPbeabebbecbebbebbebbebbdSbeebebbefbdVbdWbeibebbdXaGYbaubtlbcpbfVbembenbeobepaGXbaFbfWbazbfXbcxbgabcxbckbczbczbggbcDbybbgibgibgRaYQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabehbejaVSaXmaXzaXsbeGbesaXsaXsbexbeGaXzaXpbeyaSdaTobeEbezbeMaRKbeMbeMbeMbeMbeMbeHaSfaTubePbeQbePaTuaTubeRbeIbeRaViaViaViaVibeRbeJbeUaVjbeLbeKbeKbeNbeObeNbeKbeKbeSaSubfaaSAbeTaSAbeWbeVbfeaSAbffaRwaRwaRwaRwbfgbfhbeXbeYbeXbfhbfgaRwaRwbeZbdDbdDbdDbdDbfbbdybfnbfobfpbbEbfqbdBbfiaUQaUQaUQaUQaUQaUQaUQaUSaUSbdObfsbftbfkbfjaQvaRLaSUaRNbdTbfAbfvbfCbfwbfEbdTbfxbfybfHbfzbfHbfJbfKbfMbfBbfFbfDbfIbfGbfNbfLbebbfObfQbfPbhKbfRbfVbfYbfZbeobfTaGXbhObhNbhUbhSbhXbhWbhWbhYbczbczbggbcDbcDbgibhZbgiaYQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYDaYUaYHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaVSaVXaVSaVSaVYaVZaVSaVSaVXaWaaVWaLdaToaWbaVcaWdaWcaWfaWeaWhaWgaTuaUuaVeaUqaWjaVeaVeaUuaTuaWkaWlaWiaWnaWmaWoaWqaWraWpaWtaVjaabaUEaWuaWsaWwaWvaWxaUEaabaSuaSzaSAaWzaWAaWyaWCaWBaSAaPiaRwaSBaSCaWEaWDaULaSCaWFaSCaULaWGaSLaSCaSMaRwaSNaFFaWJaEjaMFaLPaISaOhaLNaLPaRvbuUaUQaWKaVEaVEaVEaWLaOlaOkaOmaUSaWQaWPaOxaOtaPgaGXaRPaRQaRQaRIaGXaJMaGXaGYaQIaHPaLcaWUaWXaWWaWYaGXaNhaGYaQIbBOaGYaGXaaaaGXaGYaGYaYEbbIaYIbbIaYKaYJaYJaYJaYJaYJbamaYObapbanbarbaqbatbasbawaYPbaAbayaYCbaBbaCbaCaYRaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVVaWaaVSaXmaXraXsaXtaXuaXvaXwaXxaXyaXzaXpaXnaSdaToaXqaVcaXBaXAaXFaXGaXFaXCaTuaXIaVeaXDaXHaXEaXHaXJaXLaXKaXMaXQaXQaXQaXQaXQaXQaXNaXSaVjaaaaUEaXOaWsaXPaWvaXRaUEaaaaSuaSzaSAaXTaXXaXVaXUaYaaSAaPiaRwaXWaXWaTCaXYaVuaTDaXZaTDaVuaYbaTIaTzaTzaRwaYcaIraYhaEjaMFaLPaLPaLPaLPaLPaPlaRJaPnaPmaPoaUQaUQaUQaUQaUQaUQaUSaPpaZVaPqaUSaOgaGXaGXaGXaGXaGXaGXaGYaGXaGYaHPaHPaGXaGXaGXaYnaGXaGXaGXaGXaGYbBOaWVaHNaabaHNaGYaYsbdHaYuaYybaDbaEbaubaubaubauaGXbaFaGXbazbazbazbazbazbaIbazbazbazbaybcgaXcbaMaXhaYRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXpaYMaYLaYNaXzaYZaXsaYZaXsaYZaXsaYZaXzaYVaYTaSdaToaYWaVcaYYaYXaZfaZaaZhaZbaTuaZjaUraZcaZlaZmaZnaZdaTuaZeaZgaXQaXQaXQaXQaXQaXQaXNaZraVjaabaUEaZkaZiaZpaZoaZqaUEaabaSuaSzaSAaZsaZyaZtaZAaZuaSAaPiaRwaUJaUJaUJaYpaULaSCaUIaSCaULaZvaUJaUJaUJaRwaZxaZFaZGaEjaPtaPsaPsaPsaPsaPuaPxaPvaUQaPyaPzaUQaQmaQfaQnaUQaQoaUSaZDaZVaZEaUSaQpaZKaQqaZNaZNaZKaZXaZWaZWaZWaZWaZWaQxaZYaZWbaabacbabbaebadbagbMgbaibahbajbahbalbakaVJaGXbaubaubcmbaubavbaobaxaGXbcnaHObazbcqbcwbcubcAbcxbcCbcBbazbcFbdZbdYbegbedaXlaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaZaXsaXsaVXaXzaYZaXsaYZbbaaYZaXsaYZaXzaYVaYTaSdaTobaJaVcaVcbaKaUtbaLaUtaVcaTuaTuaTuaTubaSbaPbbhbbbaTubbjbbcbblaXQaXQbbmaXQbbebbdbbpaVjaaaaUEaUEbbqbbfbbqaUEaUEaaaaSuaSzaSAbbibbgbbkaZAbbnaSAaPiaRwaSBaSCbboaWDaULaSCaUIaSCaULaWGbbxaRwaRwaRwbbrbbzbbtbbsbbCatGatGatGbbEbbFbbvbbuaUQbbwaVEaUQbbJaUQbbKaUQbbLaQrbbBbbAbbHbbGbbUbbIaQtbbNbbQbbPbbRbbQbbQbbSbbQbbIbbTbbIaXfbbUbbIbbVbbXaSGbbZaZZbcbbcabcdbccbcfbcebfnbaubaubcobekbchbcibcsbcjaGXbaFbelbazbeqbetberbevbeubczbczbewbcDbfUbfSbfSbfSaYRaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXpbcrbcNaYNaXzaYZaXsaYZaXsaYZaXsaYZaXzaYVaYTaSdaTobcvbctbcEbcybcSbcSaSfbcGbcMbcVbcWbcXbcPbcOaVebcQaTubdbbcRbddbdebcTbdgbdhbdibcUbdkaVjaaaaabaaabcYbcZbcYaaaaabaaaaSuaSzaSAbdcbdabdjbdfbdraSAaPiaRwbdmbdlaTCaZwbdoaTDbdpaTDbdsaZQbdzaRwbdubdtbdvbdDbdxbdwbbDbjMaaaaaabbEbdIbdBbdAaUQbdCbdEaVEaVEbdNaVEaVEaVEbdOaUSbdFaUSbdQaUSaUSaQuaUSbdTbdUbdKbdJbdMbdLbdTbdPbeabebbecbebbebbebbebbdSbeebebbefbdVbdWbeibebbdXaGYbaubtlbcpbfVbembenbeobepaGXbaFbfWbazbfXbcxbgabcxbckbczbczbggbcDbybbgibgibgRaYQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabehbejaVSaXmaXzaXsbeGbesaXsaXsbexbeGaXzaXpbeyaSdaTobeEbezbeMaRKbeMbeMbeMbeMbeMbeHaSfaTubePbeQbePaTuaTubeRbeIbeRaViaViaViaVibeRbeJbeUaVjbeLbeKbeKbeNbeObeNbeKbeKbeSaSubfaaSAbeTaSAbeWbeVbfeaSAbffaRwaRwaRwaRwbfgbfhbeXbeYbeXbfhbfgaRwaRwbeZbdDbdDbdDbdDbfbbdydcobfobfpbbEbfqbdBbfiaUQaUQaUQaUQaUQaUQaUQaUSaUSbdObfsbftbfkbfjaQvaRLaSUaRNbdTbfAbfvbfCbfwbfEbdTbfxbfybfHbfzbfHbfJbfKbfMbfBbfFbfDbfIbfGbfNbfLbebbfObfQbfPbhKbfRbfVbfYbfZbeobfTaGXbhObhNbhUbhSbhXbhWbhWbhYbczbczbggbcDbcDbgibhZbgiaYQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYDaYUaYHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabehaVSaVXaVSaVSaVYaVZaVSaVSaVXbejbgeaLdbdnbeEaSdaSWaSWaSXaSWaSYaMsbgvbglaSfbgnbfcbgzbgzbgqbgrbgzbgubgzbgzbgzbgDbgzbgzbgwbgFbdqbgAbghbgBbgAbgCbgAbgAbgAbgAbgEbgMbgJbgzbgzbgKbfcbgQbgxbgSbgLbgObgNbgTbgPbgPbgPbgPbgPbgPbgPbgVbgUbhabhbbhcbhdbhebgWbgXbfdbdDbdDbhfbgZbhgbgZbhgaSZaTfaTaaWNaUNbhqaUSbhrbhlaYeaYdaZRaZRaWMbeFbfrbflbdTbhobhubhsbhsbhwbdTbhAbhCbhBbhEbhDbhDbhFbhHbhGbfMbhIbhJbhPbhQbhRbebbdXaTgbaubiabcpbihbibbhVbhTbhLaGXbjnbiibazbjrbazbewbggbggbazbazbazbjsbjsaYPaYPaYPaYRaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYDbaWbaXbaYaYHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSdbgyaSdaSdaSdaSdaSdaSdbgyaSdaUZaLdbgHbieaSdbgtbgjbhmbhmbhvaMsbivbglbifbgGbfcbijbipbiobiqbiqbixbiwbiwbiwbizbiybiybiAbiCbiBbiqbiqbiDbiybiFbiEbiGbiGbiIbiHbiKbiJbiJbiJbiLbfcbgQbgxbgSbgSbgSbgSbiMbgSbgSbgSbgSbgSbgSbiNbiUbiVbiWbiXbiObiZbiQbiPbiRbiVbiVbiVbjdbjebjebjebiSbhqbhqbhqbirbhxbhqaUSbjabjjaZRaZRbiYaZRaWTbjmbfrbjKbdTbjobjfbjqbjhbjgbdTbjtbjibjvbjwbjxbjybebbebbjzbebbebbebbjBbjlbjBbebbdXaGYbaubjubcpbcpbekbjEbcpbjFaGXaGXaGXaYPaYPaYPbcDbcDbcDbjDbjAbjIbcDbcDbcDbjpbjLaYRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYDbaWbcJbcKbcLbaYaYHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabbjQaLdaSdaOQaSdbidbgIbjTbjSaSdaOQaSdaSdaLdbjUbeEaSdbkcbjObhmbhmbhvaMsbkdbglaSfbgGbfcbgzbjZbjYbkgbkgbkabkibkbbkgbkebkgbkfbkgbkhbjPbkgbkgbkgbkgbkgbkjbkkbkgbklbkrbknbkmbgzbgzbkpbkobksbkqbkubktbkubkvbkwbkvbkvbkvbkvbkvbkvbkybkAbkzbkzbkzbkzbkBbkzbkCbkDbkzbkzbkEbkGbkFbkFbkFbkFbkFbkFbkFbkHbhqbhqaUSbkMbkNbkPbkObkOblrblsbjmbfrbltbdTbdTbdTbdTbdTbkLbdTbkQbkRbkWbkSbfHbkYbebbhMbkTbkUblcbkVbleblfblgbebbdXaQLbaubliblibcpbjNblkbcpbllbllbaubkXblabkZaYPbldblnbloboJblhboJblnbloblmaYPblqaYRaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaYUbeAbeBbeCbeBbeDaYUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9090,8 +9092,8 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwaaaaabaaaaabaabcVkaabaaaaabcVkaabaaaaabcVkaabaaaaaaaaaaaaaaaaaaaaaaaaaaacRzcRzcRzcVlcVdcVmcRAcVncNBcNNcTccTccTccTccVocTccUfcSUcVhcVicVjcGPcGRcGQcGTcGScGVcGUcGXcGWcGZcGYcHbcHacUtcTjcTecVxcVDcRXcRXcVFcPTcLScVHcSdcVIcQPcVJcVEcVLcVKcVOcVMcVQcVPcVQcVRaabcQZcQZcQZcQZcQZcRecBPcHcctZctZcmJcKOcAucsLcyJcsLcMfcsLcHdchfchfchfcHechfctrbQXciYbUxcHfcBRcJKcJKcJKcWicLUcWpcWjcWqcWfcEHcEHcEHcEHcWgcWrcWwaaaaaaaaaaabaabaaaaaaaaaaaabGHbGHcFcbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwaabcNFcWxcNMaaacNFcWxcNMaaacNFcWxcNMaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabcRzcRAcRAcRAcRAcWkcWlcWmcNBcWncNBcNBcMvcWocNBcSUcWzcWycVjcHhcUicWscWtcWucWucHkcWDcWCcWFaYtaZBcHkcWBcWHcWJcWIcWLcWKcWPcWMcWScMicUGcWTcWUcWNcWOcWVcWWcWRcWYcWXcXbcXacXdcXccQpcSncXecWZcWZcQZcRecBPcGIcsLcsLcHlchfchfchfcyPcyPchfchfchfchfcHZcIacsLchfctrcIccIbcIbcIbcXmcXmcXmcXmcXmcMjcXvcXtcXzcXxcNocXAcNocXAcNocXBcWwaaaaaaaaaaaaaabaabaaaaaaaaaaaabGHcFcbGHaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNFcWxcNMaabcNFcWxcNMaaacNFcWxcNMaaaaaaaaaaaaaabaaaaaaaaaaaaaabaabaabaaaaaaaabaabcXucXucXucXucXucXucXucXCcXucXucSUcXwcXDcVjcHhcUicXycUicUicXEcRRcXGcXFcUwcIdcIecRRcXLcRXcTecXMcXOcXNcWPcXPcXJaZCcXRcXQcXVcXScXRcXWcXYcXXcYacSdcXTcXUcYccYbaabcTocYfcIfcXZcQZcRecBQcIgdfMdfMcIhcIichfcIkcIjcImcIlcIocInchfcsLcIpcsLchfctrcIqciYbQXcIrcIsciYcIucItcBRcMIcMQcMJcNacMIcMQcNbcNccMIcMQcNlcBRaabaabaabaabaabaabaabaabaabaabbGHcFcbGHbGHbGHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacYzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNFcWxcNMaaacNFcWxcNMaaacNFcWxcNMaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabcXucYtcYtcYucYAcYBcYBcYDcYCcYCcYEcYGcYFcVjcHhcVjcYHcVjcVjcVjcRRcYLcIvcIxcIwcIycYIcYJcYQcYRcYMcYMcYMcYXcYUcYZaZHcZacYScVIcQPcYTcZbcYVcYWcZccSdcXTcZdcZgcZecZhcSncZicWZcWZcQZcRecBQckKcExchfcyJcJqcyPcJscImcJucJtcJvcsLcJwcYjcIpcJxchfctrcIqciYbQXcpEbQXciYcJzcIrcBRcZqcZscZrcxNcZtcZycZvcxNcZzcZBcZAcBRaabaabaaaaaaaaaaaaaaaaaaaaaaaabGHcFcbGGbGGbGHaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNFcWxcNMaaacNFcWxcNMaabcNFcWxcNMaabaabaabaabaaaaabaaaaaaaabaabaaaaaaaaaaabaaaaaacXucYtcYtcYucZucZucZucZCcZwcZxcSUcJBcJAcJDcJCcJFcJEcJHcZFcZFcZLcZOcZNcVjcVjcVjcZPcZRcZQcZMcJIcNXcNVdacdabcSUcZScZSdafcVIcQPcZUdagcZWcZXcZYcSdcZZdahdajdaidadcQZcQZcQZcQZcQZcRecBQckKdaecsLcyJcJqchfcKvcKucKwcJtcKAcIjcKCcKBcKDcJxchfctrcIqcGLbQXcKEcKFciYcKGbQXcBRcMkcJKcJKcxNcMkcJKcJKcxNcMkcJKcJKcBRaaaaabaabaaaaaaaaaaaaaaacuQcuQbGHdaucuQbGGbGHbGHbGHcTQcTQaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNFcWxcNMaaacNFcWxcNMaaacNFcWxcNMaabaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaabaabaabcXucYtcYtcYucYAcYBcYBcYDcYCcYCcYEcYGcYFcVjcHhcVjcYHcVjcVjcVjcRRcYLcIvcIxcIwcIycYIcYJcYQcYRcYMcYMcYMcYXcYUcYZaZHcZacYSbqmcQPcYTcZbcYVcYWcZccSdcXTcZdcZgcZecZhcSncZicWZcWZcQZcRecBQckKcExchfcyJcJqcyPcJscImcJucJtcJvcsLcJwcYjcIpcJxchfctrcIqciYbQXcpEbQXciYcJzcIrcBRcZqcZscZrcxNcZtcZycZvcxNcZzcZBcZAcBRaabaabaaaaaaaaaaaaaaaaaaaaaaaabGHcFcbGGbGGbGHaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaabcNFcWxcNMaaacNFcWxcNMaabcNFcWxcNMaabaabaabaabaaaaabaaaaaaaabaabaaaaaaaaaaabaaaaaacXucYtcYtcYucZucZucZucZCcZwcZxcSUcJBcJAcJDcJCcJFcJEcJHcZFcZFcZLcZOcZNcVjcVjcVjcZPcZRcZQcZMcJIcNXcNVdacdabcSUcZScZSdafbqmcQPcZUdagcZWcZXcZYcSdcZZdahdajdaidadcQZcQZcQZcQZcQZcRecBQckKdaecsLcyJcJqchfcKvcKucKwcJtcKAcIjcKCcKBcKDcJxchfctrcIqcGLbQXcKEcKFciYcKGbQXcBRcMkcJKcJKcxNcMkcJKcJKcxNcMkcJKcJKcBRaaaaabaabaaaaaaaaaaaaaaacuQcuQbGHdaucuQbGGbGHbGHbGHcTQcTQaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamhaabcNFdavcNMaaacNFdavcNMaaacNFdavcNMaabalvaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaabcXudaodapcZucZucZudaxdardardardardardardarcKHcKJcKIcKKdawdawdawdaFdaydaJdaAdaBdawdaydaKdaRcKLcNXcObdacdabdaGdaHdaIdaTdaUdaLdaMdaNcZcdaOdaPdaVdaYdaWcOkcXcdbacSndbcdbbdbbcQZcRecBPckKchfcBNdaXcJqchfcKNcKMcJtcIjcJtcKScJtcJucJtcsLchfctrcIqciYbQXciYciYciYbQXbQXcBRdbfcKZcJKcxNdbfcKZcJKcxNdbfcKZcJKcBRaaaaaaaabaabaaaaaaaaaaaacuQdbgbGGcFccuQdbhcuQdbibGHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalvaaaaabaaaaaaaaaaabaabaabaaaaaaaabaabaaaalvaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabcXudbjcZucZucZucZucZudardbtdblcOqcOtcOrdarcKUdbqdbrcHhcVjcVjdbsdbBdbydbEdbCdbGdbFdbzcSUdbAcKLcNXcPgdacdbJcSUdbDcZSdbKdbLcSddaMdaNdbNcSddaPdaVcXTcXUcPicYbdbIcTodbScLVdbWcQZcRecBPckKchfdbMdbMcJqchfcLYcsLcLZcIjcMccMbcMecMdcJGcJvcyPctrcIqciYbQXbQXcMhciYbQXaqFcBRdbRcJKcJKcxNdbRcJKcJKcxNdbRcJKcJKcBRaaaaaaaaaaabaabaaaaaaaaacuQbGGbGGcFccuQbGGbGGbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalwalwalvalwalwamhalvalvalvalvalwalvalvalwdbTaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacXudbUcZwcZucZucZudbVdardblcPkcMOcMTcMScMVcMUcMYcMWcMZcVjdcmdcldchcPlcPEcPDcPWcPFdcndcwdbrcHhcWecPXcZMcQccSUdcscZSdctdcLcSddaMdaNcZccSddcvdaVcXTdcOcQecZedcScSndcTdbbdbbcQZcRecBQckKdcAcuccABcJqchfchfcNdcNecDncNfcNfcNgchfchfchfchfctrcIqciYbQXcNhcKFciYcepcepcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRcBRaaaaaaaaaaaaaabaabaaaaaabGHbGHbGHcFccuQdcJdcKbGGbZZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -9126,7 +9128,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadpddpCdpEdpDdpFdpfdpIdpHdpJdpfdpKdpAdpAdpLdppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaaadohdohdohdohdohaabdnLaabdohdohdohdohdohaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadpddpMdpOdpNdpPdpGdpRdpQdpSdpGdpUdpTdpWdpVdppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabdondoodoodoodoodpYdpXdpYdordordordordptaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaadpddpZdqbdqadqddqcdqfdqedqhdqgdqjdqidqldqkdppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabdoGdoGdoGdoGdoGaaadnLaaadoGdoGdoGdoGdoGaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadpddpddqqdqodqsdpfdqxdqtdqzdpfdqCdqBdqEdppdppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaaaaaaaabaabaabaaaaaadnLaabaaaaaaaabaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadpddpddqqdqodqsdpfdqxdqtdcpdpfdqCdqBdqEdppdppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaaaaaaaabaabaabaaaaaadnLaabaaaaaaaabaabaaaaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdqmdqpdqFdqpdqmdqmdqGdqrdqmdqpdqHdqpdqmaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWamWamWamWamWaaaaaaaaadnLaaaaaaaaaamWamWamWayiamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqmdisdqudqpdqvdqwdqIdqydqvdqpdqJdqAdqmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaabdqKaabamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdqmdqndqudqpdqvdqwdqIdqydqvdqpdqJdqDdqmaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamWaaaaabaaaamWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 4c9573b8e7e..e7bd86f366e 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -919,6 +919,7 @@ "rI" = (/obj/machinery/computer/security/telescreen{name = "Special Ops. Monitor"; desc = "Used for watching the Special Ops."; network = list("ERT")},/obj/structure/table/wood,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/specops) "rJ" = (/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "SPECOPS"; name = "Ready Room"; pixel_x = -6; pixel_y = 6; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "specopsoffice"; name = "Privacy Shutters"; pixel_x = 6; pixel_y = -6; req_access_txt = "114"},/obj/machinery/door_control{desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; id = "CCGAMMA"; name = "Gamma Lockdown"; pixel_x = -6; pixel_y = -6; req_access_txt = "114"},/obj/structure/table/wood,/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/specops) "rK" = (/turf/unsimulated/wall/splashscreen,/area/start) +"rL" = (/obj/structure/table/abductor,/obj/item/bonegel/alien,/obj/item/bonesetter/alien,/obj/item/FixOVein/alien,/obj/item/surgicaldrill/alien,/obj/item/circular_saw/alien,/turf/unsimulated/floor/abductor,/area/abductor_ship) "sq" = (/turf/unsimulated/wall,/area/centcom/control) "sr" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "ss" = (/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) @@ -1731,7 +1732,7 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkwkykxkxkxkAkzaNkwkDkxkxkxkAkzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDAHlHmHnDAHoFvFvHpDAHqHrHsHpDwGaDKDKDAaNaNaNHtHuHvHwHtaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkEkGkFkIkHkNkMaNkEkGkOkIkPkNkMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNHAFvFvFvHBFvFvFvFvHCFvFvFvFvHCDKDKDKDAaNaNEMDwDwHDDwDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkQkRkxkxkxkAkSaNkQkRkxkxkxkAkSaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDAHLdacZDAGVFvFvGWDAHOHPHQGWDwEIDKDKDAaNaNaNEMaNaNaNEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkUlikVlkljlmllaNkUlikVlkljlmllaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwGZHVHWDADwDwDwDwEnaNDIDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkUlikVrLljlmllaNkUlikVlkljlmllaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwGZHVHWDADwDwDwDwEnaNDIDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNlylnlAlzlFaNaNaNlylnlAlzlFaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMaNaNEMDAGXIbDAEnaNaNaNaNaNEfDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwEnaNDtDxDyDyDzGaDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNjQjPjSjRjTaNaNaNjQjPjSjRjTaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKDKDKDKDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1739,7 +1740,7 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkwlRkxkxkxkAkzaNkwlSkxkxkxkAkzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDMIqDMDwDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkEkGlTkIlUkNkMaNkEkGlVkIlYkNkMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAItDKDKDKIuDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkQkRkxkxkxkAkSaNkQkRkxkxkxkAkSaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKlKDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkUlikVlkljlmllaNkUlikVlkljlmllaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNIADKDKDKIBDNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkUlikVrLljlmllaNkUlikVrLljlmllaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNIADKDKDKIBDNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNlylnlAlzlFaNaNaNlylnlAlzlFaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfICDKDKDKIDEfaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwIFIGIHmsIJDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDxDyDzDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index 5e8b66e6c24..35d509b3584 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -174,6 +174,7 @@ "dr" = (/obj/structure/window/reinforced,/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/derelict/singularity_engine) "ds" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel/airless{icon_state = "damaged5"},/area/derelict/singularity_engine) "dt" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel/airless{icon_state = "damaged4"},/area/derelict/singularity_engine) +"du" = (/turf/space,/area/syndicate_depot/perimeter) "dv" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/derelict/singularity_engine) "dw" = (/obj/item/disk/data/demo,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "dx" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/singularity_engine) @@ -273,6 +274,7 @@ "fn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel/airless{icon_state = "damaged3"},/area/derelict/hallway/primary) "fo" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged2"},/area/derelict/hallway/primary) "fp" = (/turf/simulated/floor/plasteel/airless,/area/derelict/hallway/primary) +"fq" = (/obj/effect/landmark{name = "syndi_depot_backup"},/turf/space,/area/syndicate_depot/perimeter) "fr" = (/obj/item/ore/slag,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "fs" = (/obj/item/shard,/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) "ft" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/derelict/singularity_engine) @@ -563,6 +565,7 @@ "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" = (/turf/space,/area/syndicate_depot/outer) "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) @@ -616,42 +619,42 @@ "lU" = (/obj/structure/table,/obj/item/stock_parts/cell{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel/airless,/area/derelict/teleporter) "lV" = (/turf/simulated/floor/plasteel/airless{icon_state = "damaged4"},/area/derelict/teleporter) "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/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) -"md" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/syndicate_depot) -"me" = (/obj/machinery/door/airlock/hatch{req_access_txt = "150"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mf" = (/turf/simulated/mineral,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/syndicate_depot) -"mg" = (/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/syndicate_depot) -"mh" = (/obj/structure/closet/crate{name = "foot locker"},/obj/item/ammo_box/magazine/m10mm{pixel_x = 4},/obj/item/gun/projectile/automatic/pistol,/obj/item/clothing/head/helmet/swat/syndicate,/obj/item/clothing/glasses/thermal{pixel_x = -3; pixel_y = 3},/obj/item/clothing/shoes/black{pixel_y = -4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mi" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mj" = (/obj/structure/stool/bed,/obj/item/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/storage/fancy/cigarettes/cigpack_syndicate{pixel_x = -3; pixel_y = -2},/obj/item/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/porta_turret/syndicate/interior,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mn" = (/obj/item/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/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/reagent_containers/food/snacks/syndicake,/obj/item/reagent_containers/food/drinks/cans/beer,/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) -"mz" = (/turf/simulated/floor/engine,/area/syndicate_depot) -"mA" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/storage/box/donkpockets,/obj/item/ammo_box/magazine/mm556x45,/obj/item/gun/projectile/automatic/m90,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mB" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Telepad"; req_access_txt = "0"},/turf/simulated/floor/engine,/area/syndicate_depot) -"mC" = (/obj/machinery/telepad,/turf/simulated/floor/engine,/area/syndicate_depot) -"mD" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/ammo_box/magazine/m12g/dragon,/obj/item/storage/fancy/cigarettes/cigpack_syndicate,/obj/item/storage/firstaid/tactical,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mE" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mF" = (/obj/structure/computerframe{anchored = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) -"mG" = (/turf/simulated/mineral,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_depot) +"lX" = (/turf/simulated/mineral,/area/syndicate_depot/outer) +"lY" = (/obj/structure/mineral_door/wood,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"lZ" = (/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"ma" = (/obj/structure/spider,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mb" = (/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mc" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"md" = (/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"me" = (/obj/item/reagent_containers/food/snacks/spiderleg,/obj/structure/spider,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mf" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mg" = (/obj/effect/landmark{name = "syndi_depot_bot"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"mh" = (/obj/machinery/navbeacon/invisible{codes_txt = "patrol;next_patrol=SDNW"; invisibility = 100; location = "SDNE"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"mi" = (/turf/simulated/wall,/area/syndicate_depot/outer) +"mj" = (/obj/effect/spawner/random_spawners/syndicate/turret/external,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"mk" = (/obj/machinery/light,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"ml" = (/obj/structure/table,/obj/item/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mm" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/spider,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mn" = (/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"mo" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"mp" = (/obj/structure/falsewall,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/outer) +"mq" = (/obj/structure/stool/bed,/obj/item/bedsheet/syndie,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mr" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ms" = (/obj/structure/table,/obj/structure/reagent_dispensers/beerkeg,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mt" = (/obj/item/reagent_containers/food/drinks/flask/barflask,/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mu" = (/obj/machinery/light{dir = 1; on = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mv" = (/obj/machinery/door/poddoor{id_tag = "syndi_depot_lvl2"; name = "Level 2 Blast Doors"; protected = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mw" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mx" = (/obj/effect/spawner/random_spawners/syndicate/layout/door,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"my" = (/obj/machinery/door/airlock/hatch/syndicate,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mz" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mA" = (/obj/effect/decal/cleanable/blood,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mB" = (/obj/structure/sign/poster/contraband/syndicate_recruitment,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"mC" = (/obj/effect/spawner/random_spawners/syndicate/loot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mD" = (/obj/machinery/light,/obj/effect/spawner/random_spawners/syndicate/turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mE" = (/obj/structure/sign/poster/contraband/lamarr,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"mF" = (/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"mG" = (/obj/effect/spawner/random_spawners/syndicate/turret/external,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) "mH" = (/turf/simulated/mineral,/area/space) "mI" = (/turf/simulated/floor/plating/airless/asteroid,/area/space) "mJ" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/space) @@ -663,8 +666,10 @@ "mP" = (/obj/structure/closet/crate,/obj/item/ore/bananium,/obj/item/ore/bananium,/obj/item/ore/bananium,/obj/item/ore/bananium,/obj/item/ore/bananium,/turf/simulated/floor/plasteel/airless,/area/space) "mQ" = (/obj/structure/closet/crate{icon_state = "crateopen"; opened = 1},/obj/item/ore/bananium,/obj/item/grenade/bananade,/turf/simulated/floor/plasteel/airless,/area/space) "mR" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (EAST)"; icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/space) +"mS" = (/obj/item/stack/sheet/metal{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) "mT" = (/obj/item/shard{icon_state = "small"},/turf/simulated/floor/plating/airless/asteroid,/area/space) "mU" = (/obj/item/ore/bananium,/turf/simulated/floor/plasteel/airless,/area/space) +"mV" = (/obj/machinery/light{dir = 1; on = 1},/obj/item/stack/sheet/metal{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) "mW" = (/obj/structure/computerframe/HONKputer,/turf/simulated/floor/plasteel/airless,/area/space) "mX" = (/obj/item/shard{icon_state = "medium"},/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/space) "mY" = (/obj/effect/landmark/corpse/clown{name = "Clown Pilot"},/turf/simulated/floor/plasteel/airless,/area/space) @@ -676,7 +681,11 @@ "ne" = (/turf/simulated/floor/plasteel/airless,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/space) "nf" = (/obj/item/pickaxe,/turf/simulated/floor/plasteel/airless,/area/space) "ng" = (/obj/structure/closet/crate,/obj/item/ore/bananium,/obj/item/ore/bananium,/obj/item/ore/bananium,/obj/item/ore/bananium,/turf/simulated/floor/plasteel/airless,/area/space) +"nh" = (/obj/effect/spawner/random_spawners/syndicate/trap/mine,/obj/item/stack/sheet/metal{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ni" = (/obj/item/flag/chameleon{icon_state = "syndiflag"; name = "Syndicate Flag"; used = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nj" = (/obj/machinery/computer/syndicate_depot/teleporter,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) "nk" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (NORTH)"; icon_state = "heater"; dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/space) +"nl" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/decal/warning_stripes/blue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) "nm" = (/obj/item/shard,/turf/simulated/floor/plasteel/airless,/area/space) "nn" = (/obj/item/broken_bottle,/turf/simulated/floor/plasteel/airless,/area/space) "no" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"; dir = 2},/area/space) @@ -687,6 +696,122 @@ "nt" = (/obj/item/shard,/turf/simulated/floor/plating/airless/asteroid,/area/space) "nu" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/space) "nv" = (/obj/effect/landmark/corpse/mime{name = "Mime Pilot"},/turf/simulated/floor/plasteel/airless,/area/space) +"nw" = (/obj/machinery/bluespace_beacon/syndicate,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nx" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"ny" = (/obj/machinery/navbeacon/invisible{codes_txt = "patrol;next_patrol=SDSW"; invisibility = 100; location = "SDNW"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"nz" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/spawner/random_spawners/syndicate/turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nA" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nB" = (/obj/structure/sign/poster/contraband/fun_police,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nC" = (/obj/machinery/door/poddoor/multi_tile/two_tile_hor,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nD" = (/obj/effect/spawner/random_spawners/syndicate/trap/medbot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nE" = (/obj/effect/spawner/random_spawners/syndicate/mob,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nF" = (/obj/effect/spawner/random_spawners/syndicate/loot/level2,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nG" = (/obj/item/lighter/zippo/black,/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nH" = (/obj/structure/sign/poster/contraband/lusty_xenomorph,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nI" = (/obj/effect/spawner/random_spawners/syndicate/layout/spacepod,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nJ" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/spawner/random_spawners/syndicate/loot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nK" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/spawner/random_spawners/syndicate/loot/level2,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nL" = (/obj/structure/sign/poster/official/high_class_martini,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nM" = (/obj/machinery/light{dir = 8},/obj/effect/spawner/random_spawners/syndicate/loot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nN" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/effect/spawner/random_spawners/syndicate/loot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nO" = (/obj/effect/spawner/random_spawners/syndicate/turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nP" = (/obj/structure/dispenser,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nQ" = (/obj/structure/sign/poster/official/air1,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nR" = (/obj/item/storage/box/donkpockets,/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nS" = (/obj/machinery/computer/syndicate_depot/syndiecomms,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nT" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nU" = (/obj/structure/sign/poster/contraband/tools,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nV" = (/obj/structure/sign/poster/contraband/hacking_guide,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"nW" = (/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nX" = (/obj/effect/spawner/random_spawners/syndicate/loot/level3,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nY" = (/obj/machinery/atmospherics/unary/passive_vent/high_volume,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"nZ" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oa" = (/obj/machinery/vending/syndisnack,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ob" = (/obj/machinery/door/airlock/silver,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oc" = (/obj/structure/closet/secure_closet/syndicate/depot,/obj/effect/spawner/random_spawners/syndicate/trap/documents,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"od" = (/obj/machinery/computer/syndicate_depot/selfdestruct,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oe" = (/obj/effect/decal/warning_stripes/red,/obj/structure/window/plasmareinforced{dir = 8},/obj/structure/fusionreactor,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"of" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"og" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oh" = (/obj/structure/table,/obj/effect/spawner/random_spawners/syndicate/trap/pizzabomb,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oi" = (/obj/structure/table,/obj/item/reagent_containers/food/snacks/syndicake,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oj" = (/obj/machinery/vending/syndicigs,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ok" = (/obj/machinery/portable_atmospherics/canister/toxins,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ol" = (/obj/effect/spawner/random_spawners/syndicate/layout/door/secret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"om" = (/turf/simulated/floor/mineral/silver,/area/syndicate_depot/core) +"on" = (/obj/machinery/door/airlock/plasma{welded = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oo" = (/turf/simulated/floor/mineral/plasma,/area/syndicate_depot/core) +"op" = (/obj/structure/table,/obj/item/wrench,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oq" = (/obj/structure/table,/obj/item/folder/syndicate/yellow,/obj/item/pen,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"or" = (/obj/effect/landmark{dir = 6; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"os" = (/obj/structure/cable,/obj/machinery/power/terminal,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ot" = (/obj/effect/spawner/random_spawners/syndicate/layout/door/vault,/obj/effect/landmark{dir = 4; name = "syndi_depot_shield"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ou" = (/obj/effect/landmark{dir = 4; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"ov" = (/obj/structure/sign/poster/contraband/energy_swords,/obj/effect/landmark{dir = 4; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"ow" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/landmark{dir = 4; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"ox" = (/obj/effect/landmark{dir = 10; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"oy" = (/obj/effect/spawner/random_spawners/syndicate/mob,/turf/simulated/floor/mineral/plasma,/area/syndicate_depot/core) +"oz" = (/obj/machinery/light/small{tag = "icon-bulb1 (EAST)"; icon_state = "bulb1"; dir = 4},/turf/simulated/floor/mineral/silver,/area/syndicate_depot/core) +"oA" = (/obj/structure/sign/poster/official/state_laws,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"oB" = (/obj/effect/landmark{name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"oC" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/smes/upgraded{charge = 5e+006; input_level = 20000; output_level = 100000},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oD" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oE" = (/obj/machinery/turretid/syndicate{name = "internal turret controls"; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oF" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/spawner/random_spawners/syndicate/loot/level4,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oG" = (/obj/effect/spawner/random_spawners/syndicate/loot/level4,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oH" = (/obj/effect/spawner/random_spawners/syndicate/loot/level4,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oI" = (/obj/machinery/computer/syndicate_depot/aiterminal,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oJ" = (/obj/structure/mirror{pixel_x = -32},/turf/simulated/floor/mineral/silver,/area/syndicate_depot/core) +"oK" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 12; pixel_y = 0},/turf/simulated/floor/mineral/plasma,/area/syndicate_depot/core) +"oL" = (/obj/structure/sign/poster/contraband/missing_gloves,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"oM" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oN" = (/obj/machinery/atmospherics/unary/passive_vent/high_volume{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oO" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/effect/spawner/random_spawners/syndicate/layout/door/vault,/obj/effect/landmark{name = "syndi_depot_shield"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oQ" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oR" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oS" = (/obj/effect/decal/warning_stripes/north,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oT" = (/obj/effect/decal/warning_stripes/north,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oU" = (/obj/structure/sign/poster/contraband/revolver,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/effect/landmark{name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"oV" = (/obj/machinery/atmospherics/unary/passive_vent/high_volume{dir = 8},/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oW" = (/obj/structure/mirror{pixel_x = -32},/turf/simulated/floor/mineral/plasma,/area/syndicate_depot/core) +"oX" = (/obj/structure/toilet{dir = 8},/turf/simulated/floor/mineral/silver,/area/syndicate_depot/core) +"oY" = (/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"oZ" = (/obj/machinery/light,/obj/effect/spawner/random_spawners/syndicate/loot/level3,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pa" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pb" = (/obj/structure/cable,/obj/machinery/power/apc/noalarm{dir = 4; pixel_x = 24; req_access = list(150)},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pc" = (/obj/machinery/computer/syndicate_depot/shieldcontrol,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pd" = (/obj/effect/spawner/random_spawners/syndicate/layout/door/vault,/obj/effect/landmark{name = "syndi_depot_shield"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pe" = (/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"pf" = (/obj/structure/sign/poster/official/obey,/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"pg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"ph" = (/obj/effect/landmark{dir = 5; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"pi" = (/obj/structure/sign/poster/contraband/syndicate_pistol,/obj/effect/landmark{dir = 4; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"pj" = (/obj/effect/landmark{dir = 9; name = "syndi_depot_shield"},/turf/simulated/wall/r_wall,/area/syndicate_depot/core) +"pk" = (/mob/living/silicon/decoy/syndicate/depot,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pl" = (/obj/machinery/door_control{active_power_usage = 0; id = "syndi_depot_rear"; idle_power_usage = 0; name = "mysterious button"; normaldoorcontrol = 0; use_power = 0},/obj/structure/sign/poster/contraband/syndicate_recruitment,/turf/simulated/wall,/area/syndicate_depot/core) +"pm" = (/turf/simulated/mineral,/area/syndicate_depot/core) +"pn" = (/obj/effect/spawner/random_spawners/blood_maybe,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/core) +"po" = (/obj/machinery/light{dir = 1; on = 1},/obj/effect/spawner/random_spawners/syndicate/turret,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pp" = (/obj/machinery/light{dir = 1; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pq" = (/obj/machinery/recharge_station,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pr" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"ps" = (/obj/machinery/door_control{active_power_usage = 0; id = "syndi_depot_rear"; idle_power_usage = 0; name = "mysterious button"; normaldoorcontrol = 0; pixel_x = 24; use_power = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pt" = (/obj/item/candle,/obj/structure/table,/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/core) +"pu" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/core) +"pv" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pw" = (/obj/machinery/computer/syndicate_depot/doors,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"px" = (/obj/machinery/atmospherics/unary/passive_vent/high_volume{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"py" = (/obj/machinery/door/poddoor{id_tag = "syndi_depot_rear"; name = "Sealed Doors"; protected = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pz" = (/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/core) +"pA" = (/obj/structure/falsewall,/turf/simulated/floor/plating/airless,/area/syndicate_depot/core) +"pB" = (/obj/machinery/light/small{dir = 8},/obj/effect/spawner/random_spawners/syndicate/loot/level2,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pC" = (/turf/simulated/wall,/area/syndicate_depot/core) +"pD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pE" = (/obj/machinery/navbeacon/invisible{codes_txt = "patrol;next_patrol=SDSE"; invisibility = 100; location = "SDSW"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) +"pF" = (/obj/machinery/light/small{dir = 8},/obj/effect/spawner/random_spawners/syndicate/turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot/core) +"pG" = (/obj/machinery/power/apc/noalarm{dir = 4; pixel_x = 24},/obj/structure/cable,/obj/machinery/turretid/syndicate{name = "external turret controls"; pixel_y = 32},/turf/simulated/floor/plating/airless,/area/syndicate_depot/outer) +"pH" = (/obj/machinery/navbeacon/invisible{codes_txt = "patrol;next_patrol=SDNE"; invisibility = 100; location = "SDSE"},/turf/simulated/floor/plating/airless/asteroid,/area/syndicate_depot/outer) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -874,55 +999,6 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalXaaaalXlXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlXlXaalXlXlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlXlXlXlYlYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlZlXlZlYlYlYlYmambmcmbmdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYmambmembmflYlYlYmgmhmimjmgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYmgmimimimglYlYmamgmkmimjmlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYmgmmmimmmgmbmbmbmgmnmimompaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYmqmbmembmrmimimimemimsmtmglYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYmgmimimimimimumgmbmbmbmbmflYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYmgmimimimimimimemimvmwmbmbmbmflYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYmqmbmbmbmbmbmbmgmnmimimxmymzmglYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYlYlYlYlYlYmqmgmAmimimimBmCmglYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYlYlYlYlYlYmgmDmimEmFmymzmglYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYmqmbmbmbmbmbmbmGlYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYlYlYlYlYlYlYlYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYlYlYlYlYlYlYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYlYlYlYlYlYlYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalYlYaalYlYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacvcvcvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznknknkmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamLnnnmncmLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznonpaznpnqmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamInrnomTnsnsnqmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHaaaamHmHmHmHmHntnvnumHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmImImHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmImIaaaaczmKmKmLmLmKmKmKmKmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmIczmKmNmImOazazmPmPmQazmRdlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmTazazazazazmUazmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmWmXmYazmZmUazmUazmUmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHnaaznbazncazmOazazazmUmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHndmKneaznfazazngmPmPazmRhZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHndmKmKmLmLmKmKmKmKmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaamHmHmHmHmHmImImHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmImImImHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamImImHmImHmHmImImIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHaaaaaaaaaaaamImHmHmHmHmHmHmIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -933,6 +1009,55 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadudududududududufqdudududududufqdudududududududududufqdududududududududufqdududududududududududufqdudududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXlXkVkVkVkVkVkVkVlXkVkVkVkVkVkVkVlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVfqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXlXkVkVkVkVkVlXlXkVkVlXkVkVkVkVlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafqkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXlXlXkVlXlXlXkVkVlXlXlXlXkVlXlXlXlXlXkVlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVlXkVkVkVkVkVlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVlXlXlXlXlXlYlYlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlZlXlXlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVlXlXmbmamdmcmcmcmfmemalXlXmgmhlZlZlZlZlZlZlZlZlZlZlZlZlZlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacvcvcvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVlXlXmimcmcmcmcmcmcmcmdmamilXlZlZmjlZmklZlZlZlZlZmklZmjlZlZlXlXlXlXkVkVkVkVlXkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznknknkmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVlXlXlXmimcmcmcmcmcmcmlmcmmmilXlXlXmnmnmnmnmnmnmnmnmnmnmnmolZlZlXlXlXlXkVkVlXlXlXkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamLnnnmncmLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVlXlXlXlXmimpmpmimimimimimimimilXlXlXmnmqmqmqmrmtmsmnmumqmnmvmnlZlZlXlXlXkVkVkVkVlXkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznonpaznpnqmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlXlXlXlXmcmclXlXlXlXlXlXlXlXlXlXlXmnmwmwmwmwmwmwmxmwmwmymzmnlZlZlXlXlXlXlXkVkVkVlXkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamInrnomTnsnsnqmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlZlZmnmnmAmwmnmnmnmnmnmBmnmnmnmnmnmnmCmCmDmwmwmwmnmxmEmnmnmnmjlZlZlXlXlXlXlXkVkVlXkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHaaaamHmHmHmHmHntnvnumHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXmglZmnmwmwmwmFmwmGmnmSmSnhmVmwnimnmnmnmnmnmnmnmxmnmwnlnjnwmnlZlZlZlXlXlXlXlXkVlXlXkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmImImHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafqkVkVkVkVlXlXlZnynxmnmGmzmwmwmwmzmxmwmSmSnhnhmwmxmwmwmwnzmwmwmwmnmwmwnAmwmnmolZlXlXlXkVkVlXlXlXkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVlXlXlXlZlZlZmnmnmnnBnCmwmnmnmwmwmSmnmnmxmnnDmwmwmwnEmwnFmnmwnimwnimnlZlZlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmImIaaaaczmKmKmLmLmKmKmKmKmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVlXlXlXlXlZmjmnmwmwmwmwmwmnmnmnmnmnmnnGmwmnnFnFmwmwmwmwnFmnmymnnHmnmnlZlZlXlXkVkVlXkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmIczmKmNmImOazazmPmPmQazmRdlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXlZlZmnnImwmwmwmwmnmCnJnFmnnKmwmwmnmnnLmnmnmxmnmnmnmwmwnJmCmnlZlZlXlXlXlXlXkVkVkVkVkVkVkVkVkVkVkVfqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmTazazazazazmUazmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlZlZmnnMmwmwmwnNmnmwmwmwmxmwmwmwmxmwmwnOmFmwmwmwmxmwmwmwmwmnlZlZlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmWmXmYazmZmUazmUazmUmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlZnxnQnPmwmwmwmwmxmwmwnEmnnOmwmwmnmwmwmwmwmwmwnRmnnimrnSmwmnmolZlZlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHnaaznbazncazmOazazazmUmRehaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXlZlZmnnTnOmwmwnOmnnUmxmnmnmnnVmnmnnWnYnXnZnZmwoamnmnmnmnobmnmjlZlXlXlXlXmilXkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHndmKneaznfazazngmPmPazmRhZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVlXlXlXlZlZmjmnmnmnmxmnmnmnocmwmFmrodofoemnmwognXoiohmwojolokonomoomnlZlZlXlXlXlZlZlZmikVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHndmKmKmLmLmKmKmKmKmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXlZlZmvmzmymwmwopmnoqmwmwmwmwosorouotowovouoxmxmnmnolmnoyozmnlZlZlXlXlZlZmilZlZkVkVkVlXkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXlZlZmnmnoAmwnEmwmxmwnOmwnWmwoCoBoEoDoGoFoHoBmwmwnzoImnoJoKmnlZlZlXlXmilZlXlZlZkVkVmilXlZkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaamHmHmHmHmHmImImHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlZlZnxmnmCmwmwnNoLmwmwmwoNoMoPoOoRoQoToSoSoUoRoVmwnAmnoWoXmnmolZlXlXlZlZlXlXlZkVkVkVlZlZkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmImImImHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlZlZlZmnmnmnmxmnmnoYnXoZmwpapboBpcmwogmwmwpdmwmwmwmwmnobmnmnlZlZlXlXlZlXlXlXlZlZkVlXmilXlZkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamImImHmImHmHmImImIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVlXlXlXlZlZmjlZpemnmwmwmnpfmnmnmxpgmnphoupiowotoupjnXnXmwpkmnmwnOmnlZlZpmplpnlXlZlZlZlZmilXkVlXkVkVkVkVfqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHaaaaaaaaaaaamImHmHmHmHmHmHmIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafqkVkVkVkVlXlXlXlZlZlZlZlZmnnEmwmFmwmwmnmwpomnoYnXnXppmwpqmnmnmnmxmnmnprpsmnmymnpmptpumilZmilXlZlXlZlZlXkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVlXlXlXlXlXlXlXlZlZmnmnnFpwpvmwmxmwpamxmwmwmwpxnWmwmxmwmFmwnhmxmwmwmymzpypApzpnlXlZlXlZlZlZlXlZlXlXkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVlXlXlXlXlXlXlZlZmnmnmnmnmnmnpBpamnmwmwnOmwmwmwmnnOmwmwmwmBmwmwmnmymnpmpmpClXlZlZlZlXlZlXlZmikVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVlXkVlXlXlXlZmjlZpelZlZlZmnmnpgmnmnmxmnmxmnmnmnmnnFmwmwmnmCmCmnlZlZlXlXlXkVlZlXmilXlZlXlZlXkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVlXlXlXlZlZmglZlZlZlZmvpDmymwmwmnmwnKnFnFmnnFmwnEmnmnmnmnlZlZlXlXlZlXkVkVlZkVlZlZlZkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVlXlXkVlXlXlZpElZlZlZlZmnpgmnpFmwmxnEmwmwmwmxmwmwmwmnlZlZpelZlZlXlXlZlZkVkVkVkVlZlZkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVlXlXlZlZlZlZmjlZpepGmnmnmnmnmnmnmnmwmnmwmwnOmnlZlZlZlZlZlXlXlZmikVkVkVkVlZkVkVkVkVkVkVkVfqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVlXlXlXlXlXlXlZlZlZlZlZlZpelZlZlZlZmnmnmnmnmnmnmnlZlZmglZlXlXlXlZkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafqkVkVkVkVkVkVkVkVkVlXlXlXlXlXlXlXlXlXlXlXlXlZlZlZlZlZmjlZlZpelZlZlZpemjpHlZlXlXlXlXkVlXkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVlXlXkVkVlXlXlXlXlXlXlXlXlXlXlZlZlZlZlZlZlZlZlZlZlZlZlXlXlXlXlXkVkVlXkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVlXkVkVkVlXlXlXkVkVlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXkVkVlXkVkVlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXlXlXlXkVkVlXlXlXkVkVlXlXlXkVkVlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXkVkVkVkVkVkVlXlXkVkVlXlXlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVlXlXkVkVkVkVlXkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadukVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVkVduaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadududududududududududufqdududududududududufqdudududududududududududududufqdududududududududufqdudududududududududuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 3fcf79fe8d8..ede0351993b 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -33,7 +33,6 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) if(!armor) armor = list(melee = 25, bullet = 10, laser = 10, energy = 100, bomb = 0, bio = 100, rad = 100) ..() - SSair.atmos_machinery += src if(!pipe_color) pipe_color = color @@ -42,6 +41,10 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new()) if(!pipe_color_check(pipe_color)) pipe_color = null +/obj/machinery/atmospherics/Initialize() + . = ..() + SSair.atmos_machinery += src + /obj/machinery/atmospherics/proc/atmos_init() if(can_unwrench) stored = new(src, make_from = src) diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index 11ecc8f10e3..df4e8b47f31 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -181,4 +181,4 @@ /obj/effect/hotspot/Crossed(mob/living/L) ..() if(isliving(L)) - L.fire_act() \ No newline at end of file + L.fire_act() diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index a8f35105cd8..f1475bb2605 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -552,4 +552,4 @@ turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space else if(!air.check_turf_total(enemy_tile)) excited = 1 - SSair.active_turfs |= src \ No newline at end of file + SSair.active_turfs |= src diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index c244dc0c7a7..686bc3e1759 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -32,11 +32,10 @@ #define CANWEAKEN 2 #define CANPARALYSE 4 #define CANPUSH 8 -#define LEAPING 16 -#define PASSEMOTES 32 //Mob has a cortical borer or holders inside of it that need to see emotes. -#define GOTTAGOFAST 64 -#define GOTTAGOREALLYFAST 128 -#define IGNORESLOWDOWN 256 +#define PASSEMOTES 16 //Mob has a cortical borer or holders inside of it that need to see emotes. +#define GOTTAGOFAST 32 +#define GOTTAGOREALLYFAST 64 +#define IGNORESLOWDOWN 128 #define GODMODE 4096 #define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath #define XENO_HOST 16384 //Tracks whether we're gonna be a baby alien's mummy. diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 0ec1567f86d..cd6688d095f 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -101,7 +101,6 @@ //turf-only flags #define NOJAUNT 1 -#define RPD_ALLOWED_HERE 2//By default, RPD is disabled on turfs. //ITEM INVENTORY SLOT BITMASKS #define SLOT_OCLOTHING 1 diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm index aba6e6baea9..65b7f0f24d0 100644 --- a/code/__DEFINES/genetics.dm +++ b/code/__DEFINES/genetics.dm @@ -142,4 +142,5 @@ #define VIRUSIMMUNE 14 #define NOCRITDAMAGE 15 #define RESISTHOT 16 -#define RESISTCOLD 17 \ No newline at end of file +#define RESISTCOLD 17 +#define NO_EXAMINE 18 \ No newline at end of file diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 29392997893..60252fc11ba 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -27,6 +27,7 @@ #define PLANT_WEED_HUD "22"// Weed level #define DIAG_TRACK_HUD "23"// Mech tracking beacon #define DIAG_PATH_HUD "24"//Bot path indicators +#define GLAND_HUD "25"//Gland indicators for abductors //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior @@ -54,6 +55,7 @@ #define ANTAG_HUD_CHANGELING 16 #define ANTAG_HUD_VAMPIRE 17 #define ANTAG_HUD_ABDUCTOR 18 +#define DATA_HUD_ABDUCTOR 19 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 5b38b592ac6..809567a0a75 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -81,4 +81,15 @@ #define TARGET_DEPT_SEC 2 #define TARGET_DEPT_MED 3 #define TARGET_DEPT_SCI 4 -#define TARGET_DEPT_ENG 5 \ No newline at end of file +#define TARGET_DEPT_ENG 5 + +// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! +// These are warning defines, they should trigger before the state, not after. +#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. +#define SUPERMATTER_INACTIVE 0 // No or minimal energy +#define SUPERMATTER_NORMAL 1 // Normal operation +#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE +#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged +#define SUPERMATTER_DANGER 4 // Integrity < 75% +#define SUPERMATTER_EMERGENCY 5 // Integrity < 50% +#define SUPERMATTER_DELAMINATING 6 // Pretty obvious, Integrity < 25% diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index f3870c25d30..67a187c45db 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -1,6 +1,16 @@ //Object specific defines #define CANDLE_LUM 3 //For how bright candles are +//Directions (already defined on BYOND natively, purely here for reference) +//#define NORTH 1 +//#define SOUTH 2 +//#define EAST 4 +//#define WEST 8 +//#define NORTHEAST 5 +//#define SOUTHEAST 6 +//#define NORTHWEST 9 +//#define SOUTHWEST 10 + //Security levels #define SEC_LEVEL_GREEN 0 #define SEC_LEVEL_BLUE 1 @@ -360,4 +370,4 @@ // used for alternate_option #define GET_RANDOM_JOB 0 #define BE_ASSISTANT 1 -#define RETURN_TO_LOBBY 2 +#define RETURN_TO_LOBBY 2 \ No newline at end of file diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 023ebe426d9..1d47ae409b3 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -130,7 +130,31 @@ #define EYE_SHINE_THRESHOLD 6 //dark_view threshold past which a humanoid's eyes will 'shine' in the dark. //Human sub-species -#define isabductor(A) (is_species(A, "Abductor")) +#define isshadowling(A) (is_species(A, /datum/species/shadow/ling)) +#define isshadowlinglesser(A) (is_species(A, /datum/species/shadow/ling/lesser)) +#define isabductor(A) (is_species(A, /datum/species/abductor)) +#define isgolem(A) (is_species(A, /datum/species/golem)) +#define ismonkeybasic(A) (is_species(A, /datum/species/monkey)) +#define isfarwa(A) (is_species(A, /datum/species/monkey/tajaran)) +#define iswolpin(A) (is_species(A, /datum/species/monkey/vulpkanin)) +#define isneara(A) (is_species(A, /datum/species/monkey/skrell)) +#define isstok(A) (is_species(A, /datum/species/monkey/unathi)) +#define isplasmaman(A) (is_species(A, /datum/species/plasmaman)) +#define isshadowperson(A) (is_species(A, /datum/species/shadow)) +#define isskeleton(A) (is_species(A, /datum/species/skeleton)) +#define ishumanbasic(A) (is_species(A, /datum/species/human)) +#define isunathi(A) (is_species(A, /datum/species/unathi)) +#define istajaran(A) (is_species(A, /datum/species/tajaran)) +#define isvulpkanin(A) (is_species(A, /datum/species/vulpkanin)) +#define isskrell(A) (is_species(A, /datum/species/skrell)) +#define isvox(A) (is_species(A, /datum/species/vox)) +#define isvoxarmalis(A) (is_species(A, /datum/species/vox/armalis)) +#define iskidan(A) (is_species(A, /datum/species/kidan)) +#define isslimeperson(A) (is_species(A, /datum/species/slime)) +#define isgrey(A) (is_species(A, /datum/species/grey)) +#define isdiona(A) (is_species(A, /datum/species/diona)) +#define ismachine(A) (is_species(A, /datum/species/machine)) +#define isdrask(A) (is_species(A, /datum/species/drask)) #define isanimal(A) (istype((A), /mob/living/simple_animal)) #define iscorgi(A) (istype((A), /mob/living/simple_animal/pet/corgi)) diff --git a/code/__DEFINES/pipes.dm b/code/__DEFINES/pipes.dm new file mode 100644 index 00000000000..c855a5e4260 --- /dev/null +++ b/code/__DEFINES/pipes.dm @@ -0,0 +1,76 @@ +//Atmospherics pipes + +#define PIPE_SIMPLE_STRAIGHT 0 +#define PIPE_SIMPLE_BENT 1 +#define PIPE_HE_STRAIGHT 2 +#define PIPE_HE_BENT 3 +#define PIPE_CONNECTOR 4 +#define PIPE_MANIFOLD 5 +#define PIPE_JUNCTION 6 +#define PIPE_UVENT 7 +#define PIPE_MVALVE 8 +#define PIPE_PUMP 9 +#define PIPE_SCRUBBER 10 +#define PIPE_INSULATED_STRAIGHT 11 +#define PIPE_INSULATED_BENT 12 +#define PIPE_GAS_FILTER 13 +#define PIPE_GAS_MIXER 14 +#define PIPE_PASSIVE_GATE 15 +#define PIPE_VOLUME_PUMP 16 +#define PIPE_HEAT_EXCHANGE 17 +#define PIPE_TVALVE 18 +#define PIPE_MANIFOLD4W 19 +#define PIPE_CAP 20 +#define PIPE_OMNI_MIXER 21 +#define PIPE_OMNI_FILTER 22 +#define PIPE_UNIVERSAL 23 +#define PIPE_SUPPLY_STRAIGHT 24 +#define PIPE_SUPPLY_BENT 25 +#define PIPE_SCRUBBERS_STRAIGHT 26 +#define PIPE_SCRUBBERS_BENT 27 +#define PIPE_SUPPLY_MANIFOLD 28 +#define PIPE_SCRUBBERS_MANIFOLD 29 +#define PIPE_SUPPLY_MANIFOLD4W 30 +#define PIPE_SCRUBBERS_MANIFOLD4W 31 +#define PIPE_SUPPLY_CAP 32 +#define PIPE_SCRUBBERS_CAP 33 +#define PIPE_INJECTOR 34 +#define PIPE_DVALVE 35 +#define PIPE_DP_VENT 36 +#define PIPE_PASV_VENT 37 +#define PIPE_DTVALVE 38 +#define PIPE_CIRCULATOR 39 +#define PIPE_GAS_SENSOR 98 +#define PIPE_METER 99 + +//Disposals pipes + +#define PIPE_DISPOSALS_STRAIGHT 100 +#define PIPE_DISPOSALS_BENT 101 +#define PIPE_DISPOSALS_JUNCTION_RIGHT 102 +#define PIPE_DISPOSALS_JUNCTION_LEFT 103 +#define PIPE_DISPOSALS_Y_JUNCTION 104 +#define PIPE_DISPOSALS_TRUNK 105 +#define PIPE_DISPOSALS_BIN 106 +#define PIPE_DISPOSALS_OUTLET 107 +#define PIPE_DISPOSALS_CHUTE 108 +#define PIPE_DISPOSALS_SORT_RIGHT 109 +#define PIPE_DISPOSALS_SORT_LEFT 110 + + +//RPD stuff + +#define RPD_ATMOS_MODE 1 +#define RPD_DISPOSALS_MODE 2 +#define RPD_ROTATE_MODE 3 +#define RPD_FLIP_MODE 4 +#define RPD_DELETE_MODE 5 + +#define RPD_ATMOS_PIPING 1 +#define RPD_SUPPLY_PIPING 2 +#define RPD_SCRUBBERS_PIPING 3 +#define RPD_DEVICES 4 +#define RPD_HEAT_PIPING 5 + +#define PIPETYPE_ATMOS 1 +#define PIPETYPE_DISPOSAL 2 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index d0e1feb3d62..a068bb8604e 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -38,18 +38,23 @@ language_keys[".[lowertext(L.key)]"] = L language_keys["#[lowertext(L.key)]"] = L - var/list/paths = subtypesof(/datum/species) var/rkey = 0 - for(var/T in paths) - var/datum/species/S = new T + for(var/spath in subtypesof(/datum/species)) + var/datum/species/S = new spath() S.race_key = ++rkey //Used in mob icon caching. - all_species[S.name] = S + GLOB.all_species[S.name] = S if(IS_WHITELISTED in S.species_traits) whitelisted_species += S.name init_subtypes(/datum/crafting_recipe, crafting_recipes) + //Pipe list building + init_subtypes(/datum/pipes, GLOB.construction_pipe_list) + for(var/D in GLOB.construction_pipe_list) + var/datum/pipes/P = D + if(P.rpd_dispensable) + GLOB.rpd_pipe_list += list(list("pipe_name" = P.pipe_name, "pipe_id" = P.pipe_id, "pipe_type" = P.pipe_type, "pipe_category" = P.pipe_category, "orientations" = P.orientations, "pipe_icon" = P.pipe_icon, "bendy" = P.bendy)) return 1 /* // Uncomment to debug chemical reaction list. diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 8628e6957cf..3d495964cb0 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -178,7 +178,7 @@ proc/random_name(gender, species = "Human") var/datum/species/current_species if(species) - current_species = all_species[species] + current_species = GLOB.all_species[species] if(!current_species || current_species.name == "Human") if(gender==FEMALE) @@ -373,11 +373,11 @@ This is always put in the attack log. if(progress) qdel(progbar) -/proc/is_species(A, species_name) +/proc/is_species(A, species_datum) . = FALSE if(ishuman(A)) var/mob/living/carbon/human/H = A - if(H.get_species() == species_name) + if(H.dna && istype(H.dna.species, species_datum)) . = TRUE /proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE, list/extra_args) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 5fb559651d5..8e9b5f93691 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -96,9 +96,12 @@ if(non_whitespace) return text //only accepts the text if it has some non-spaces // Used to get a sanitized input. -/proc/stripped_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN) - var/name = input(user, message, title, default) - return strip_html_properly(name, max_length) +/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as text|null + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) //Filters out undesirable characters from names /proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 35d271461df..1a9ccbe6c2b 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1497,6 +1497,10 @@ var/mob/dview/dview_mob = new /mob/dview/New() //For whatever reason, if this isn't called, then BYOND will throw a type mismatch runtime when attempting to add this to the mobs list. -Fox +/mob/dview/Destroy() + // should never be deleted + return QDEL_HINT_LETMELIVE + /proc/IsValidSrc(A) if(istype(A, /datum)) var/datum/D = A @@ -1962,4 +1966,4 @@ var/mob/dview/dview_mob = new CRASH(msg) /proc/pass() - return \ No newline at end of file + return diff --git a/code/_globalvars/lists/fortunes.dm b/code/_globalvars/lists/fortunes.dm new file mode 100644 index 00000000000..546e33f913f --- /dev/null +++ b/code/_globalvars/lists/fortunes.dm @@ -0,0 +1,57 @@ +GLOBAL_LIST_INIT(fortune_cookie_messages, list("If you feel you are right, stand firmly by your convictions.", +"A stranger is a friend you have not spoken to yet.", +"Yesterday, you said tomorrow. Just do it!", +"Do, or do not. There is no try.", +"Fear leads to anger. Anger leads to hate. Hate leads to suffering.", +"Luck always favours the prepared mind.", +"A smile is your passport into the hearts of others.", +"Hard work pays off in the future, laziness pays off now.", +"Change can hurt, but it leads a path to something better.", +"If winter comes soon, can spring be far behind?", +"Love with your heart; use your head for everything else.", +"The man on the top of the mountain did not fall there.", +"The greatest risk is not taking one.", +"Strategy without tactics is the slowest route to victory.
Tactics without strategy is the noise before defeat.", +"If you are far from the enemy, make him believe you are near.", +"He who knows when he can fight and when he cannot, will be victorious.", +"A clever person solves a problem. A wise person avoids it.", +"When fighting for freedom, never wear new pants.", +"If you want the rainbow, you must put up with the rain.", +"Get ready! Good fortune comes in bunches.", +"An exciting opportunity lies ahead of you.", +"A journey of a thousand miles begins with a single step.", +"Expect the unexpected.", +"Live this day as if it were your last.", +"Remember the compliments you receive; forget the insults.", +"A chance meeting opens new doors to success and friendship.", +"Failure is the mother of success.", +"A rolling stone gathers no moss.", +"When life gives you lemons, make lemonade.", +"You will inherit some money or a small piece of land.", +"Happy news is on its way to you.", +"A pleasant surprise is in store for you.", +"You will be invited to an exciting event.", +"Keep your plans secret for now.", +"You will live a long, happy life.", +"When one door closes, another opens.", +"Life is a canvas, and you are its painter.", +"Failure to prepare is to prepare to fail.", +"Beware the robot that thinks for itself.", +"The early bird gets the worm, but the second mouse gets the cheese.", +"Don't pursue happiness - create it.", +"Courage is not the absence of fear; it is the conquest of it.", +"All things are difficult before they are easy.", +"A ship in harbour is safe, but that's not why ships are built.", +"Hardly anyone knows how much is gained by ignoring the future.", +"The wise man is the one that makes you think that he is dumb.", +"Hatred outlives the hateful.", +"The fatal flaw in every plan is the assumption that you know more than the enemy", +"A journey of a thousand miles begins with a single step.", +"Dig the well before you are thirsty.", +"Be not afraid of growing slowly, be afraid only of standing still.", +"Do not remove a fly from your friend's forehead with a hatchet.", +"A foolish man listens to his heart.
A wise man listens to cookies.", +"Thank you! But your fortune is in another cookie!", +"The greatest danger could be your stupidity.", +"He who laughs at himself never runs out of things to laugh at.", +"Help! I'm being held prisoner in a Nanotrasen bakery!")) diff --git a/code/_globalvars/lists/misc.dm b/code/_globalvars/lists/misc.dm index 148488a6ddf..65bffa7515a 100644 --- a/code/_globalvars/lists/misc.dm +++ b/code/_globalvars/lists/misc.dm @@ -31,4 +31,6 @@ var/list/round_end_sounds = list( // Maps available round end sounds to their du 'sound/goonstation/misc/newround2.ogg' = 14.8 SECONDS ) -GLOBAL_LIST(station_level_space_turfs) \ No newline at end of file +GLOBAL_LIST(station_level_space_turfs) + +#define EGG_LAYING_MESSAGES list("lays an egg.", "squats down and croons.", "begins making a huge racket.", "begins clucking raucously.") \ No newline at end of file diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 28ebfca6b1b..7cc456f9440 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -1,5 +1,5 @@ //Languages/species/whitelist. //Languages and species fit with mobs right -var/global/list/all_species[0] +GLOBAL_LIST_EMPTY(all_species) var/global/list/all_languages[0] var/global/list/language_keys[0] // Table of say codes for all languages var/global/list/all_superheroes[0] diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index 959c930bbf1..f403695b0f6 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -9,7 +9,6 @@ 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") var/list/adjectives = file2list("config/names/adjectives.txt") diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 5a025702877..82d4c113997 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -43,4 +43,4 @@ var/global/list/meteor_list = list() //list of all meteors var/global/list/poi_list = list() //list of points of interest for observe/follow var/global/list/active_jammers = list() // List of active radio jammers -var/global/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing. \ No newline at end of file +var/global/list/active_diseases = list() //List of Active disease in all mobs; purely for quick referencing. diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 26fb60335c8..29fef068cce 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -161,3 +161,8 @@ //1 = standard hud //2 = reduced hud (just hands and intent switcher) //3 = no hud (for screenshots) + + +#define HUD_LAYER_SCREEN 20 + +#define HUD_LAYER_BUILDMODE 30 diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index fd0c91ded3a..a44f5d2e5a8 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -1,8 +1,3 @@ -#define FULLSCREEN_LAYER 18 -#define DAMAGE_LAYER FULLSCREEN_LAYER + 0.1 -#define BLIND_LAYER DAMAGE_LAYER + 0.1 -#define CRIT_LAYER BLIND_LAYER + 0.1 - /mob var/list/screens = list() @@ -68,11 +63,11 @@ /obj/screen/fullscreen/brute icon_state = "brutedamageoverlay" - layer = DAMAGE_LAYER + layer = UI_DAMAGE_LAYER /obj/screen/fullscreen/oxy icon_state = "oxydamageoverlay" - layer = DAMAGE_LAYER + layer = UI_DAMAGE_LAYER /obj/screen/fullscreen/crit icon_state = "passage" @@ -107,5 +102,4 @@ #undef FULLSCREEN_LAYER #undef BLIND_LAYER -#undef DAMAGE_LAYER #undef CRIT_LAYER diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index 29d7295feac..8cf38a88eb9 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -1,3 +1,15 @@ +/mob/living/simple_animal/create_mob_hud() + hud_used = new /datum/hud/simple_animal(src) + +/datum/hud/simple_animal/New(mob/user) + ..() + var/obj/screen/using + using = new /obj/screen/act_intent/simple_animal() + using.icon_state = mymob.a_intent + static_inventory += using + action_intent = using + + /mob/living/simple_animal/pet/create_mob_hud() if(client && !hud_used) hud_used = new /datum/hud/corgi(src) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 5bf3a483cd8..b61cb69e0e4 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -9,7 +9,7 @@ /obj/screen name = "" icon = 'icons/mob/screen_gen.dmi' - layer = 20 + layer = HUD_LAYER_SCREEN plane = HUD_PLANE unacidable = 1 var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. @@ -71,17 +71,14 @@ if(ishuman(usr)) var/_x = text2num(params2list(params)["icon-x"]) var/_y = text2num(params2list(params)["icon-y"]) - if(_x<=16 && _y<=16) usr.a_intent_change(INTENT_HARM) else if(_x<=16 && _y>=17) usr.a_intent_change(INTENT_HELP) else if(_x>=17 && _y<=16) usr.a_intent_change(INTENT_GRAB) - else if(_x>=17 && _y>=17) usr.a_intent_change(INTENT_DISARM) - else usr.a_intent_change("right") @@ -97,6 +94,11 @@ name = "run/walk toggle" icon_state = "running" + +/obj/screen/act_intent/simple_animal + icon = 'icons/mob/screen_simplemob.dmi' + screen_loc = ui_acti + /obj/screen/mov_intent/Click() if(iscarbon(usr)) var/mob/living/carbon/C = usr diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index bf481d4e747..0299a7ec2fc 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -17,7 +17,7 @@ return SendSignal(COMSIG_PARENT_ATTACKBY, W, user, params) /obj/attackby(obj/item/I, mob/living/user, params) - return ..() || I.attack_obj(src, user) + return ..() || (can_be_hit && I.attack_obj(src, user)) /mob/living/attackby(obj/item/I, mob/living/user, params) user.changeNext_move(CLICK_CD_MELEE) @@ -43,7 +43,7 @@ else return 1 - if(isscrewdriver(src) && M.get_species() == "Machine") + if(isscrewdriver(src) && ismachine(M)) if(!attempt_initiate_surgery(src, M, user)) return 0 else diff --git a/code/controllers/Processes/npcpool.dm b/code/controllers/Processes/npcpool.dm index 553801b42b8..945938852b4 100644 --- a/code/controllers/Processes/npcpool.dm +++ b/code/controllers/Processes/npcpool.dm @@ -31,6 +31,9 @@ DECLARE_GLOBAL_CONTROLLER(npcpool, npc_master) if(istype(toInsert, /mob/living/carbon/human/interactive)) botPool_l |= toInsert +/datum/controller/process/npcpool/proc/removeBot(toRemove) + botPool_l -= toRemove + /datum/controller/process/npcpool/statProcess() ..() stat(null, "T [botPool_l.len + botPool_l_non.len] | D [needsDelegate.len] | A [needsAssistant.len + needsHelp_non.len] | U [canBeUsed.len + canBeUsed_non.len]") diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index 9b056472bde..177e670d6c9 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -351,7 +351,7 @@ var/global/datum/controller/radio/radio_controller /datum/signal/proc/get_race(mob/M) if(ishuman(M)) var/mob/living/carbon/human/H = M - . = H.species.name + . = H.dna.species.name else if(isbrain(M)) var/mob/living/carbon/brain/B = M . = B.get_race() diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index b35bc300434..7f60fd0cac3 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -172,6 +172,9 @@ var/disable_away_missions = 0 // disable away missions var/disable_space_ruins = 0 //disable space ruins + var/extra_space_ruin_levels_min = 2 + var/extra_space_ruin_levels_max = 4 + var/ooc_allowed = 1 var/looc_allowed = 1 var/dooc_allowed = 1 @@ -581,6 +584,14 @@ if("disable_cid_warn_popup") config.disable_cid_warn_popup = 1 + if("extra_space_ruin_levels_min") + var/vvalue = text2num(value) + config.extra_space_ruin_levels_min = max(vvalue, 0) + + if("extra_space_ruin_levels_max") + var/vvalue = text2num(value) + config.extra_space_ruin_levels_max = max(vvalue, 0) + if("max_loadout_points") config.max_loadout_points = text2num(value) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 7606149c39d..93e5780e1a7 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -46,13 +46,12 @@ var/global/pipe_processing_killed = 0 seedRuins(level_name_to_num(EMPTY_AREA), rand(0, 3), /area/space, space_ruins_templates) log_startup_progress("Loaded random space levels in [stop_watch(timer)]s.") - // We'll keep this around for the time when we finally expunge all - // code that checks on hard-defined z positions + // load in extra levels of space ruins - // var/num_extra_space = 6 - // for(var/i = 1, i <= num_extra_space, i++) - // var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED) - // seedRuins(zlev, rand(0, 3), /area/space, space_ruins_templates) + var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max) + for(var/i = 1, i <= num_extra_space, i++) + var/zlev = space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED) + seedRuins(zlev, rand(0, 3), /area/space, space_ruins_templates) space_manager.do_transition_setup() diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index d46ec164e35..9f21eb23e2d 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -66,8 +66,8 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/Initialize(timeofday) setup_overlays() // Assign icons and such for gas-turf-overlays setup_allturfs() - setup_atmos_machinery() - setup_pipenets() + setup_atmos_machinery(machines) + setup_pipenets(machines) ..() @@ -316,11 +316,17 @@ SUBSYSTEM_DEF(air) ET.excited = 1 . += ET -/datum/controller/subsystem/air/proc/setup_atmos_machinery() +/datum/controller/subsystem/air/proc/setup_atmos_machinery(var/list/machines_to_init) var/watch = start_watch() - var/count = 0 log_startup_progress("Initializing atmospherics machinery...") - for(var/obj/machinery/atmospherics/A in machines) + var/count = _setup_atmos_machinery(machines_to_init) + log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.") + +// this underscored variant is so that we can have a means of late initing +// atmos machinery without a loud announcement to the world +/datum/controller/subsystem/air/proc/_setup_atmos_machinery(var/list/machines_to_init) + var/count = 0 + for(var/obj/machinery/atmospherics/A in machines_to_init) A.atmos_init() count++ if(istype(A, /obj/machinery/atmospherics/unary/vent_pump)) @@ -329,19 +335,25 @@ SUBSYSTEM_DEF(air) else if(istype(A, /obj/machinery/atmospherics/unary/vent_scrubber)) var/obj/machinery/atmospherics/unary/vent_scrubber/T = A T.broadcast_status() - log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.") + return count //this can't be done with setup_atmos_machinery() because // all atmos machinery has to initalize before the first // pipenet can be built. -/datum/controller/subsystem/air/proc/setup_pipenets() +/datum/controller/subsystem/air/proc/setup_pipenets(var/list/pipes) var/watch = start_watch() - var/count = 0 log_startup_progress("Initializing pipe networks...") - for(var/obj/machinery/atmospherics/machine in machines) + var/count = _setup_pipenets(pipes) + log_startup_progress(" Initialized [count] pipenets in [stop_watch(watch)]s.") + +// An underscored wrapper that exists for the same reason +// the machine init wrapper does +/datum/controller/subsystem/air/proc/_setup_pipenets(var/list/pipes) + var/count = 0 + for(var/obj/machinery/atmospherics/machine in pipes) machine.build_network() count++ - log_startup_progress(" Initialized [count] pipenets in [stop_watch(watch)]s.") + return count /datum/controller/subsystem/air/proc/setup_overlays() plmaster = new /obj/effect/overlay() diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index c3943ea9163..54adebf5125 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -23,7 +23,7 @@ SUBSYSTEM_DEF(atoms) -/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) +/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms, noisy = TRUE) if(initialized == INITIALIZATION_INSSATOMS) return @@ -32,7 +32,10 @@ SUBSYSTEM_DEF(atoms) LAZYINITLIST(late_loaders) var/watch = start_watch() - log_startup_progress("Initializing atoms...") + if(noisy) + log_startup_progress("Initializing atoms...") + else + log_debug("Initializing atoms...") var/count var/list/mapload_arg = list(TRUE) if(atoms) @@ -40,7 +43,7 @@ SUBSYSTEM_DEF(atoms) count = atoms.len for(var/I in atoms) var/atom/A = I - if(!A.initialized) + if(A && !A.initialized) if(InitAtom(I, mapload_arg)) atoms -= I CHECK_TICK @@ -52,18 +55,27 @@ SUBSYSTEM_DEF(atoms) ++count CHECK_TICK - log_startup_progress(" Initialized [count] atoms in [stop_watch(watch)]s") + if(noisy) + log_startup_progress(" Initialized [count] atoms in [stop_watch(watch)]s") + else + log_debug(" Initialized [count] atoms in [stop_watch(watch)]s") pass(count) initialized = INITIALIZATION_INNEW_REGULAR if(late_loaders.len) watch = start_watch() - log_startup_progress("Late-initializing atoms...") + if(noisy) + log_startup_progress("Late-initializing atoms...") + else + log_debug("Late-initializing atoms...") for(var/I in late_loaders) var/atom/A = I A.LateInitialize() - log_startup_progress(" Late initialized [late_loaders.len] atoms in [stop_watch(watch)]s") + if(noisy) + log_startup_progress(" Late initialized [late_loaders.len] atoms in [stop_watch(watch)]s") + else + log_debug(" Late initialized [late_loaders.len] atoms in [stop_watch(watch)]s") late_loaders.Cut() if(atoms) @@ -117,4 +129,4 @@ SUBSYSTEM_DEF(atoms) if(initialized == INITIALIZATION_INNEW_MAPLOAD) InitializeAtoms() old_initialized = SSatoms.old_initialized - BadInitializeCalls = SSatoms.BadInitializeCalls \ No newline at end of file + BadInitializeCalls = SSatoms.BadInitializeCalls diff --git a/code/datums/action.dm b/code/datums/action.dm index e49002e8e9d..e0634527104 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -127,7 +127,7 @@ var/obj/item/I = target var/old_layer = I.layer var/old_plane = I.plane - I.layer = 21 + I.layer = HUD_LAYER_SCREEN + 1 I.plane = HUD_PLANE current_button.overlays += I I.layer = old_layer diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 0da932d1575..775a8667b3f 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -106,7 +106,7 @@ /datum/component/proc/_GetInverseTypeList(our_type = type) #if DM_VERSION >= 513 - #warning 512 is definitely stable now, remove the old code + #warn 512 is definitely stable now, remove the old code #endif #if DM_VERSION < 512 diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 1a22131d55f..4fc2522ce65 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -280,7 +280,7 @@ var/record_id_num = 1001 G.fields["p_stat"] = "Active" G.fields["m_stat"] = "Stable" G.fields["sex"] = capitalize(H.gender) - G.fields["species"] = H.get_species() + G.fields["species"] = H.dna.species.name G.fields["photo"] = get_id_photo(H) G.fields["photo-south"] = "'data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = SOUTH))]'" G.fields["photo-west"] = "'data:image/png;base64,[icon2base64(icon(G.fields["photo"], dir = WEST))]'" @@ -357,7 +357,7 @@ var/record_id_num = 1001 temp = new /icon(icobase, "groin_[g]") preview_icon.Blend(temp, ICON_OVERLAY) var/head = "head" - if(head_organ.alt_head && head_organ.species.bodyflags & HAS_ALT_HEADS) + if(head_organ.alt_head && head_organ.dna.species.bodyflags & HAS_ALT_HEADS) var/datum/sprite_accessory/alt_heads/alternate_head = alt_heads_list[head_organ.alt_head] if(alternate_head.icon_state) head = alternate_head.icon_state @@ -368,7 +368,7 @@ var/record_id_num = 1001 if(H.body_accessory && istype(H.body_accessory, /datum/body_accessory/tail)) temp = new/icon("icon" = H.body_accessory.icon, "icon_state" = H.body_accessory.icon_state) preview_icon.Blend(temp, ICON_OVERLAY) - else if(H.tail && H.species.bodyflags & HAS_TAIL) + else if(H.tail && H.dna.species.bodyflags & HAS_TAIL) temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.tail]_s") preview_icon.Blend(temp, ICON_OVERLAY) @@ -376,19 +376,19 @@ var/record_id_num = 1001 preview_icon.Blend(E.get_icon(), ICON_OVERLAY) // Skin tone - if(H.species.bodyflags & HAS_SKIN_TONE) + if(H.dna.species.bodyflags & HAS_SKIN_TONE) if(H.s_tone >= 0) preview_icon.Blend(rgb(H.s_tone, H.s_tone, H.s_tone), ICON_ADD) else preview_icon.Blend(rgb(-H.s_tone, -H.s_tone, -H.s_tone), ICON_SUBTRACT) // Proper Skin color - Fix, you can't have HAS_SKIN_TONE *and* HAS_SKIN_COLOR - if(H.species.bodyflags & HAS_SKIN_COLOR) + if(H.dna.species.bodyflags & HAS_SKIN_COLOR) preview_icon.Blend(H.skin_colour, ICON_ADD) //Tail Markings var/icon/t_marking_s - if(H.species.bodyflags & HAS_TAIL_MARKINGS) + if(H.dna.species.bodyflags & HAS_TAIL_MARKINGS) var/tail_marking = H.m_styles["tail"] var/datum/sprite_accessory/tail_marking_style = marking_styles_list[tail_marking] if(tail_marking_style && tail_marking_style.species_allowed) @@ -398,8 +398,8 @@ var/record_id_num = 1001 preview_icon.Blend(t_marking_s, ICON_OVERLAY) var/icon/face_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = "bald_s") - if(!(H.species.bodyflags & NO_EYES)) - var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.species ? H.species.eyes : "eyes_s") + if(!(H.dna.species.bodyflags & NO_EYES)) + var/icon/eyes_s = new/icon("icon" = 'icons/mob/human_face.dmi', "icon_state" = H.dna.species ? H.dna.species.eyes : "eyes_s") if(!eyes_organ) return eyes_s.Blend(eyes_organ.eye_colour, ICON_ADD) @@ -410,7 +410,7 @@ var/record_id_num = 1001 var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") // I'll want to make a species-specific proc for this sooner or later // But this'll do for now - if(head_organ.species.name == "Slime People") + if(istype(head_organ.dna.species, /datum/species/slime)) hair_s.Blend("[H.skin_colour]A0", ICON_AND) //A0 = 160 alpha. else hair_s.Blend(head_organ.hair_colour, ICON_ADD) @@ -424,7 +424,7 @@ var/record_id_num = 1001 face_s.Blend(hair_s, ICON_OVERLAY) //Head Accessory - if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") @@ -434,7 +434,7 @@ var/record_id_num = 1001 var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(head_organ.species.name == "Slime People") + if(istype(head_organ.dna.species, /datum/species/slime)) facial_s.Blend("[H.skin_colour]A0", ICON_ADD) //A0 = 160 alpha. else facial_s.Blend(head_organ.facial_colour, ICON_ADD) @@ -448,15 +448,15 @@ var/record_id_num = 1001 face_s.Blend(facial_s, ICON_OVERLAY) //Markings - if((H.species.bodyflags & HAS_HEAD_MARKINGS) || (H.species.bodyflags & HAS_BODY_MARKINGS)) - if(H.species.bodyflags & HAS_BODY_MARKINGS) //Body markings. + if((H.dna.species.bodyflags & HAS_HEAD_MARKINGS) || (H.dna.species.bodyflags & HAS_BODY_MARKINGS)) + if(H.dna.species.bodyflags & HAS_BODY_MARKINGS) //Body markings. var/body_marking = H.m_styles["body"] var/datum/sprite_accessory/body_marking_style = marking_styles_list[body_marking] if(body_marking_style && body_marking_style.species_allowed) var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s") b_marking_s.Blend(H.m_colours["body"], ICON_ADD) face_s.Blend(b_marking_s, ICON_OVERLAY) - if(H.species.bodyflags & HAS_HEAD_MARKINGS) //Head markings. + if(H.dna.species.bodyflags & HAS_HEAD_MARKINGS) //Head markings. var/head_marking = H.m_styles["head"] var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking] if(head_marking_style && head_marking_style.species_allowed) @@ -615,7 +615,7 @@ var/record_id_num = 1001 temp.Shift(EAST, H.body_accessory.pixel_x_offset) if(H.body_accessory.pixel_y_offset) temp.Shift(NORTH, H.body_accessory.pixel_y_offset) - if(H.species.bodyflags & HAS_SKIN_COLOR) + if(H.dna.species.bodyflags & HAS_SKIN_COLOR) temp.Blend(H.skin_colour, H.body_accessory.blend_mode) if(t_marking_s) temp.Blend(t_marking_s, ICON_OVERLAY) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index ae9a6df5b4f..70c783d634e 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -37,4 +37,8 @@ qdel(C, FALSE, TRUE) dc.Cut() - return QDEL_HINT_QUEUE \ No newline at end of file + return QDEL_HINT_QUEUE + + +/datum/nothing + // Placeholder object, used for ispath checks. Has to be defined to prevent errors, but shouldn't ever be created. \ No newline at end of file diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 9526a3e671a..27d92b085fd 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -781,6 +781,30 @@ log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") message_admins("[key_name_admin(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") + else if(href_list["makespeedy"]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + var/obj/A = locateUID(href_list["makespeedy"]) + if(!istype(A)) + return + A.var_edited = TRUE + A.makeSpeedProcess() + log_admin("[key_name(usr)] has made [A] speed process") + message_admins("[key_name(usr)] has made [A] speed process") + return TRUE + + else if(href_list["makenormalspeed"]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + var/obj/A = locateUID(href_list["makenormalspeed"]) + if(!istype(A)) + return + A.var_edited = TRUE + A.makeNormalProcess() + log_admin("[key_name(usr)] has made [A] process normally") + message_admins("[key_name(usr)] has made [A] process normally") + return TRUE + else if(href_list["addreagent"]) /* Made on /TG/, credit to them. */ if(!check_rights(R_DEBUG|R_ADMIN)) return @@ -986,14 +1010,15 @@ to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") return - var/new_species = input("Please choose a new species.","Species",null) as null|anything in all_species + var/new_species = input("Please choose a new species.","Species",null) as null|anything in GLOB.all_species if(!H) to_chat(usr, "Mob doesn't exist anymore") return - if(H.set_species(new_species)) - to_chat(usr, "Set species of [H] to [H.species].") + var/datum/species/S = GLOB.all_species[new_species] + if(H.set_species(S.type)) + to_chat(usr, "Set species of [H] to [H.dna.species].") H.regenerate_icons() message_admins("[key_name_admin(usr)] has changed the species of [key_name_admin(H)] to [new_species]") log_admin("[key_name(usr)] has changed the species of [key_name(H)] to [new_species]") @@ -1327,4 +1352,4 @@ if(href_list["listrefresh"]) debug_variables(locate(href_list["listrefresh"])) - return TRUE \ No newline at end of file + return TRUE diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index e39a592bc3b..1bbba44f78b 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -134,7 +134,7 @@ /mob/living/carbon/human/CanContractDisease(datum/disease/D) - if((VIRUSIMMUNE in species.species_traits) && !D.bypasses_immunity) + if((VIRUSIMMUNE in dna.species.species_traits) && !D.bypasses_immunity) return 0 for(var/thing in D.required_organs) if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs))) diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 571a0d7aa7b..9414a079e80 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -1,4 +1,6 @@ +#define VIRUS_SYMPTOM_LIMIT 6 + //Visibility Flags #define HIDDEN_SCANNER 1 #define HIDDEN_PANDEMIC 2 diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 8a90b848f22..8ba3ed64008 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -36,7 +36,7 @@ Bonus else if(ishuman(M)) var/mob/living/carbon/human/H = M - H.SetSpecialVoice(H.species.get_random_name(H.gender)) + H.SetSpecialVoice(H.dna.species.get_random_name(H.gender)) return diff --git a/code/datums/diseases/kingstons.dm b/code/datums/diseases/kingstons.dm index abad7dcf720..c7db27968ef 100644 --- a/code/datums/diseases/kingstons.dm +++ b/code/datums/diseases/kingstons.dm @@ -16,26 +16,26 @@ switch(stage) if(1) if(prob(10)) - if(affected_mob.get_species() == "Tajaran") + if(istajaran(affected_mob)) to_chat(affected_mob, "You feel good.") else to_chat(affected_mob, "You feel like playing with string.") if(2) if(prob(10)) - if(affected_mob.get_species() == "Tajaran") + if(istajaran(affected_mob)) to_chat(affected_mob, "Something in your throat itches.") else to_chat(affected_mob, "You NEED to find a mouse.") if(3) if(prob(10)) - if(affected_mob.get_species() == "Tajaran") + if(istajaran(affected_mob)) to_chat(affected_mob, "You feel something in your throat!") affected_mob.emote("cough") else affected_mob.say(pick(list("Mew", "Meow!", "Nya!~"))) if(4) if(prob(5)) - if(affected_mob.get_species() == "Tajaran") + if(istajaran(affected_mob)) affected_mob.visible_message("[affected_mob] coughs up a hairball!", \ "You cough up a hairball!") affected_mob.Stun(5) @@ -43,7 +43,7 @@ affected_mob.visible_message("[affected_mob]'s form contorts into something more feline!", \ "YOU TURN INTO A TAJARAN!") var/mob/living/carbon/human/catface = affected_mob - catface.set_species("Tajaran") + catface.set_species(/datum/species/tajaran) /datum/disease/kingstons/advanced @@ -57,39 +57,40 @@ permeability_mod = 0.75 desc = "If left untreated the subject will mutate to a different species." severity = BIOHAZARD - var/list/virspecies = list("Human", "Tajaran", "Unathi", "Skrell", "Vulpkanin")//no karma races sorrys. + var/list/virspecies = list(/datum/species/human, /datum/species/tajaran, /datum/species/unathi,/datum/species/skrell, /datum/species/vulpkanin) //no karma races sorrys. var/list/virsuffix = list("pox", "rot", "flu", "cough", "-gitis", "cold", "rash", "itch", "decay") - var/chosentype + var/datum/species/chosentype var/chosensuff /datum/disease/kingstons/advanced/New() chosentype = pick(virspecies) chosensuff = pick(virsuffix) - name = "[chosentype] [chosensuff]" + name = "[initial(chosentype.name)] [chosensuff]" /datum/disease/kingstons/advanced/stage_act() ..() - switch(stage) - if(1) - if(prob(10)) - to_chat(affected_mob, "You feel awkward.") - if(2) - if(prob(10)) - to_chat(affected_mob, "You itch.") - if(3) - if(prob(10)) - to_chat(affected_mob, "Your skin starts to flake!") + if(ishuman(affected_mob)) + var/mob/living/carbon/human/twisted = affected_mob + switch(stage) + if(1) + if(prob(10)) + to_chat(twisted, "You feel awkward.") + if(2) + if(prob(10)) + to_chat(twisted, "You itch.") + if(3) + if(prob(10)) + to_chat(twisted, "Your skin starts to flake!") - if(4) - if(prob(5)) - if(affected_mob.get_species() != chosentype) - affected_mob.visible_message("[affected_mob]'s skin splits and form contorts!", \ - "Your body mutates into a [chosentype]!") - var/mob/living/carbon/human/twisted = affected_mob - twisted.set_species(chosentype) - else - affected_mob.visible_message("[affected_mob] scratches at thier skin!", \ - "You scratch your skin to try not to itch!") - affected_mob.adjustBruteLoss(-5) - affected_mob.adjustStaminaLoss(5) \ No newline at end of file + if(4) + if(prob(5)) + if(!istype(twisted.dna.species, chosentype)) + twisted.visible_message("[twisted]'s skin splits and form contorts!", \ + "Your body mutates into a [initial(chosentype.name)]!") + twisted.set_species(chosentype) + else + twisted.visible_message("[twisted] scratches at thier skin!", \ + "You scratch your skin to try not to itch!") + twisted.adjustBruteLoss(-5) + twisted.adjustStaminaLoss(5) \ No newline at end of file diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 5546efe537e..444b4838319 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -194,13 +194,13 @@ if(1) if(ishuman(affected_mob)) var/mob/living/carbon/human/H = affected_mob - if(H.species.name == "Slime People") + if(isslimeperson(H)) stage = 5 if(3) if(ishuman(affected_mob)) var/mob/living/carbon/human/human = affected_mob - if(human.species.name != "Slime People") - human.set_species("Slime People") + if(!isslimeperson(human)) + human.set_species(/datum/species/slime) /datum/disease/transformation/corgi name = "The Barkening" diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm index 1ecf89de0fe..0352c932a5a 100644 --- a/code/datums/helper_datums/map_template.dm +++ b/code/datums/helper_datums/map_template.dm @@ -58,10 +58,10 @@ if(ST_bot_left == null || ST_top_right == null) log_runtime(EXCEPTION("One of the smoothing corners is bust"), src) + space_manager.remove_dirt(placement.z) late_setup_level( block(bot_left, top_right), block(ST_bot_left, ST_top_right)) - space_manager.remove_dirt(placement.z) log_game("[name] loaded at [min_x],[min_y],[placement.z]") return 1 @@ -175,4 +175,4 @@ var/datum/map_template/vr/V = new vr_type() vr_templates[V.id] = V - map_templates[V.id] = V \ No newline at end of file + map_templates[V.id] = V diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 04ebcc68ed5..84c45299ece 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -20,7 +20,8 @@ var/datum/atom_hud/huds = list( \ ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\ ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\ ANTAG_HUD_VAMPIRE = new/datum/atom_hud/antag/hidden(),\ - ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden()\ + ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\ + DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor()\ ) /datum/atom_hud diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 3f62c8ffaed..0e8d655c546 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -61,7 +61,6 @@ var/linglink var/datum/vampire/vampire //vampire holder var/datum/nations/nation //nation holder - var/datum/abductor/abductor //abductor holder var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD @@ -1132,14 +1131,17 @@ log_admin("[key_name(usr)] turned [current] into abductor.") ticker.mode.update_abductor_icons_added(src) if("equip") + if(!ishuman(current)) + to_chat(usr, "This only works on humans!") + return + + var/mob/living/carbon/human/H = current var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist") if(gear) - var/datum/game_mode/abduction/temp = new - temp.equip_common(current) if(gear=="Agent") - temp.equip_agent(current) + H.equipOutfit(/datum/outfit/abductor/agent) else - temp.equip_scientist(current) + H.equipOutfit(/datum/outfit/abductor/scientist) else if(href_list["silicon"]) switch(href_list["silicon"]) @@ -1424,36 +1426,32 @@ var/mob/living/carbon/human/H = current - H.set_species("Abductor") + H.set_species(/datum/species/abductor) + var/datum/species/abductor/S = H.dna.species - switch(role) - if("Agent") - H.mind.abductor.agent = 1 - if("Scientist") - H.mind.abductor.scientist = 1 - H.mind.abductor.team = team + if(role == "Scientist") + S.scientist = TRUE + + S.team = team var/list/obj/effect/landmark/abductor/agent_landmarks = new var/list/obj/effect/landmark/abductor/scientist_landmarks = new agent_landmarks.len = 4 scientist_landmarks.len = 4 for(var/obj/effect/landmark/abductor/A in landmarks_list) - if(istype(A,/obj/effect/landmark/abductor/agent)) + if(istype(A, /obj/effect/landmark/abductor/agent)) agent_landmarks[text2num(A.team)] = A - else if(istype(A,/obj/effect/landmark/abductor/scientist)) + else if(istype(A, /obj/effect/landmark/abductor/scientist)) scientist_landmarks[text2num(A.team)] = A var/obj/effect/landmark/L - if(teleport=="Yes") + if(teleport == "Yes") switch(role) if("Agent") - H.mind.abductor.agent = 1 L = agent_landmarks[team] - H.loc = L.loc if("Scientist") - H.mind.abductor.scientist = 1 L = agent_landmarks[team] - H.loc = L.loc + H.forceMove(L.loc) // check whether this mind's mob has been brigged for the given duration diff --git a/code/datums/outfits/outfit_admin.dm b/code/datums/outfits/outfit_admin.dm index b31084aee9f..edb254203bf 100644 --- a/code/datums/outfits/outfit_admin.dm +++ b/code/datums/outfits/outfit_admin.dm @@ -371,7 +371,7 @@ ) /datum/outfit/admin/vox/equip(mob/living/carbon/human/H, visualsOnly = FALSE) - if(H.get_species() == "Vox Armalis") + if(isvoxarmalis(H)) . = ..() else H.equip_vox_raider() diff --git a/code/datums/pipe_datums.dm b/code/datums/pipe_datums.dm new file mode 100644 index 00000000000..cf2ec79fe85 --- /dev/null +++ b/code/datums/pipe_datums.dm @@ -0,0 +1,390 @@ +GLOBAL_LIST_EMPTY(construction_pipe_list) //List of all pipe datums +GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable by the RPD, so we have a separate thing + +/datum/pipes + var/pipe_name //What the pipe is called in the interface + var/pipe_id //Use the pipe define for this + var/pipe_type //Atmos, disposals etc. + var/pipe_category //What category of pipe + var/bendy = FALSE //Is this pipe bendy? + var/orientations //Number of orientations (for interface purposes) + var/pipe_icon //icon_state of the dispensed pipe (for interface purposes) + var/rpd_dispensable = FALSE + +/datum/pipes/atmospheric + pipe_type = PIPETYPE_ATMOS + pipe_category = PIPETYPE_ATMOS + +/datum/pipes/disposal + pipe_type = PIPETYPE_DISPOSAL + +//Normal pipes + +/datum/pipes/atmospheric/simple + pipe_name = "straight pipe" + pipe_id = PIPE_SIMPLE_STRAIGHT + orientations = 2 + pipe_icon = "simple" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/bent //Why is this not atmospheric/simple/bent you ask? Because otherwise the ordering of the pipes in the UI menu gets weird + pipe_name = "bent pipe" + pipe_id = PIPE_SIMPLE_BENT + orientations = 4 + bendy = TRUE + pipe_icon = "simple" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/manifold + pipe_name = "t-manifold" + pipe_id = PIPE_MANIFOLD + orientations = 4 + pipe_icon = "manifold" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/manifold4w + pipe_name = "4-way manifold" + pipe_id = PIPE_MANIFOLD4W + orientations = 1 + pipe_icon = "manifold4w" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/cap + pipe_name = "pipe cap" + pipe_id = PIPE_CAP + orientations = 4 + pipe_icon = "cap" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/valve + pipe_name = "manual valve" + pipe_id = PIPE_MVALVE + orientations = 2 + pipe_icon = "mvalve" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/valve/digital + pipe_name = "digital valve" + pipe_id = PIPE_DVALVE + pipe_icon = "dvalve" + +/datum/pipes/atmospheric/tvalve + pipe_name = "manual t-valve" + pipe_id = PIPE_TVALVE + orientations = 4 + pipe_icon = "tvalve" + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/tvalve/digital + pipe_name = "digital t-valve" + pipe_id = PIPE_DTVALVE + pipe_icon = "dtvalve" + +//Supply pipes + +/datum/pipes/atmospheric/simple/supply + pipe_name = "straight supply pipe" + pipe_id = PIPE_SUPPLY_STRAIGHT + pipe_category = RPD_SUPPLY_PIPING + +/datum/pipes/atmospheric/bent/supply + pipe_name = "bent supply pipe" + pipe_id = PIPE_SUPPLY_BENT + pipe_category = RPD_SUPPLY_PIPING + +/datum/pipes/atmospheric/manifold/supply + pipe_name = "supply T-manifold" + pipe_id = PIPE_SUPPLY_MANIFOLD + pipe_category = RPD_SUPPLY_PIPING + +/datum/pipes/atmospheric/manifold4w/supply + pipe_name = "4-way supply manifold" + pipe_id = PIPE_SUPPLY_MANIFOLD4W + pipe_category = RPD_SUPPLY_PIPING + +/datum/pipes/atmospheric/cap/supply + pipe_name = "supply pipe cap" + pipe_id = PIPE_SUPPLY_CAP + pipe_category = RPD_SUPPLY_PIPING + +//Scrubbers pipes + +/datum/pipes/atmospheric/simple/scrubbers + pipe_name = "straight scrubbers pipe" + pipe_id = PIPE_SCRUBBERS_STRAIGHT + pipe_category = RPD_SCRUBBERS_PIPING + +/datum/pipes/atmospheric/bent/scrubbers + pipe_name = "bent scrubbers pipe" + pipe_id = PIPE_SCRUBBERS_BENT + pipe_category = RPD_SCRUBBERS_PIPING + +/datum/pipes/atmospheric/manifold/scrubbers + pipe_name = "scrubbers t-manifold" + pipe_id = PIPE_SCRUBBERS_MANIFOLD + pipe_category = RPD_SCRUBBERS_PIPING + +/datum/pipes/atmospheric/manifold4w/scrubbers + pipe_name = "4-way scrubbers manifold" + pipe_id = PIPE_SCRUBBERS_MANIFOLD4W + pipe_category = RPD_SCRUBBERS_PIPING + +/datum/pipes/atmospheric/cap/scrubbers + pipe_name = "scrubbers pipe cap" + pipe_id = PIPE_SCRUBBERS_CAP + pipe_category = RPD_SCRUBBERS_PIPING + +//Devices + +/datum/pipes/atmospheric/upa + pipe_name = "universal pipe adapter" + pipe_id = PIPE_UNIVERSAL + orientations = 2 + pipe_icon = "universal" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/connector + pipe_name = "connector" + pipe_id = PIPE_CONNECTOR + orientations = 4 + pipe_icon = "connector" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/unaryvent + pipe_name = "unary vent" + pipe_id = PIPE_UVENT + orientations = 4 + pipe_icon = "uvent" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/scrubber + pipe_name = "scrubber" + pipe_id = PIPE_SCRUBBER + orientations = 4 + pipe_icon = "scrubber" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/pump + pipe_name = "pump" + pipe_id = PIPE_PUMP + orientations = 4 + pipe_icon = "pump" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/volume_pump + pipe_name = "volume pump" + pipe_id = PIPE_VOLUME_PUMP + orientations = 4 + pipe_icon = "volumepump" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/gate + pipe_name = "passive gate" + pipe_id = PIPE_PASSIVE_GATE + orientations = 4 + pipe_icon = "passivegate" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/filter + pipe_name = "gas filter" + pipe_id = PIPE_GAS_FILTER + orientations = 4 + pipe_icon = "filter" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/mixer + pipe_name = "gas mixer" + pipe_id = PIPE_GAS_MIXER + orientations = 4 + pipe_icon = "mixer" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/sensor + pipe_name = "gas sensor" + pipe_id = PIPE_GAS_SENSOR + orientations = 1 + pipe_icon = "sensor" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/meter + pipe_name = "meter" + pipe_id = PIPE_METER + orientations = 1 + pipe_icon = "meter" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/passive_vent + pipe_name = "passive vent" + pipe_id = PIPE_PASV_VENT + orientations = 4 + pipe_icon = "passive vent" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/dual_vent_pump + pipe_name = "dual-port vent pump" + pipe_id = PIPE_DP_VENT + orientations = 2 + pipe_icon = "dual-port vent" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/injector + pipe_name = "air injector" + pipe_id = PIPE_INJECTOR + orientations = 4 + pipe_icon = "injector" + pipe_category = RPD_DEVICES + rpd_dispensable = TRUE + +//Heat exchange pipes + +/datum/pipes/atmospheric/simple/he + pipe_name = "straight h/e pipe" + pipe_id = PIPE_HE_STRAIGHT + pipe_icon = "he" + pipe_category = RPD_HEAT_PIPING + +/datum/pipes/atmospheric/bent/he + pipe_name = "bent h/e pipe" + pipe_id = PIPE_HE_BENT + pipe_icon = "he" + bendy = TRUE + pipe_category = RPD_HEAT_PIPING + +/datum/pipes/atmospheric/he_junction + pipe_name = "junction" + pipe_id = PIPE_JUNCTION + orientations = 4 + pipe_icon = "junction" + pipe_category = RPD_HEAT_PIPING + rpd_dispensable = TRUE + +/datum/pipes/atmospheric/heat_exchanger + pipe_name = "heat exchanger" + pipe_id = PIPE_HEAT_EXCHANGE + orientations = 4 + pipe_icon = "heunary" + pipe_category = RPD_HEAT_PIPING + rpd_dispensable = TRUE + +//DISPOSALS PIPES + +/datum/pipes/disposal/straight + pipe_name = "straight disposals pipe" + pipe_id = PIPE_DISPOSALS_STRAIGHT + orientations = 2 + pipe_icon = "pipe-s" + rpd_dispensable = TRUE + +/datum/pipes/disposal/bent + pipe_name = "bent disposals pipe" + pipe_id = PIPE_DISPOSALS_BENT + orientations = 4 + pipe_icon = "pipe-c" + rpd_dispensable = TRUE + +/datum/pipes/disposal/junction + pipe_name = "disposals junction" + pipe_id = PIPE_DISPOSALS_JUNCTION_RIGHT + orientations = 4 + pipe_icon = "pipe-j1" + rpd_dispensable = TRUE + +/datum/pipes/disposal/y_junction + pipe_name = "disposals y-junction" + pipe_id = PIPE_DISPOSALS_Y_JUNCTION + orientations = 4 + pipe_icon = "pipe-y" + rpd_dispensable = TRUE + +/datum/pipes/disposal/trunk + pipe_name = "disposals trunk" + pipe_id = PIPE_DISPOSALS_TRUNK + orientations = 4 + pipe_icon = "pipe-t" + rpd_dispensable = TRUE + +/datum/pipes/disposal/bin + pipe_name = "disposals pipe bin" + pipe_id = PIPE_DISPOSALS_BIN + orientations = 1 + pipe_icon = "disposal" + rpd_dispensable = TRUE + +/datum/pipes/disposal/outlet + pipe_name = "disposals outlet" + pipe_id = PIPE_DISPOSALS_OUTLET + orientations = 4 + pipe_icon = "outlet" + rpd_dispensable = TRUE + +/datum/pipes/disposal/chute + pipe_name = "disposals chute" + pipe_id = PIPE_DISPOSALS_CHUTE + orientations = 4 + pipe_icon = "intake" + rpd_dispensable = TRUE + +//Pipes the RPD can't dispense. Since these don't use an interface, we don't need to bother with setting an icon. We do, however, want to name these for other purposes + +/datum/pipes/atmospheric/circulator + pipe_name = "circulator / heat exchanger" + pipe_id = PIPE_CIRCULATOR + pipe_icon = "circ" + +/datum/pipes/atmospheric/omni_filter + pipe_name = "omni filter" + pipe_id = PIPE_OMNI_FILTER + pipe_icon = "omni_filter" + +/datum/pipes/atmospheric/omni_mixer + pipe_name = "omni mixer" + pipe_id = PIPE_OMNI_MIXER + pipe_icon = "omni_mixer" + +/datum/pipes/atmospheric/insulated + pipe_name = "insulated pipe" + pipe_id = PIPE_INSULATED_STRAIGHT + pipe_icon = "insulated" + +/datum/pipes/atmospheric/insulated/bent + pipe_name = "bent insulated pipe" + pipe_id = PIPE_INSULATED_BENT + +/datum/pipes/disposal/sortjunction + pipe_name = "disposals sort junction" + pipe_id = PIPE_DISPOSALS_SORT_RIGHT + pipe_icon = "pipe-j1s" + +/datum/pipes/disposal/sortjunction/left + pipe_id = PIPE_DISPOSALS_SORT_LEFT + pipe_icon = "pipe-j2s" + +/datum/pipes/disposal/left_junction + pipe_name = "disposals junction" + pipe_id = PIPE_DISPOSALS_JUNCTION_LEFT + pipe_icon = "pipe-j2" + +/proc/get_pipe_name(var/pipe_id, var/pipe_type) + for(var/datum/pipes/P in GLOB.construction_pipe_list) + if(P.pipe_id == pipe_id && P.pipe_type == pipe_type) + return P.pipe_name + return "unknown pipe" + +/proc/get_pipe_icon(var/pipe_id) + for(var/datum/pipes/P in GLOB.construction_pipe_list) + if(P.pipe_id == pipe_id) + return P.pipe_icon + return "unknown icon" diff --git a/code/datums/spells/lichdom.dm b/code/datums/spells/lichdom.dm index 84c3a552c03..f1744e22550 100644 --- a/code/datums/spells/lichdom.dm +++ b/code/datums/spells/lichdom.dm @@ -68,7 +68,7 @@ lich.real_name = M.mind.name M.mind.transfer_to(lich) - lich.set_species("Skeleton") + lich.set_species(/datum/species/skeleton) to_chat(lich, "Your bones clatter and shutter as they're pulled back into this world!") charge_max += 600 var/mob/old_body = current_body @@ -122,7 +122,7 @@ current_body = M.mind.current if(ishuman(M)) var/mob/living/carbon/human/H = M - H.set_species("Skeleton") + H.set_species(/datum/species/skeleton) H.unEquip(H.wear_suit) H.unEquip(H.head) H.unEquip(H.shoes) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 353d38a6932..628b754a5ae 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1236,8 +1236,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/materials/plastic30 name = "30 Plastic Sheets Crate" contains = list(/obj/item/stack/sheet/plastic) - amount = 50 - cost = 10 + amount = 30 + cost = 20 containername = "plastic sheets crate" ////////////////////////////////////////////////////////////////////////////// diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 50f24eac58f..952711f3063 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1029,9 +1029,8 @@ var/list/uplink_items = list() /datum/uplink_item/suits/hardsuit name = "Syndicate Hardsuit" - desc = "The feared suit of a syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ - that runs off standard atmospheric tanks. When the built in helmet is deployed your identity will be \ - protected, even in death, as the suit cannot be removed by outside forces. Toggling the suit in and out of \ + desc = "The feared suit of a syndicate nuclear agent. Features armor and a combat mode \ + for faster movement on station. Toggling the suit in and out of \ combat mode will allow you all the mobility of a loose fitting uniform without sacrificing armoring. \ Additionally the suit is collapsible, making it small enough to fit within a backpack. \ Nanotrasen crew who spot these suits are known to panic." diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index acd155e7560..a1c6a83da61 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -34,7 +34,7 @@ if(prob(40)) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(!(RADIMMUNE in H.species.species_traits)) + if(!(RADIMMUNE in H.dna.species.species_traits)) if(prob(max(0, 100 - resist))) randmuti(H) // Applies bad mutation if(prob(50)) diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index ee25f8c3898..609dce59e84 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -3,52 +3,33 @@ /datum/wires/camera random = 0 holder_type = /obj/machinery/camera - wire_count = 6 + wire_count = 2 /datum/wires/camera/get_status() . = ..() var/obj/machinery/camera/C = holder . += "The focus light is [(C.view_range == initial(C.view_range)) ? "on" : "off"]." . += "The power link light is [C.can_use() ? "on" : "off"]." - . += "The camera light is [C.light_disabled ? "off" : "on"]." - . += "The alarm light is [C.alarm_on ? "on" : "off"]." /datum/wires/camera/CanUse(mob/living/L) var/obj/machinery/camera/C = holder if(!C.panel_open) - return 0 - return 1 + return FALSE + return TRUE var/const/CAMERA_WIRE_FOCUS = 1 var/const/CAMERA_WIRE_POWER = 2 -var/const/CAMERA_WIRE_LIGHT = 4 -var/const/CAMERA_WIRE_ALARM = 8 -var/const/CAMERA_WIRE_NOTHING1 = 16 -var/const/CAMERA_WIRE_NOTHING2 = 32 /datum/wires/camera/GetWireName(index) switch(index) if(CAMERA_WIRE_FOCUS) return "Focus" - + if(CAMERA_WIRE_POWER) return "Power" - - if(CAMERA_WIRE_LIGHT) - return "Light" - - if(CAMERA_WIRE_ALARM) - return "Alarm" - - if(CAMERA_WIRE_NOTHING1) - return "Nothing" - - if(CAMERA_WIRE_NOTHING2) - return "Nothing" /datum/wires/camera/UpdateCut(index, mended) var/obj/machinery/camera/C = holder - switch(index) if(CAMERA_WIRE_FOCUS) var/range = (mended ? initial(C.view_range) : C.short_range) @@ -56,16 +37,8 @@ var/const/CAMERA_WIRE_NOTHING2 = 32 if(CAMERA_WIRE_POWER) if(C.status && !mended || !C.status && mended) - C.toggle_cam(usr, 1) - - if(CAMERA_WIRE_LIGHT) - C.light_disabled = !mended - - if(CAMERA_WIRE_ALARM) - if(!mended) - C.triggerCameraAlarm() - else - C.cancelCameraAlarm() + C.toggle_cam(usr, TRUE) + C.obj_integrity = C.max_integrity //this is a pretty simplistic way to heal the camera, but there's no reason for this to be complex. ..() /datum/wires/camera/UpdatePulsed(index) @@ -79,16 +52,10 @@ var/const/CAMERA_WIRE_NOTHING2 = 32 if(CAMERA_WIRE_POWER) C.toggle_cam(null) // Deactivate the camera - - if(CAMERA_WIRE_LIGHT) - C.light_disabled = !C.light_disabled - - if(CAMERA_WIRE_ALARM) - C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") ..() /datum/wires/camera/proc/CanDeconstruct() - if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS) && IsIndexCut(CAMERA_WIRE_LIGHT) && IsIndexCut(CAMERA_WIRE_NOTHING1) && IsIndexCut(CAMERA_WIRE_NOTHING2)) - return 1 + if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS)) + return TRUE else - return 0 \ No newline at end of file + return FALSE \ No newline at end of file diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index b6e3ecde8bd..1664a7051da 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -48,8 +48,8 @@ if(!message) return - var/tmp/message_title = new_title ? new_title : title - var/tmp/message_sound = new_sound ? sound(new_sound) : sound + var/message_title = new_title ? new_title : title + var/message_sound = new_sound ? sound(new_sound) : sound if(!msg_sanitized) message = trim_strip_html_properly(message, allow_lines = 1) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index e331376a0dc..1744f638c5d 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -543,12 +543,6 @@ var/list/ghostteleportlocs = list() name = "\improper Syndicate Infiltrators" icon_state = "syndie-elite" -/area/syndicate_depot - name = "\improper Suspicious Supply Depot" - icon_state = "red" - tele_proof = 1 - requires_power = 0 - //EXTRA /area/asteroid // -- TLE diff --git a/code/game/area/depot-areas.dm b/code/game/area/depot-areas.dm new file mode 100644 index 00000000000..9de680da82e --- /dev/null +++ b/code/game/area/depot-areas.dm @@ -0,0 +1,430 @@ + +/area/syndicate_depot + name = "Suspicious Supply Depot" + icon_state = "dark" + tele_proof = 1 + +/area/syndicate_depot/core + icon_state = "red" + + var/local_alarm = FALSE // Level 1: Local alarm tripped, bot spawned, red fire overlay activated + var/called_backup = FALSE // Level 2: Remote alarm tripped. Bot may path through depot. Backup spawned. + var/used_self_destruct = FALSE // Level 3: Self destruct activated. Depot will be destroyed shortly. + + var/run_started = FALSE + var/run_finished = FALSE + + // Soft UID-based refs + var/list/guard_list = list() + var/list/hostile_list = list() + var/list/dead_list = list() + var/list/peaceful_list = list() + var/list/shield_list = list() + + var/list/alert_log = list() // no refs, just a simple list of text strings + + var/used_lockdown = FALSE + var/destroyed = FALSE + var/something_looted = FALSE + var/on_peaceful = FALSE + var/peace_betrayed = FALSE + var/detected_mech = FALSE + var/detected_pod = FALSE + var/detected_double_agent = FALSE + var/obj/machinery/computer/syndicate_depot/syndiecomms/comms_computer = null + var/obj/structure/fusionreactor/reactor + +/area/syndicate_depot/core/updateicon() + if(destroyed) + icon_state = null + invisibility = INVISIBILITY_MAXIMUM + else if(on_peaceful) + icon_state = "green" + invisibility = INVISIBILITY_LIGHTING + else if(used_self_destruct) + icon_state = "radiation" + invisibility = INVISIBILITY_LIGHTING + else if(called_backup) + icon_state = "red" + invisibility = INVISIBILITY_LIGHTING + else if(local_alarm) + icon_state = "bluenew" + invisibility = INVISIBILITY_LIGHTING + else + icon_state = null + invisibility = INVISIBILITY_MAXIMUM + +/area/syndicate_depot/core/proc/reset_alert() + + if(used_self_destruct) + return + + local_alarm = FALSE + called_backup = FALSE + used_self_destruct = FALSE + something_looted = FALSE + detected_mech = FALSE + detected_pod = FALSE + detected_double_agent = FALSE + updateicon() + despawn_guards() + + guard_list = list() + hostile_list = list() + dead_list = list() + peaceful_list = list() + + alert_log += "Alert level reset." + +/area/syndicate_depot/core/proc/increase_alert(reason) + if(on_peaceful) + peaceful_mode(FALSE, FALSE) + peace_betrayed = TRUE + activate_self_destruct("Depot has been infiltrated by double-agents.", TRUE, null) + return + if(!local_alarm) + local_alarm(reason, FALSE) + return + if(!called_backup) + call_backup(reason, FALSE) + return + if(!used_self_destruct) + activate_self_destruct(reason, FALSE, null) + updateicon() + +/area/syndicate_depot/core/proc/locker_looted() + something_looted = TRUE + if(on_peaceful) + increase_alert("Thieves!") + +/area/syndicate_depot/core/proc/turret_died() + something_looted = TRUE + if(on_peaceful) + increase_alert("Vandals!") + +/area/syndicate_depot/core/proc/saw_mech(obj/mecha/E) + if(detected_mech) + return + detected_mech = TRUE + increase_alert("Hostile mecha detected: [E]") + +/area/syndicate_depot/core/proc/saw_pod(obj/spacepod/P) + if(detected_pod) + return + detected_pod = TRUE + increase_alert("Hostile spacepod detected: [P]") + +/area/syndicate_depot/core/proc/saw_double_agent(mob/living/M) + if(detected_double_agent) + return + detected_double_agent = TRUE + increase_alert("Hostile double-agent detected: [M]") + +/area/syndicate_depot/core/proc/peaceful_mode(newvalue, bycomputer) + if(newvalue) + log_game("Depot visit: started") + alert_log += "Code GREEN: visitor mode started." + ghostlog("The syndicate depot has visitors") + for(var/mob/living/simple_animal/bot/medbot/syndicate/B in src) + qdel(B) + for(var/mob/living/simple_animal/hostile/syndicate/N in src) + N.a_intent = INTENT_HELP + for(var/obj/structure/closet/secure_closet/syndicate/depot/L in src) + if(L.opened) + L.close() + if(!L.locked) + L.locked = 1 + L.req_access = list(access_syndicate_leader) + L.update_icon() + for(var/obj/machinery/computer/syndicate_depot/teleporter/P in src) + if(!P.portal_enabled) + P.toggle_portal() + for(var/obj/machinery/door/airlock/hatch/syndicate/vault/V in src) + if(!V.density) + V.close() + V.emergency = 0 + if(!V.locked) + V.locked = !V.locked + V.update_icon() + else + log_game("Depot visit: ended") + alert_log += "Visitor mode ended." + for(var/mob/living/simple_animal/hostile/syndicate/N in src) + N.a_intent = INTENT_HARM + for(var/obj/machinery/door/airlock/A in src) + A.req_access_txt = "[access_syndicate_leader]" + for(var/obj/structure/closet/secure_closet/syndicate/depot/L in src) + if(L.locked) + L.locked = !L.locked + L.req_access = list() + L.update_icon() + on_peaceful = newvalue + if(newvalue) + announce_here("Depot Visitor","A Syndicate agent is visiting the depot.") + else + if(bycomputer) + message_admins("Syndicate Depot visitor mode deactivated. Visitors:") + announce_here("Depot Alert","Visit ended. All visting agents signed out.") + else + message_admins("Syndicate Depot visitor mode auto-deactivated because visitors robbed depot! Visitors:") + announce_here("Depot Alert","A visiting agent has betrayed the Syndicate. Shoot all visitors on sight!") + for(var/mob/M in list_getmobs(peaceful_list)) + if("syndicate" in M.faction) + M.faction -= "syndicate" + message_admins("- SYNDI DEPOT VISITOR: [ADMIN_FULLMONTY(M)]") + list_add(M, hostile_list) + peaceful_list = list() + updateicon() + +/area/syndicate_depot/core/proc/local_alarm(reason, silent) + if(local_alarm) + return + log_game("Depot code: blue: " + list_show(hostile_list, TRUE)) + ghostlog("The syndicate depot has declared code blue.") + alert_log += "Code BLUE: [reason]" + local_alarm = TRUE + if(!silent) + announce_here("Depot Code BLUE", reason) + var/list/possible_bot_spawns = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "syndi_depot_bot") + possible_bot_spawns |= L + if(possible_bot_spawns.len) + var/obj/effect/landmark/S = pick(possible_bot_spawns) + new /obj/effect/portal(get_turf(S)) + var/mob/living/simple_animal/bot/ed209/syndicate/B = new /mob/living/simple_animal/bot/ed209/syndicate(get_turf(S)) + list_add(B, guard_list) + B.depotarea = src + updateicon() + +/area/syndicate_depot/core/proc/call_backup(reason, silent) + if(called_backup || used_self_destruct) + return + log_game("Depot code: red: " + list_show(hostile_list, TRUE)) + ghostlog("The syndicate depot has declared code red.") + alert_log += "Code RED: [reason]" + called_backup = TRUE + lockout_computers() + for(var/obj/machinery/door/poddoor/P in airlocks) + if(P.density && P.id_tag == "syndi_depot_lvl2" && !P.operating) + spawn(0) + P.open() + if(!silent) + announce_here("Depot Code RED", reason) + + var/comms_online = FALSE + if(istype(comms_computer)) + if(!(comms_computer.stat & (NOPOWER|BROKEN))) + comms_online = TRUE + if(comms_online) + spawn(0) + for(var/obj/effect/landmark/L in landmarks_list) + if(prob(50)) + if(L.name == "syndi_depot_backup") + var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/S = new /mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space(get_turf(L)) + S.name = "Syndicate Backup " + "([rand(1, 1000)])" + S.depotarea = src + list_add(S, guard_list) + else if(!silent) + announce_here("Depot Communications Offline", "Comms computer is damaged, destroyed or depowered. Unable to call in backup from Syndicate HQ.") + updateicon() + +/area/syndicate_depot/core/proc/activate_self_destruct(reason, containment_failure, mob/user) + if(used_self_destruct) + return + log_game("Depot code: delta: " + list_show(hostile_list, TRUE)) + ghostlog("The syndicate depot is about to self-destruct.") + alert_log += "Code DELTA: [reason]" + used_self_destruct = TRUE + local_alarm = TRUE + called_backup = TRUE + activate_lockdown(TRUE) + lockout_computers() + updateicon() + despawn_guards() + if(containment_failure) + announce_here("Depot Code DELTA", reason) + else + announce_here("Depot Code DELTA","[reason] Depot declared lost to hostile forces. Priming self-destruct!") + + if(user) + var/turf/T = get_turf(user) + var/area/A = get_area(T) + var/log_msg = "[key_name(user)] has armed the depot self destruct device at [A.name] ([T.x],[T.y],[T.z])" + message_admins(log_msg) + log_game(log_msg) + playsound(user, 'sound/machines/Alarm.ogg', 100, 0, 0) + else + log_game("Depot self destruct activated.") + if(reactor) + reactor.overload(containment_failure) + else + message_admins("Syndicate Depot lacks reactor to initiate self-destruct. Must be destroyed manually.") + updateicon() + +/area/syndicate_depot/core/proc/activate_lockdown() + if(used_lockdown) + return + used_lockdown = TRUE + for(var/obj/machinery/door/airlock/A in src) + spawn(0) + A.close() + if(A.density) + A.lock() + +/area/syndicate_depot/core/proc/lockout_computers() + for(var/obj/machinery/computer/syndicate_depot/C in src) + C.activate_security_lockout() + +/area/syndicate_depot/core/proc/toggle_door_locks() + for(var/obj/machinery/door/airlock/A in src) + A.emergency = !A.emergency + if(A.locked) + A.locked = !A.locked + A.update_icon() + +/area/syndicate_depot/core/proc/toggle_falsewalls() + for(var/obj/structure/falsewall/reinforced/F in src) + spawn(0) + F.toggle() + +/area/syndicate_depot/core/proc/toggle_teleport_beacon() + for(var/obj/machinery/bluespace_beacon/syndicate/B in src) + return B.toggle() + +/area/syndicate_depot/core/proc/announce_here(a_header = "Depot Defense Alert", a_text = "") + var/msg_text = "[a_header]
[a_text]" + var/list/receivers = list() + for(var/mob/M in mob_list) + if(!M.ckey) + continue + var/turf/T = get_turf(M) + if(T.loc != src) + continue + receivers |= M + for(var/mob/R in receivers) + to_chat(R, msg_text) + R << sound('sound/misc/notice1.ogg') + +/area/syndicate_depot/core/proc/shields_up() + if(shield_list.len) + return + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == "syndi_depot_shield") + var/obj/machinery/shieldwall/syndicate/S = new /obj/machinery/shieldwall/syndicate(L.loc) + shield_list += S.UID() + +/area/syndicate_depot/core/proc/shields_key_check() + if(!shield_list.len) + return + if(detected_mech || detected_pod || detected_double_agent) + return + shields_down() + +/area/syndicate_depot/core/proc/shields_down() + for(var/shuid in shield_list) + var/obj/machinery/shieldwall/syndicate/S = locateUID(shuid) + if(S) + qdel(S) + shield_list = list() + +/area/syndicate_depot/core/proc/despawn_guards() + for(var/mob/thismob in list_getmobs(guard_list)) + new /obj/effect/portal(get_turf(thismob)) + qdel(thismob) + guard_list = list() + +/area/syndicate_depot/core/proc/ghostlog(gmsg) + if(istype(reactor)) + var/image/alert_overlay = image('icons/obj/flag.dmi', "syndiflag") + notify_ghosts(gmsg, title = "Depot News", source = reactor, alert_overlay = alert_overlay, action = NOTIFY_JUMP) + +/area/syndicate_depot/core/proc/declare_started() + if(!run_started) + run_started = TRUE + log_game("Depot run: started: " + list_show(hostile_list, TRUE)) + +/area/syndicate_depot/core/proc/declare_finished() + if(!run_finished && !used_self_destruct) + run_finished = TRUE + log_game("Depot run: finished successfully: " + list_show(hostile_list, TRUE)) + +/area/syndicate_depot/core/proc/list_add(mob/M, list/L) + if(!istype(M)) + return + var/mob_uid = M.UID() + if(mob_uid in L) + return + L += mob_uid + +/area/syndicate_depot/core/proc/list_remove(mob/M, list/L) + if(!istype(M)) + return + var/mob_uid = M.UID() + if(mob_uid in L) + L -= mob_uid + +/area/syndicate_depot/core/proc/list_includes(mob/M, list/L) + if(!istype(M)) + return FALSE + var/mob_uid = M.UID() + if(mob_uid in L) + return TRUE + return FALSE + +/area/syndicate_depot/core/proc/list_show(list/L, show_ckeys = FALSE) + var/list/formatted = list() + for(var/uid in L) + var/mob/M = locateUID(uid) + if(!istype(M)) + continue + if(show_ckeys) + formatted += "[M.ckey]([M])" + else + formatted += "[M]" + return formatted.Join(", ") + +/area/syndicate_depot/core/proc/list_getmobs(list/L, show_ckeys = FALSE) + var/list/moblist = list() + for(var/uid in L) + var/mob/M = locateUID(uid) + if(!istype(M)) + continue + moblist += M + return moblist + +/area/syndicate_depot/core/proc/list_gethtmlmobs(list/L) + var/returntext = "" + var/list/moblist = list_getmobs(L) + if(moblist.len) + returntext += "" + else + returntext += "
NONE" + return returntext + +/area/syndicate_depot/outer + name = "Suspicious Asteroid" + icon_state = "green" + +/area/syndicate_depot/perimeter + name = "Suspicious Asteroid Perimeter" + icon_state = "yellow" + var/list/shield_list = list() + +/area/syndicate_depot/perimeter/proc/perimeter_shields_up() + if(shield_list.len) + return + for(var/turf/T in src) + var/obj/machinery/shieldwall/syndicate/S = new /obj/machinery/shieldwall/syndicate(T) + S.alpha = 0 + shield_list += S.UID() + +/area/syndicate_depot/perimeter/proc/perimeter_shields_down() + for(var/shuid in shield_list) + var/obj/machinery/shieldwall/syndicate/S = locateUID(shuid) + if(S) + qdel(S) + shield_list = list() \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 136c8950028..ea3b9df4f54 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -302,6 +302,9 @@ /atom/proc/emag_act() return +/atom/proc/rpd_act() + return + /atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7ab561f0814..4e467e4eb18 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -29,11 +29,10 @@ areaMaster = get_area_master(src) /atom/movable/attempt_init() - if(ticker && ticker.current_state >= GAME_STATE_SETTING_UP) - var/turf/T = get_turf(src) - if(T && space_manager.is_zlevel_dirty(T.z)) - space_manager.postpone_init(T.z, src) - return + var/turf/T = get_turf(src) + if(T && SSatoms.initialized != INITIALIZATION_INSSATOMS && space_manager.is_zlevel_dirty(T.z)) + space_manager.postpone_init(T.z, src) + return . = ..() @@ -429,4 +428,8 @@ flick_overlay(I, viewing, 5) // 5 ticks/half a second // And animate the attack! - animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) \ No newline at end of file + animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) + + +/atom/movable/proc/portal_destroyed(obj/effect/portal/P) + return diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index a4faafcf91f..db2fb3c64df 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -52,6 +52,9 @@ /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) +/datum/atom_hud/abductor + hud_icons = list(GLAND_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) diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index f21c2948b01..cba96ded0db 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -99,8 +99,7 @@ var/global/list/bad_blocks[0] var/b_type = "A+" // Should probably change to an integer => string map but I'm lazy. var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings, - // New stuff - var/species = "Human" + var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man) // Make a copy of this strand. // USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION! @@ -110,7 +109,7 @@ var/global/list/bad_blocks[0] new_dna.struc_enzymes_original=struc_enzymes_original // will make clone's SE the same as the original, do we want this? new_dna.b_type=b_type new_dna.real_name=real_name - new_dna.species=species + new_dna.species = new species.type for(var/b=1;b<=DNA_SE_LENGTH;b++) new_dna.SE[b]=SE[b] if(b<=DNA_UI_LENGTH) @@ -141,7 +140,7 @@ var/global/list/bad_blocks[0] // FIXME: Species-specific defaults pls var/obj/item/organ/external/head/H = character.get_organ("head") var/obj/item/organ/internal/eyes/eyes_organ = character.get_int_organ(/obj/item/organ/internal/eyes) - var/datum/species/S = character.species + var/datum/species/S = character.dna.species /*// Body Accessory if(!character.body_accessory) @@ -421,7 +420,7 @@ var/global/list/bad_blocks[0] data["UE"] = unique_enzymes data["SE"] = SE.Copy() // This is probably too lazy for my own good data["UI"] = UI.Copy() - data["species"] = species // This works because `species` is a string, not a datum + data["species"] = species.type // Because old DNA coders were insane or something data["b_type"] = b_type data["real_name"] = real_name @@ -434,10 +433,7 @@ var/global/list/bad_blocks[0] UI = data["UI"] UpdateUI() UpdateSE() - species = data["species"] + var/datum/species/S = data["species"] + species = new S b_type = data["b_type"] - real_name = data["real_name"] - -// a nice hook for if/when we refactor species on dna -/datum/dna/proc/get_species_name() - return species + real_name = data["real_name"] \ No newline at end of file diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm index f2ad2b2fe03..07979f40b7c 100644 --- a/code/game/dna/dna2_domutcheck.dm +++ b/code/game/dna/dna2_domutcheck.dm @@ -16,7 +16,7 @@ /proc/genemutcheck(var/mob/living/M, var/block, var/connected=null, var/flags=0) if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure. var/mob/living/carbon/human/H = M - if(NO_DNA in H.species.species_traits) + if(NO_DNA in H.dna.species.species_traits) return if(!M) return @@ -42,7 +42,7 @@ var/defaultgenes // Do not mutate inherent species abilities if(ishuman(M)) var/mob/living/carbon/human/H = M - defaultgenes = H.species.default_genes + defaultgenes = H.dna.species.default_genes if((gene in defaultgenes) && gene_active) return diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 6c05dfd6f2b..d392ab303ca 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -133,7 +133,7 @@ var/mob/living/carbon/human/H = src var/obj/item/organ/external/head/head_organ = H.get_organ("head") var/obj/item/organ/internal/eyes/eye_organ = H.get_int_organ(/obj/item/organ/internal/eyes) - var/datum/species/S = H.species + var/datum/species/S = H.dna.species if(istype(head_organ)) dna.write_head_attributes(head_organ) if(istype(eye_organ)) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 93d9977b5e8..354536561c1 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -327,7 +327,7 @@ if(ishuman(occupant)) var/mob/living/carbon/human/H = occupant - if(NO_DNA in H.species.species_traits) + if(NO_DNA in H.dna.species.species_traits) return 1 var/radiation_protection = occupant.run_armor_check(null, "rad", "Your clothes feel warm.", "Your clothes feel warm.") diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm index e59dd3fc558..b39b31a1c5a 100644 --- a/code/game/dna/genes/goon_disabilities.dm +++ b/code/game/dna/genes/goon_disabilities.dm @@ -44,7 +44,7 @@ return 0 if(ishuman(M)) var/mob/living/carbon/human/H = M - if((RADIMMUNE in H.species.species_traits) && !(flags & MUTCHK_FORCED)) + if((RADIMMUNE in H.dna.species.species_traits) && !(flags & MUTCHK_FORCED)) return 0 return 1 diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 666cb057635..d0c32b19620 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -7,8 +7,8 @@ /datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) return ishuman(M) -/datum/dna/gene/monkey/activate(var/mob/living/carbon/human/H, var/connected, var/flags) - if(!istype(H,/mob/living/carbon/human)) +/datum/dna/gene/monkey/activate(mob/living/carbon/human/H, connected, flags) + if(!istype(H)) return if(issmall(H)) return @@ -24,6 +24,9 @@ H.canmove = 0 H.icon = null H.invisibility = 101 + var/has_primitive_form = H.dna.species.primitive_form // cache this + if(has_primitive_form) + H.set_species(has_primitive_form) new /obj/effect/temp_visual/monkeyify(H.loc) sleep(22) @@ -31,23 +34,24 @@ H.SetStunned(0) H.invisibility = initial(H.invisibility) - if(!H.species.primitive_form) //If the creature in question has no primitive set, this is going to be messy. + if(!has_primitive_form) //If the pre-change mob in question has no primitive set, this is going to be messy. H.gib() return - H.set_species(H.species.primitive_form) - QDEL_NULL(H.hud_used) if(H.client) H.hud_used = new /datum/hud/monkey(H, ui_style2icon(H.client.prefs.UI_style), H.client.prefs.UI_style_color, H.client.prefs.UI_style_alpha) + H.hud_used.show_hud(H.hud_used.hud_version) - to_chat(H, "You are now a [H.species.name].") + to_chat(H, "You are now a [H.dna.species.name].") return H -/datum/dna/gene/monkey/deactivate(var/mob/living/carbon/human/H, var/connected, var/flags) - if(!istype(H,/mob/living/carbon/human)) +/datum/dna/gene/monkey/deactivate(mob/living/carbon/human/H, connected, flags) + if(!istype(H)) + return + if(!issmall(H)) return for(var/obj/item/W in H) if(W == H.w_uniform) // will be torn @@ -62,6 +66,9 @@ H.canmove = 0 H.icon = null H.invisibility = 101 + var/has_greater_form = H.dna.species.greater_form //cache this + if(has_greater_form) + H.set_species(has_greater_form) new /obj/effect/temp_visual/monkeyify/humanify(H.loc) sleep(22) @@ -69,11 +76,10 @@ H.SetStunned(0) H.invisibility = initial(H.invisibility) - if(!H.species.greater_form) //If the creature in question has no primitive set, this is going to be messy. + if(!has_greater_form) //If the pre-change mob in question has no primitive set, this is going to be messy. H.gib() return - H.set_species(H.species.greater_form) H.real_name = H.dna.real_name H.name = H.real_name @@ -81,7 +87,8 @@ if(H.client) H.hud_used = new /datum/hud/human(H, ui_style2icon(H.client.prefs.UI_style), H.client.prefs.UI_style_color, H.client.prefs.UI_style_alpha) + H.hud_used.show_hud(H.hud_used.hud_version) - to_chat(H, "You are now a [H.species.name].") + to_chat(H, "You are now a [H.dna.species.name].") return H diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm index e9d69c2b904..1e5e6b66842 100644 --- a/code/game/dna/genes/powers.dm +++ b/code/game/dna/genes/powers.dm @@ -39,7 +39,7 @@ return 0 if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.species && H.species.slowdown && !(flags & MUTCHK_FORCED)) + if(H.dna.species && H.dna.species.slowdown && !(flags & MUTCHK_FORCED)) return 0 return 1 diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 3e709560a45..f9e8620bef1 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -50,7 +50,7 @@ M.change_eye_color(new_eyes) //Alt heads. - if(head_organ.species.bodyflags & HAS_ALT_HEADS) + if(head_organ.dna.species.bodyflags & HAS_ALT_HEADS) var/list/valid_alt_heads = M.generate_valid_alt_heads() var/new_alt_head = input("Please select alternate head", "Character Generation", head_organ.alt_head) as null|anything in valid_alt_heads if(new_alt_head) @@ -92,7 +92,7 @@ M.change_facial_hair_color(new_facial, 1) //Head accessory. - if(head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + if(head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) var/list/valid_head_accessories = M.generate_valid_head_accessories() var/new_head_accessory = input("Please select head accessory style", "Character Generation", head_organ.ha_style) as null|anything in valid_head_accessories if(new_head_accessory) @@ -103,7 +103,7 @@ M.change_head_accessory_color(new_head_accessory_colour) //Body accessory. - if(M.species.tail && M.species.bodyflags & HAS_TAIL) + if(M.dna.species.tail && M.dna.species.bodyflags & HAS_TAIL) var/list/valid_body_accessories = M.generate_valid_body_accessories() if(valid_body_accessories.len > 1) //By default valid_body_accessories will always have at the very least a 'none' entry populating the list, even if the user's species is not present in any of the list items. var/new_body_accessory = input("Please select body accessory style", "Character Generation", M.body_accessory) as null|anything in valid_body_accessories @@ -111,7 +111,7 @@ M.change_body_accessory(new_body_accessory) //Head markings. - if(M.species.bodyflags & HAS_HEAD_MARKINGS) + if(M.dna.species.bodyflags & HAS_HEAD_MARKINGS) var/list/valid_head_markings = M.generate_valid_markings("head") var/new_marking = input("Please select head marking style", "Character Generation", M.m_styles["head"]) as null|anything in valid_head_markings if(new_marking) @@ -121,7 +121,7 @@ if(new_marking_colour) M.change_marking_color(new_marking_colour, "head") //Body markings. - if(M.species.bodyflags & HAS_BODY_MARKINGS) + if(M.dna.species.bodyflags & HAS_BODY_MARKINGS) var/list/valid_body_markings = M.generate_valid_markings("body") var/new_marking = input("Please select body marking style", "Character Generation", M.m_styles["body"]) as null|anything in valid_body_markings if(new_marking) @@ -131,7 +131,7 @@ if(new_marking_colour) M.change_marking_color(new_marking_colour, "body") //Tail markings. - if(M.species.bodyflags & HAS_TAIL_MARKINGS) + if(M.dna.species.bodyflags & HAS_TAIL_MARKINGS) var/list/valid_tail_markings = M.generate_valid_markings("tail") var/new_marking = input("Please select tail marking style", "Character Generation", M.m_styles["tail"]) as null|anything in valid_tail_markings if(new_marking) @@ -142,7 +142,7 @@ M.change_marking_color(new_marking_colour, "tail") //Skin tone. - if(M.species.bodyflags & HAS_SKIN_TONE) + if(M.dna.species.bodyflags & HAS_SKIN_TONE) var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", M.s_tone) as null|text if(!new_tone) new_tone = 35 @@ -150,11 +150,11 @@ new_tone = 35 - max(min(round(text2num(new_tone)), 220), 1) M.change_skin_tone(new_tone) - if(M.species.bodyflags & HAS_ICON_SKIN_TONE) - var/prompt = "Please select skin tone: 1-[M.species.icon_skin_tones.len] (" - for(var/i = 1 to M.species.icon_skin_tones.len) - prompt += "[i] = [M.species.icon_skin_tones[i]]" - if(i != M.species.icon_skin_tones.len) + if(M.dna.species.bodyflags & HAS_ICON_SKIN_TONE) + var/prompt = "Please select skin tone: 1-[M.dna.species.icon_skin_tones.len] (" + for(var/i = 1 to M.dna.species.icon_skin_tones.len) + prompt += "[i] = [M.dna.species.icon_skin_tones[i]]" + if(i != M.dna.species.icon_skin_tones.len) prompt += ", " prompt += ")" @@ -162,11 +162,11 @@ if(!new_tone) new_tone = 0 else - new_tone = max(min(round(text2num(new_tone)), M.species.icon_skin_tones.len), 1) + new_tone = max(min(round(text2num(new_tone)), M.dna.species.icon_skin_tones.len), 1) M.change_skin_tone(new_tone) //Skin colour. - if(M.species.bodyflags & HAS_SKIN_COLOR) + if(M.dna.species.bodyflags & HAS_SKIN_COLOR) var/new_body_colour = input("Please select body colour.", "Character Generation", M.skin_colour) as null|color if(new_body_colour) M.change_skin_color(new_body_colour) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index 329408bffce..477a0de2573 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -112,7 +112,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" if(identity_theft.target && identity_theft.target.current) identity_theft.target_real_name = kill_objective.target.current.real_name //Whoops, forgot this. var/mob/living/carbon/human/H = identity_theft.target.current - if(can_absorb_species(H.species)) // For species that can't be absorbed - should default to an escape objective + if(can_absorb_species(H.dna.species)) // For species that can't be absorbed - should default to an escape objective identity_theft.explanation_text = "Escape on the shuttle or an escape pod with the identity of [identity_theft.target_real_name], the [identity_theft.target.assigned_role] while wearing [identity_theft.target.p_their()] identification card." changeling.objectives += identity_theft else @@ -273,7 +273,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" /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) + if(tDNA.unique_enzymes == D.unique_enzymes && tDNA.uni_identity == D.uni_identity && tDNA.species.type == D.species.type) return D return null @@ -316,7 +316,7 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon" to_chat(user, "DNA of [target] is ruined beyond usability!") return - if(NO_DNA in T.species.species_traits) + if(NO_DNA in T.dna.species.species_traits) to_chat(user, "This creature does not have DNA!") return diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index a7af2b94482..befdf899253 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -375,7 +375,7 @@ var/list/sting_paths path.on_purchase(src) var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste - mind.changeling.absorbed_dna |= C.dna + mind.changeling.absorbed_dna |= C.dna.Clone() mind.changeling.trim_dna() return 1 diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index fb3012cd274..72b0e821e66 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -26,10 +26,10 @@ to_chat(user, "We transform our appearance.") user.dna.SetSEState(MONKEYBLOCK,0,1) genemutcheck(user,MONKEYBLOCK,null,MUTCHK_FORCED) + if(istype(user)) + user.set_species(chosen_dna.species.type) 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 = "" user.dna.UpdateSE() diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 3d3b7f2bc07..2197163cbd5 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -17,17 +17,13 @@ var/mob/living/carbon/human/H = user - if(!istype(H) || !H.species.primitive_form) + if(!istype(H) || !H.dna.species.primitive_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!") - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/implant/W in H) - implants += W H.monkeyize() changeling.purchasedpowers += new /obj/effect/proc_holder/changeling/humanform(null) feedback_add_details("changeling_powers","LF") diff --git a/code/game/gamemodes/changeling/powers/revive.dm b/code/game/gamemodes/changeling/powers/revive.dm index b3881ee54fb..3e03d49dc49 100644 --- a/code/game/gamemodes/changeling/powers/revive.dm +++ b/code/game/gamemodes/changeling/powers/revive.dm @@ -31,7 +31,7 @@ H.traumatic_shock = 0 H.shock_stage = 0 H.next_pain_time = 0 - H.species.create_organs(H) + H.dna.species.create_organs(H) // Now that recreating all organs is necessary, the rest of this organ stuff probably // isn't, but I don't want to remove it, just in case. for(var/organ_name in H.bodyparts_by_name) diff --git a/code/game/gamemodes/changeling/powers/swap_form.dm b/code/game/gamemodes/changeling/powers/swap_form.dm index 9015677c70e..c40a33284a1 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) || NO_DNA in target.species.species_traits) + if(!istype(target) || issmall(target) || NO_DNA in target.dna.species.species_traits) to_chat(user, "[target] is not compatible with this ability.") return return 1 diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index c344897c624..bb216ddad35 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -80,8 +80,7 @@ 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((NOTRANSSTING in newspecies.species_traits) || newspecies.is_small) + if((NOTRANSSTING in selected_dna.species.species_traits) || selected_dna.species.is_small) to_chat(user, "The selected DNA is incompatible with our sting.") return ..() @@ -94,7 +93,7 @@ return FALSE if(ishuman(target)) var/mob/living/carbon/human/H = target - if(NO_DNA in H.species.species_traits) + if(NO_DNA in H.dna.species.species_traits) to_chat(user, "This won't work on a creature without DNA.") return FALSE return TRUE @@ -112,11 +111,11 @@ target.visible_message("[target] begins to violenty convulse!","You feel a tiny prick and a begin to uncontrollably convulse!") spawn(10) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.set_species(NewDNA.species.type) target.dna = NewDNA.Clone() target.real_name = NewDNA.real_name - var/mob/living/carbon/human/H = target - if(istype(H)) - H.set_species() target.UpdateAppearance() domutcheck(target, null) feedback_add_details("changeling_powers","TS") diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index b7c8abefd1d..bacdc8b0d8b 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -14,10 +14,10 @@ if(!chosen_dna) return + if(ishuman(user)) + user.set_species(chosen_dna.species.type) user.dna = chosen_dna.Clone() user.real_name = chosen_dna.real_name - if(ishuman(user)) - 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() diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 2edbfca609f..b8e5365cb5d 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -50,7 +50,7 @@ ..() if(ishuman(target)) var/mob/living/carbon/human/H = target - if((H.stat != DEAD) && !(NO_BLOOD in H.species.species_traits)) + if((H.stat != DEAD) && !(NO_BLOOD in H.dna.species.species_traits)) H.bleed(50) /obj/item/restraints/legcuffs/bola/cult @@ -201,6 +201,7 @@ increment = 5 max = 40 prefix = "darkened" + claw_damage_increase = 2 /obj/item/whetstone/cult/update_icon() icon_state = "cult_sharpener[used ? "_used" : ""]" diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 8d858c6fade..70e78176463 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -279,7 +279,7 @@ var/mob/living/carbon/human/H = user user.visible_message("Otherworldly armor suddenly appears on [user]!", \ "You speak the words of the talisman, arming yourself!") - if(H.get_species() == "Plasmaman") + if(isplasmaman(H)) H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/cultist(H), slot_wear_suit) H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/cultist(H), slot_head) else diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 3b908952de7..4cbe909ef84 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -101,7 +101,7 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' vox.name = vox.real_name newraider.name = vox.name vox.age = rand(12,20) - vox.set_species("Vox") + vox.set_species(/datum/species/vox) vox.s_tone = rand(1, 6) vox.languages = list() // Removing language from chargen. vox.flavor_text = "" diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index 50b749a62a2..ca868f4874e 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -116,7 +116,7 @@ if((man.mind.assigned_role in ticker.mode.protected_jobs) || (man.mind.assigned_role in ticker.mode.restricted_jobs)) return //don't include suspects who can't possibly be the antag based on their species (no suspecting the machines of being sneaky changelings) - if(man.get_species() in ticker.mode.protected_species) + if(man.dna.species.name in ticker.mode.protected_species) return dudes += man for(var/i = 0, i < max(player_list.len/10,2), i++) diff --git a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm new file mode 100644 index 00000000000..af2920c4626 --- /dev/null +++ b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm @@ -0,0 +1,147 @@ +/datum/objective/abductee + completed = 1 + +/datum/objective/abductee/steal + explanation_text = "Steal all" + +/datum/objective/abductee/steal/New() + var/target = pick(list("pets","lights","monkeys","fruits","shoes","bars of soap", "weapons", "computers", "organs")) + explanation_text+=" [target]." + +/datum/objective/abductee/paint + explanation_text = "The station is hideous. You must color it all" + +/datum/objective/abductee/paint/New() + var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood")) + explanation_text+= " [color]!" + +/datum/objective/abductee/speech + explanation_text = "Your brain is broken... you can only communicate in" + +/datum/objective/abductee/speech/New() + var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon")) + explanation_text+= " [style]." + +/datum/objective/abductee/capture + explanation_text = "Capture" + +/datum/objective/abductee/capture/New() + var/list/jobs = job_master.occupations.Copy() + for(var/datum/job/J in jobs) + if(J.current_positions < 1) + jobs -= J + if(jobs.len > 0) + var/datum/job/target = pick(jobs) + explanation_text += " a [target.title]." + else + explanation_text += " someone." + +/datum/objective/abductee/shuttle + explanation_text = "You must escape the station! Get the shuttle called!" + +/datum/objective/abductee/noclone + explanation_text = "Don't allow anyone to be cloned." + +/datum/objective/abductee/oxygen + explanation_text = "The oxygen is killing them all and they don't even know it. Make sure no oxygen is on the station." + +/datum/objective/abductee/blazeit + explanation_text = "Your body must be improved. Ingest as many drugs as you can." + +/datum/objective/abductee/yumyum + explanation_text = "You are hungry. Eat as much food as you can find." + +/datum/objective/abductee/insane + explanation_text = "You see you see what they cannot you see the open door you seeE you SEeEe you SEe yOU seEee SHOW THEM ALL" + +/datum/objective/abductee/cannotmove + explanation_text = "Convince the crew that you are a paraplegic." + +/datum/objective/abductee/deadbodies + explanation_text = "Start a collection of corpses. Don't kill people to get these corpses." + +/datum/objective/abductee/floors + explanation_text = "Replace all the floor tiles with wood, carpeting, grass or bling." + +/datum/objective/abductee/POWERUNLIMITED + explanation_text = "Flood the station's powernet with as much electricity as you can." + +/datum/objective/abductee/pristine + explanation_text = "The CEO of Nanotrasen is coming! Ensure the station is in absolutely pristine condition." + +/datum/objective/abductee/nowalls + explanation_text = "The crew must get to know one another better. Break down the walls inside the station!" + +/datum/objective/abductee/nations + explanation_text = "Ensure your department prospers over all else." + +/datum/objective/abductee/abductception + explanation_text = "You have been changed forever. Find the ones that did this to you and give them a taste of their own medicine." + +/datum/objective/abductee/summon + explanation_text = "The elder gods hunger. Gather a cult and conduct a ritual to summon one." + +/datum/objective/abductee/machine + explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power so the AI may acknowledge you at last." + +/datum/objective/abductee/calling + explanation_text = "Call forth a spirit from the other side." + +/datum/objective/abductee/calling/New() + var/mob/dead/D = pick(dead_mob_list) + if(D) + explanation_text = "You know that [D] has perished. Hold a seance to call them from the spirit realm." + +/datum/objective/abductee/social_experiment + explanation_text = "This is a secret social experiment conducted by Nanotrasen. Convince the crew that this is the truth." + +/datum/objective/abductee/vr + explanation_text = "It's all an entirely virtual simulation within an underground vault. Convince the crew to escape the shackles of VR." + +/datum/objective/abductee/pets + explanation_text = "Nanotrasen is abusing the animals! Save as many as you can!" + +/datum/objective/abductee/defect + explanation_text = "Fuck the system! Defect from the station and start an independent colony in space, Mining Outpost or the derelict. Recruit crewmates if you can." + +/datum/objective/abductee/promote + explanation_text = "Climb the corporate ladder all the way to the top!" + +/datum/objective/abductee/science + explanation_text = "So much lies undiscovered. Look deeper into the machinations of the universe." + +/datum/objective/abductee/build + explanation_text = "Expand the station." + +/datum/objective/abductee/pragnant + explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby." + +/datum/objective/abductee/engine + explanation_text = "Go have a good conversation with the singularity/tesla/supermatter crystal. Bonus points if it responds." + +/datum/objective/abductee/music + explanation_text = "You burn with passion for music. Share your vision. If anyone hates it, beat them on the head with your instrument!" + +/datum/objective/abductee/clown + explanation_text = "The clown is not funny. You can do better! Steal his audience and make the crew laugh!" + +/datum/objective/abductee/party + explanation_text = "You're throwing a huge rager. Make it as awesome as possible so the whole crew comes... OR ELSE!" + +/datum/objective/abductee/pets + explanation_text = "All the pets around here suck. You need to make them cooler. Replace them with exotic beasts!" + +/datum/objective/abductee/conspiracy + explanation_text = "The leaders of this station are hiding a grand, evil conspiracy. Only you can learn what it is, and expose it to the people!" + +/datum/objective/abductee/stalker + explanation_text = "The Syndicate has hired you to compile dossiers on all important members of the crew. Be sure they don't know you're doing it." + +/datum/objective/abductee/narrator + explanation_text = "You're the narrator of this tale. Follow around the protagonists to tell their story." + +/datum/objective/abductee/lurve + explanation_text = "You are doomed to feel woefully incomplete forever... until you find your true love on this station. They're waiting for you!" + +/datum/objective/abductee/sixthsense + explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo." \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 1c6dc7d3022..5d5c3342010 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -89,62 +89,14 @@ return 1 /datum/game_mode/abduction/post_setup() - //Spawn Team - var/list/obj/effect/landmark/abductor/agent_landmarks = new - var/list/obj/effect/landmark/abductor/scientist_landmarks = new - agent_landmarks.len = max_teams - scientist_landmarks.len = max_teams - for(var/obj/effect/landmark/abductor/A in landmarks_list) - if(istype(A,/obj/effect/landmark/abductor/agent)) - agent_landmarks[text2num(A.team)] = A - else if(istype(A,/obj/effect/landmark/abductor/scientist)) - scientist_landmarks[text2num(A.team)] = A - - var/datum/mind/agent - var/obj/effect/landmark/L - var/datum/mind/scientist - var/team_name - var/mob/living/carbon/human/H for(var/team_number=1,team_number<=abductor_teams,team_number++) - team_name = team_names[team_number] - agent = agents[team_number] - H = agent.current - L = agent_landmarks[team_number] - H.forceMove(get_turf(L)) - H.body_accessory = null - H.set_species("Abductor") - H.mind.abductor.agent = 1 - H.mind.abductor.team = team_number - H.real_name = team_name + " Agent" - H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys. - H.overeatduration = 0 - equip_common(H,team_number) - equip_agent(H,team_number) - greet_agent(agent,team_number) - update_abductor_icons_added(agent) - - scientist = scientists[team_number] - H = scientist.current - L = scientist_landmarks[team_number] - H.forceMove(get_turf(L)) - H.body_accessory = null - H.set_species("Abductor") - H.mind.abductor.scientist = 1 - H.mind.abductor.team = team_number - H.real_name = team_name + " Scientist" - H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys. - H.overeatduration = 0 - equip_common(H,team_number) - equip_scientist(H,team_number) - greet_scientist(scientist,team_number) - update_abductor_icons_added(scientist) - + post_setup_team(team_number) return ..() //Used for create antag buttons /datum/game_mode/abduction/proc/post_setup_team(team_number) - var/list/obj/effect/landmark/abductor/agent_landmarks = new - var/list/obj/effect/landmark/abductor/scientist_landmarks = new + var/list/obj/effect/landmark/abductor/agent_landmarks = list() + var/list/obj/effect/landmark/abductor/scientist_landmarks = list() agent_landmarks.len = max_teams scientist_landmarks.len = max_teams for(var/obj/effect/landmark/abductor/A in landmarks_list) @@ -153,11 +105,13 @@ else if(istype(A,/obj/effect/landmark/abductor/scientist)) scientist_landmarks[text2num(A.team)] = A + var/team_name = team_names[team_number] + var/datum/mind/agent var/obj/effect/landmark/L var/datum/mind/scientist - var/team_name var/mob/living/carbon/human/H + var/datum/species/abductor/S team_name = team_names[team_number] agent = agents[team_number] @@ -165,12 +119,13 @@ L = agent_landmarks[team_number] H.forceMove(get_turf(L)) H.body_accessory = null - H.set_species("Abductor") - H.mind.abductor.agent = 1 - H.mind.abductor.team = team_number + H.set_species(/datum/species/abductor) + S = H.dna.species + S.team = team_number H.real_name = team_name + " Agent" - equip_common(H,team_number) - equip_agent(H,team_number) + H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys. + H.overeatduration = 0 + H.equipOutfit(/datum/outfit/abductor/agent) greet_agent(agent,team_number) update_abductor_icons_added(agent) @@ -179,21 +134,17 @@ L = scientist_landmarks[team_number] H.forceMove(get_turf(L)) H.body_accessory = null - H.set_species("Abductor") - H.mind.abductor.scientist = 1 - H.mind.abductor.team = team_number + H.set_species(/datum/species/abductor) + S = H.dna.species + S.scientist = TRUE + S.team = team_number H.real_name = team_name + " Scientist" - equip_common(H,team_number) - equip_scientist(H,team_number) + H.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ayys. + H.overeatduration = 0 + H.equipOutfit(/datum/outfit/abductor/scientist) greet_scientist(scientist,team_number) update_abductor_icons_added(scientist) - -/datum/abductor //stores abductor's team and whether they're a scientist or agent; since species datums are global, we have to use this, instead. - var/scientist = 0 - var/agent = 0 - var/team = 1 - /datum/game_mode/abduction/proc/greet_agent(datum/mind/abductor,team_number) abductor.objectives += team_objectives[team_number] var/team_name = team_names[team_number] @@ -202,11 +153,7 @@ to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!") to_chat(abductor.current, "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve.") - var/obj_count = 1 - for(var/datum/objective/objective in abductor.objectives) - to_chat(abductor.current, "Objective #[obj_count]: [objective.explanation_text]") - obj_count++ - return + abductor.announce_objectives() /datum/game_mode/abduction/proc/greet_scientist(datum/mind/abductor,team_number) abductor.objectives += team_objectives[team_number] @@ -216,64 +163,12 @@ to_chat(abductor.current, "With the help of your teammate, kidnap and experiment on station crew members!") to_chat(abductor.current, "Use your tool and ship consoles to support the agent and retrieve human specimens.") - var/obj_count = 1 - for(var/datum/objective/objective in abductor.objectives) - to_chat(abductor.current, "Objective #[obj_count]: [objective.explanation_text]") - obj_count++ - return - -/datum/game_mode/abduction/proc/equip_common(mob/living/carbon/human/agent,team_number) - var/radio_freq = SYND_FREQ - - var/obj/item/radio/R = new /obj/item/radio/headset/syndicate/alt(agent) - R.set_frequency(radio_freq) - R.name = "alien headset" - agent.equip_to_slot_or_del(R, slot_l_ear) - agent.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(agent), slot_shoes) - agent.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(agent), slot_w_uniform) //they're greys gettit - agent.equip_to_slot_or_del(new /obj/item/storage/backpack(agent), slot_back) - -/datum/game_mode/abduction/proc/get_team_console(team) - var/obj/machinery/abductor/console/console - for(var/obj/machinery/abductor/console/c in abductor_equipment) - if(c.team == team) - console = c - break - return console - -/datum/game_mode/abduction/proc/equip_agent(mob/living/carbon/human/agent,team_number) - if(!team_number) - team_number = agent.mind.abductor.team - - var/obj/machinery/abductor/console/console = get_team_console(team_number) - var/obj/item/clothing/suit/armor/abductor/vest/V = new /obj/item/clothing/suit/armor/abductor/vest(agent) - if(console!=null) - console.vest = V - V.flags |= NODROP - agent.equip_to_slot_or_del(V, slot_wear_suit) - agent.equip_to_slot_or_del(new /obj/item/abductor_baton(agent), slot_in_backpack) - agent.equip_to_slot_or_del(new /obj/item/gun/energy/alien(agent), slot_in_backpack) - agent.equip_to_slot_or_del(new /obj/item/abductor/silencer(agent), slot_in_backpack) - agent.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/abductor(agent), slot_head) - agent.equip_to_slot_or_del(new /obj/item/storage/belt/military/abductor/full(agent), slot_belt) - agent.update_icons() - - -/datum/game_mode/abduction/proc/equip_scientist(var/mob/living/carbon/human/scientist,var/team_number) - if(!team_number) - team_number = scientist.mind.abductor.team - - var/obj/machinery/abductor/console/console = get_team_console(team_number) - var/obj/item/abductor/gizmo/G = new /obj/item/abductor/gizmo(scientist) - if(console!=null) - console.gizmo = G - G.console = console - scientist.equip_to_slot_or_del(G, slot_in_backpack) - - var/obj/item/implant/abductor/beamplant = new /obj/item/implant/abductor(scientist) - beamplant.implant(scientist) - scientist.update_icons() + abductor.announce_objectives() +/datum/game_mode/abduction/proc/get_team_console(team_number) + for(var/obj/machinery/abductor/console/C in machines) + if(C.team == team_number) + return C /datum/game_mode/abduction/check_finished() if(!finished) @@ -336,18 +231,19 @@ var/ab_team = team if(owner) if(!owner.current || !ishuman(owner.current)) - return 0 + return FALSE var/mob/living/carbon/human/H = owner.current - if(H.get_species() != "Abductor") - return 0 - ab_team = H.mind.abductor.team - for(var/obj/machinery/abductor/experiment/E in abductor_equipment) + if(!isabductor(H)) + return FALSE + var/datum/species/abductor/S = H.dna.species + ab_team = S.team + for(var/obj/machinery/abductor/experiment/E in machines) if(E.team == ab_team) if(E.points >= target_amount) - return 1 + return TRUE else - return 0 - return 0 + return FALSE + return FALSE /datum/game_mode/proc/remove_abductor(datum/mind/abductor_mind) if(abductor_mind in abductors) @@ -358,7 +254,7 @@ 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_removed(abductor_mind) /datum/game_mode/proc/update_abductor_icons_added(datum/mind/alien_mind) var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_ABDUCTOR] @@ -368,152 +264,4 @@ /datum/game_mode/proc/update_abductor_icons_removed(datum/mind/alien_mind) var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_ABDUCTOR] hud.leave_hud(alien_mind.current) - set_antag_hud(alien_mind.current, null) - -/datum/objective/abductee - completed = 1 - -/datum/objective/abductee/steal - explanation_text = "Steal all" - -/datum/objective/abductee/steal/New() - var/target = pick(list("pets","lights","monkeys","fruits","shoes","bars of soap", "weapons", "computers", "organs")) - explanation_text+=" [target]." - -/datum/objective/abductee/paint - explanation_text = "The station is hideous. You must color it all" - -/datum/objective/abductee/paint/New() - var/color = pick(list("red", "blue", "green", "yellow", "orange", "purple", "black", "in rainbows", "in blood")) - explanation_text+= " [color]!" - -/datum/objective/abductee/speech - explanation_text = "Your brain is broken... you can only communicate in" - -/datum/objective/abductee/speech/New() - var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon")) - explanation_text+= " [style]." - -/datum/objective/abductee/capture - explanation_text = "Capture" - -/datum/objective/abductee/capture/New() - var/list/jobs = job_master.occupations.Copy() - for(var/datum/job/J in jobs) - if(J.current_positions < 1) - jobs -= J - if(jobs.len > 0) - var/datum/job/target = pick(jobs) - explanation_text += " a [target.title]." - else - explanation_text += " someone." - -/datum/objective/abductee/shuttle - explanation_text = "You must escape the station! Get the shuttle called!" - -/datum/objective/abductee/noclone - explanation_text = "Don't allow anyone to be cloned." - -/datum/objective/abductee/oxygen - explanation_text = "The oxygen is killing them all and they don't even know it. Make sure no oxygen is on the station." - -/datum/objective/abductee/blazeit - explanation_text = "Your body must be improved. Ingest as many drugs as you can." - -/datum/objective/abductee/yumyum - explanation_text = "You are hungry. Eat as much food as you can find." - -/datum/objective/abductee/insane - explanation_text = "You see you see what they cannot you see the open door you seeE you SEeEe you SEe yOU seEee SHOW THEM ALL" - -/datum/objective/abductee/cannotmove - explanation_text = "Convince the crew that you are a paraplegic." - -/datum/objective/abductee/deadbodies - explanation_text = "Start a collection of corpses. Don't kill people to get these corpses." - -/datum/objective/abductee/floors - explanation_text = "Replace all the floor tiles with wood, carpeting, grass or bling." - -/datum/objective/abductee/POWERUNLIMITED - explanation_text = "Flood the station's powernet with as much electricity as you can." - -/datum/objective/abductee/pristine - explanation_text = "The CEO of Nanotrasen is coming! Ensure the station is in absolutely pristine condition." - -/datum/objective/abductee/nowalls - explanation_text = "The crew must get to know one another better. Break down the walls inside the station!" - -/datum/objective/abductee/nations - explanation_text = "Ensure your department prospers over all else." - -/datum/objective/abductee/abductception - explanation_text = "You have been changed forever. Find the ones that did this to you and give them a taste of their own medicine." - -/datum/objective/abductee/summon - explanation_text = "The elder gods hunger. Gather a cult and conduct a ritual to summon one." - -/datum/objective/abductee/machine - explanation_text = "You are secretly an android. Interface with as many machines as you can to boost your own power so the AI may acknowledge you at last." - -/datum/objective/abductee/calling - explanation_text = "Call forth a spirit from the other side." - -/datum/objective/abductee/calling/New() - var/mob/dead/D = pick(dead_mob_list) - if(D) - explanation_text = "You know that [D] has perished. Hold a seance to call them from the spirit realm." - -/datum/objective/abductee/social_experiment - explanation_text = "This is a secret social experiment conducted by Nanotrasen. Convince the crew that this is the truth." - -/datum/objective/abductee/vr - explanation_text = "It's all an entirely virtual simulation within an underground vault. Convince the crew to escape the shackles of VR." - -/datum/objective/abductee/pets - explanation_text = "Nanotrasen is abusing the animals! Save as many as you can!" - -/datum/objective/abductee/defect - explanation_text = "Fuck the system! Defect from the station and start an independent colony in space, Mining Outpost or the derelict. Recruit crewmates if you can." - -/datum/objective/abductee/promote - explanation_text = "Climb the corporate ladder all the way to the top!" - -/datum/objective/abductee/science - explanation_text = "So much lies undiscovered. Look deeper into the machinations of the universe." - -/datum/objective/abductee/build - explanation_text = "Expand the station." - -/datum/objective/abductee/pragnant - explanation_text = "You are pregnant and soon due. Find a safe place to deliver your baby." - -/datum/objective/abductee/engine - explanation_text = "Go have a good conversation with the singularity/tesla/supermatter crystal. Bonus points if it responds." - -/datum/objective/abductee/music - explanation_text = "You burn with passion for music. Share your vision. If anyone hates it, beat them on the head with your instrument!" - -/datum/objective/abductee/clown - explanation_text = "The clown is not funny. You can do better! Steal his audience and make the crew laugh!" - -/datum/objective/abductee/party - explanation_text = "You're throwing a huge rager. Make it as awesome as possible so the whole crew comes... OR ELSE!" - -/datum/objective/abductee/pets - explanation_text = "All the pets around here suck. You need to make them cooler. Replace them with exotic beasts!" - -/datum/objective/abductee/conspiracy - explanation_text = "The leaders of this station are hiding a grand, evil conspiracy. Only you can learn what it is, and expose it to the people!" - -/datum/objective/abductee/stalker - explanation_text = "The Syndicate has hired you to compile dossiers on all important members of the crew. Be sure they don't know you're doing it." - -/datum/objective/abductee/narrator - explanation_text = "You're the narrator of this tale. Follow around the protagonists to tell their story." - -/datum/objective/abductee/lurve - explanation_text = "You are doomed to feel woefully incomplete forever... until you find your true love on this station. They're waiting for you!" - -/datum/objective/abductee/sixthsense - explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo." \ No newline at end of file + set_antag_hud(alien_mind.current, null) \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 9a43df56926..c8539b568db 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -2,6 +2,8 @@ #define VEST_COMBAT 2 #define GIZMO_SCAN 1 #define GIZMO_MARK 2 +#define MIND_DEVICE_MESSAGE 1 +#define MIND_DEVICE_CONTROL 2 //AGENT VEST /obj/item/clothing/suit/armor/abductor/vest @@ -14,6 +16,7 @@ origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4" armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15) actions_types = list(/datum/action/item_action/hands_free/activate) + allowed = list(/obj/item/abductor, /obj/item/abductor_baton, /obj/item/melee/baton, /obj/item/gun/energy, /obj/item/restraints/handcuffs) var/mode = VEST_STEALTH var/stealth_active = 0 var/combat_cooldown = 10 @@ -23,6 +26,11 @@ species_fit = null sprite_sheets = null +/obj/item/clothing/suit/armor/abductor/vest/proc/toggle_nodrop() + flags ^= NODROP + if(ismob(loc)) + to_chat(loc, "Your vest is now [flags & NODROP ? "locked" : "unlocked"].") + /obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode() switch(mode) if(VEST_STEALTH) @@ -53,7 +61,7 @@ return stealth_active = 1 if(ishuman(loc)) - var/mob/living/carbon/human/M = src.loc + var/mob/living/carbon/human/M = loc new /obj/effect/temp_visual/dir_setting/ninja/cloak(get_turf(M), M.dir) M.name_override = disguise.name M.icon = disguise.icon @@ -67,7 +75,7 @@ return stealth_active = 0 if(ishuman(loc)) - var/mob/living/carbon/human/M = src.loc + var/mob/living/carbon/human/M = loc new /obj/effect/temp_visual/dir_setting/ninja(get_turf(M), M.dir) M.name_override = null M.overlays.Cut() @@ -94,9 +102,9 @@ /obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline() if(ishuman(loc)) if(combat_cooldown != initial(combat_cooldown)) - to_chat(src.loc, "Combat injection is still recharging.") + to_chat(loc, "Combat injection is still recharging.") return - var/mob/living/carbon/human/M = src.loc + var/mob/living/carbon/human/M = loc M.adjustStaminaLoss(-75) M.SetParalysis(0) M.SetStunned(0) @@ -109,6 +117,17 @@ if(combat_cooldown==initial(combat_cooldown)) processing_objects.Remove(src) +/obj/item/clothing/suit/armor/abductor/Destroy() + processing_objects.Remove(src) + for(var/obj/machinery/abductor/console/C in machines) + if(C.vest == src) + C.vest = null + break + return ..() + +/obj/item/abductor + icon = 'icons/obj/abductor.dmi' + /obj/item/abductor/proc/AbductorCheck(user) if(isabductor(user)) return TRUE @@ -116,14 +135,19 @@ return FALSE /obj/item/abductor/proc/ScientistCheck(user) + if(!AbductorCheck(user)) + return FALSE + var/mob/living/carbon/human/H = user - if(H.mind && H.mind.abductor) - return H.mind.abductor.scientist + var/datum/species/abductor/S = H.dna.species + if(S.scientist) + return TRUE + to_chat(user, "You're not trained to use this!") + return FALSE /obj/item/abductor/gizmo name = "science tool" desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras." - icon = 'icons/obj/abductor.dmi' icon_state = "gizmo_scan" item_state = "gizmo" origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3" @@ -132,11 +156,12 @@ var/obj/machinery/abductor/console/console /obj/item/abductor/gizmo/attack_self(mob/user) - if(!AbductorCheck(user)) - return if(!ScientistCheck(user)) - to_chat(user, "You're not trained to use this!") return + if(!console) + to_chat(user, "The device is not linked to a console!") + return + if(mode == GIZMO_SCAN) mode = GIZMO_MARK icon_state = "gizmo_mark" @@ -146,11 +171,12 @@ to_chat(user, "You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE") /obj/item/abductor/gizmo/attack(mob/living/M, mob/user) - if(!AbductorCheck(user)) - return if(!ScientistCheck(user)) - to_chat(user, "You're not trained to use this") return + if(!console) + to_chat(user, "The device is not linked to console!") + return + switch(mode) if(GIZMO_SCAN) scan(M, user) @@ -161,11 +187,12 @@ /obj/item/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params) if(flag) return - if(!AbductorCheck(user)) - return if(!ScientistCheck(user)) - to_chat(user, "You're not trained to use this") return + if(!console) + to_chat(user, "The device is not linked to console!") + return + switch(mode) if(GIZMO_SCAN) scan(target, user) @@ -174,9 +201,8 @@ /obj/item/abductor/gizmo/proc/scan(atom/target, mob/living/user) if(ishuman(target)) - if(console!=null) - console.AddSnapshot(target) - to_chat(user, "You scan [target] and add [target.p_them()] to the database.") + console.AddSnapshot(target) + to_chat(user, "You scan [target] and add [target.p_them()] to the database.") /obj/item/abductor/gizmo/proc/mark(atom/target, mob/living/user) if(marked == target) @@ -200,11 +226,15 @@ marked = target to_chat(user, "You finish preparing [target] for transport.") +/obj/item/abductor/gizmo/Destroy() + if(console) + console.gizmo = null + return ..() + /obj/item/abductor/silencer name = "abductor silencer" desc = "A compact device used to shut down communications equipment." - icon = 'icons/obj/abductor.dmi' icon_state = "silencer" item_state = "silencer" origin_tech = "materials=4;programming=7;abductor=3" @@ -222,7 +252,7 @@ radio_off(target, user) /obj/item/abductor/silencer/proc/radio_off(atom/target, mob/living/user) - if(!(user in (viewers(7,target)))) + if(!(user in (viewers(7, target)))) return var/turf/targloc = get_turf(target) @@ -238,17 +268,90 @@ var/list/all_items = M.GetAllContents() for(var/obj/I in all_items) - if(istype(I,/obj/item/radio/)) + if(istype(I, /obj/item/radio)) var/obj/item/radio/r = I r.listening = 0 - if(!istype(I,/obj/item/radio/headset)) + if(!istype(I, /obj/item/radio/headset)) r.broadcasting = 0 //goddamned headset hacks +/obj/item/abductor/mind_device + name = "mental interface device" + desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, or to send a command to a test subject with a charged gland." + icon_state = "mind_device_message" + item_state = "silencer" + var/mode = MIND_DEVICE_MESSAGE + +/obj/item/abductor/mind_device/attack_self(mob/user) + if(!ScientistCheck(user)) + return + + if(mode == MIND_DEVICE_MESSAGE) + mode = MIND_DEVICE_CONTROL + icon_state = "mind_device_control" + else + mode = MIND_DEVICE_MESSAGE + icon_state = "mind_device_message" + to_chat(user, "You switch the device to [mode == MIND_DEVICE_MESSAGE ? "TRANSMISSION" : "COMMAND"] MODE") + +/obj/item/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params) + if(!ScientistCheck(user)) + return + + switch(mode) + if(MIND_DEVICE_CONTROL) + mind_control(target, user) + if(MIND_DEVICE_MESSAGE) + mind_message(target, user) + +/obj/item/abductor/mind_device/proc/mind_control(atom/target, mob/living/user) + if(iscarbon(target)) + var/mob/living/carbon/C = target + var/obj/item/organ/internal/heart/gland/G = C.get_organ_slot("heart") + if(!istype(G)) + to_chat(user, "Your target does not have an experimental gland!") + return + if(!G.mind_control_uses) + to_chat(user, "Your target's gland is spent!") + return + if(G.active_mind_control) + to_chat(user, "Your target is already under a mind-controlling influence!") + return + + var/command = stripped_input(user, "Enter the command for your target to follow. Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command") + + if(!command) + return + + if(QDELETED(user) || user.get_active_hand() != src || loc != user) + return + + if(QDELETED(G)) + return + + G.mind_control(command, user) + to_chat(user, "You send the command to your target.") + +/obj/item/abductor/mind_device/proc/mind_message(atom/target, mob/living/user) + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + to_chat(user, "Your target is dead!") + return + var/message = stripped_input(user, "Write a message to send to your target's brain.", "Enter message") + if(!message) + return + if(QDELETED(L) || L.stat == DEAD) + return + + to_chat(L, "You hear a voice in your head saying: [message]") + to_chat(user, "You send the message to your target.") + log_say("[key_name(user)] sent an abductor mind message to [key_name(L)]: '[message]'", user) + /obj/item/gun/energy/alien name = "alien pistol" desc = "A complicated gun that fires bursts of high-intensity radiation." ammo_type = list(/obj/item/ammo_casing/energy/declone) - restricted_species = list("Abductor") + restricted_species = list(/datum/species/abductor) icon_state = "alienpistol" item_state = "alienpistol" origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3" @@ -258,7 +361,6 @@ name = "Dissection Guide" icon_state = "alienpaper_words" info = {"Dissection for Dummies
-
1.Acquire fresh specimen.
2.Put the specimen on operating table.
@@ -303,7 +405,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} w_class = WEIGHT_CLASS_NORMAL actions_types = list(/datum/action/item_action/toggle_mode) -/obj/item/abductor_baton/proc/toggle(mob/living/user=usr) +/obj/item/abductor_baton/proc/toggle(mob/living/user = usr) mode = (mode+1)%BATON_MODES var/txt switch(mode) @@ -432,7 +534,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} if(ishuman(L)) var/mob/living/carbon/human/H = L - species = "[H.species.name]" + species = "[H.dna.species.name]" if(L.mind && L.mind.changeling) species = "Changeling lifeform" var/obj/item/organ/internal/heart/gland/temp = locate() in H.internal_organs @@ -476,6 +578,24 @@ Congratulations! You are now trained for invasive xenobiology research!"} if(BATON_PROBE) to_chat(user, "The baton is in probing mode.") +/obj/item/radio/headset/abductor + name = "alien headset" + desc = "An advanced alien headset designed to monitor communications of human space stations. Why does it have a microphone? No one knows." + flags = EARBANGPROTECT + origin_tech = "magnets=2;abductor=3" + icon = 'icons/obj/abductor.dmi' + icon_state = "abductor_headset" + item_state = "abductor_headset" + ks2type = /obj/item/encryptionkey/heads/captain + +/obj/item/radio/headset/abductor/New() + ..() + make_syndie() + +/obj/item/radio/headset/abductor/attackby(obj/item/I, mob/user, params) + if(isscrewdriver(I)) + return // Stops humans from disassembling abductor headsets. + return ..() /obj/item/scalpel/alien name = "alien scalpel" @@ -519,6 +639,27 @@ Congratulations! You are now trained for invasive xenobiology research!"} origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 +/obj/item/bonegel/alien + name = "alien bone gel" + desc = "It smells like duct tape." + icon = 'icons/obj/abductor.dmi' + origin_tech = "materials=2;biotech=2;abductor=2" + toolspeed = 0.25 + +/obj/item/FixOVein/alien + name = "alien FixOVein" + desc = "Bloodless aliens would totally know how to stop internal bleeding...right?" + icon = 'icons/obj/abductor.dmi' + origin_tech = "materials=2;biotech=2;abductor=2" + toolspeed = 0.25 + +/obj/item/bonesetter/alien + name = "alien bone setter" + desc = "You're not sure you want to know whether or not aliens have bones." + icon = 'icons/obj/abductor.dmi' + origin_tech = "materials=2;biotech=2;abductor=2" + toolspeed = 0.25 + /obj/item/clothing/head/helmet/abductor name = "agent headgear" desc = "Abduct with style - spiky style. Prevents digital tracking." @@ -535,6 +676,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} name = "resting contraption" desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?" icon = 'icons/obj/abductor.dmi' + buildstacktype = /obj/item/stack/sheet/mineral/abductor icon_state = "bed" /obj/structure/table_frame/abductor @@ -593,7 +735,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} icon = 'icons/obj/abductor.dmi' icon_state = "bed" no_icon_updates = 1 //no icon updates for this; it's static. - injected_reagents = list("corazone") + injected_reagents = list("corazone","spaceacillin") /obj/structure/closet/abductor name = "alien locker" diff --git a/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm b/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm new file mode 100644 index 00000000000..bb39e90cd01 --- /dev/null +++ b/code/game/gamemodes/miniantags/abduction/abduction_outfits.dm @@ -0,0 +1,62 @@ +/datum/outfit/abductor + name = "Abductor Basic" + uniform = /obj/item/clothing/under/color/grey //they're greys gettit + shoes = /obj/item/clothing/shoes/combat + back = /obj/item/storage/backpack + l_ear = /obj/item/radio/headset/abductor + +/datum/outfit/abductor/proc/get_team_console(team_number) + for(var/obj/machinery/abductor/console/C in machines) + if(C.team == team_number) + return C + +/datum/outfit/abductor/proc/link_to_console(mob/living/carbon/human/H, team_number) + if(!team_number && isabductor(H)) + var/datum/species/abductor/S = H.dna.species + team_number = S.team + + if(!team_number) + team_number = 1 + + var/obj/machinery/abductor/console/console = get_team_console(team_number) + if(console) + var/obj/item/clothing/suit/armor/abductor/vest/V = locate() in H + if(V) + console.vest = V + V.flags |= NODROP + + var/obj/item/abductor/gizmo/G = locate() in H.get_item_by_slot(slot_back) + if(G) + console.gizmo = G + G.console = console + +/datum/outfit/abductor/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + if(!visualsOnly) + link_to_console(H) + + +/datum/outfit/abductor/agent + name = "Abductor Agent" + head = /obj/item/clothing/head/helmet/abductor + suit = /obj/item/clothing/suit/armor/abductor/vest + belt = /obj/item/storage/belt/military/abductor/full + + backpack_contents = list( + /obj/item/abductor_baton = 1, + /obj/item/gun/energy/alien = 1, + /obj/item/abductor/silencer = 1 + ) + +/datum/outfit/abductor/scientist + name = "Abductor Scientist" + + backpack_contents = list( + /obj/item/abductor/gizmo = 1 + ) + +/datum/outfit/abductor/scientist/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + if(!visualsOnly) + var/obj/item/implant/abductor/beamplant = new /obj/item/implant/abductor(H) + beamplant.implant(H) \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm index d07381b7cce..d4d791c5b19 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm @@ -15,7 +15,7 @@ return FALSE var/mob/living/carbon/human/H = user // You must either: Be of the abductor species, or contain an abductor implant - if((H.get_species() == "Abductor" || (locate(/obj/item/implant/abductor) in H))) + if((isabductor(H) || (locate(/obj/item/implant/abductor) in H))) return TRUE return FALSE @@ -37,7 +37,7 @@ /datum/surgery_step/internal/extract_organ/end_step(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/mob/living/carbon/human/AB = target - if(NO_INTORGANS in AB.species.species_traits) + if(NO_INTORGANS in AB.dna.species.species_traits) user.visible_message("[user] prepares [target]'s [target_zone] for further dissection!", "You prepare [target]'s [target_zone] for further dissection.") return TRUE if(IC) @@ -93,7 +93,7 @@ return FALSE var/mob/living/carbon/human/H = user // You must either: Be of the abductor species, or contain an abductor implant - if((H.get_species() == "Abductor" || (locate(/obj/item/implant/abductor) in H))) + if((isabductor(H) || (locate(/obj/item/implant/abductor) in H))) return TRUE return FALSE diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 8e7219e401a..8f058a872e6 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -14,28 +14,69 @@ var/active = 0 tough = TRUE //not easily broken by combat damage + var/mind_control_uses = 1 + var/mind_control_duration = 1800 + var/active_mind_control = FALSE + /obj/item/organ/internal/heart/gland/proc/ownerCheck() if(ishuman(owner)) - return 1 + return TRUE if(!human_only && iscarbon(owner)) - return 1 - return 0 + return TRUE + return FALSE /obj/item/organ/internal/heart/gland/proc/Start() active = 1 next_activation = world.time + rand(cooldown_low,cooldown_high) +/obj/item/organ/internal/heart/gland/proc/update_gland_hud() + if(!owner) + return + var/image/holder = owner.hud_list[GLAND_HUD] + var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) + holder.pixel_y = I.Height() - world.icon_size + if(active_mind_control) + holder.icon_state = "hudgland_active" + else if(mind_control_uses) + holder.icon_state = "hudgland_ready" + else + holder.icon_state = "hudgland_spent" + +/obj/item/organ/internal/heart/gland/proc/mind_control(command, mob/living/user) + if(!ownerCheck() || !mind_control_uses || active_mind_control) + return + mind_control_uses-- + to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order...") + to_chat(owner, "[command]") + active_mind_control = TRUE + log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]") + update_gland_hud() + + addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration) + +/obj/item/organ/internal/heart/gland/proc/clear_mind_control() + if(!ownerCheck() || !active_mind_control) + return + to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders.") + active_mind_control = FALSE + update_gland_hud() /obj/item/organ/internal/heart/gland/remove(var/mob/living/carbon/M, special = 0) active = 0 if(initial(uses) == 1) uses = initial(uses) + var/datum/atom_hud/abductor/hud = huds[DATA_HUD_ABDUCTOR] + hud.remove_from_hud(owner) + clear_mind_control() . = ..() /obj/item/organ/internal/heart/gland/insert(var/mob/living/carbon/M, special = 0) ..() if(special != 2 && uses) // Special 2 means abductor surgery Start() + var/datum/atom_hud/abductor/hud = huds[DATA_HUD_ABDUCTOR] + hud.add_to_hud(owner) + update_gland_hud() /obj/item/organ/internal/heart/gland/on_life() if(!beating) @@ -61,9 +102,12 @@ cooldown_high = 400 uses = -1 icon_state = "health" + mind_control_uses = 3 + mind_control_duration = 3000 /obj/item/organ/internal/heart/gland/heals/activate() to_chat(owner, "You feel curiously revitalized.") + owner.adjustToxLoss(-20) owner.adjustBruteLoss(-20) owner.adjustOxyLoss(-20) owner.adjustFireLoss(-20) @@ -73,6 +117,13 @@ cooldown_high = 1200 uses = -1 icon_state = "slime" + mind_control_uses = 1 + mind_control_duration = 2400 + +/obj/item/organ/internal/heart/gland/slime/insert(mob/living/carbon/M, special = 0) + ..() + owner.faction |= "slime" + owner.add_language("Bubblish") /obj/item/organ/internal/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") @@ -84,10 +135,12 @@ /obj/item/organ/internal/heart/gland/mindshock origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" - cooldown_low = 300 - cooldown_high = 300 + cooldown_low = 400 + cooldown_high = 700 uses = -1 icon_state = "mindshock" + mind_control_uses = 1 + mind_control_duration = 6000 /obj/item/organ/internal/heart/gland/mindshock/activate() to_chat(owner, "You get a headache.") @@ -96,19 +149,29 @@ for(var/mob/living/carbon/H in orange(4,T)) if(H == owner) continue - to_chat(H, "You hear a buzz in your head.") - H.AdjustConfused(20) + switch(pick(1,3)) + if(1) + to_chat(H, "You hear a loud buzz in your head, silencing your thoughts!") + H.Stun(3) + if(2) + to_chat(H, "You hear an annoying buzz in your head.") + H.AdjustConfused(15) + H.adjustBrainLoss(5, 15) + if(3) + H.hallucination += 60 /obj/item/organ/internal/heart/gland/pop cooldown_low = 900 cooldown_high = 1800 uses = -1 - human_only = 1 + human_only = TRUE icon_state = "species" + mind_control_uses = 5 + mind_control_duration = 3000 /obj/item/organ/internal/heart/gland/pop/activate() to_chat(owner, "You feel unlike yourself.") - var/species = pick("Unathi","Skrell","Diona","Tajaran","Vulpkanin","Kidan","Grey","Diona") + var/species = pick(/datum/species/unathi, /datum/species/skrell, /datum/species/diona, /datum/species/tajaran, /datum/species/vulpkanin, /datum/species/kidan, /datum/species/grey) owner.set_species(species) /obj/item/organ/internal/heart/gland/ventcrawling @@ -117,6 +180,8 @@ cooldown_high = 2400 uses = 1 icon_state = "vent" + mind_control_uses = 4 + mind_control_duration = 1800 /obj/item/organ/internal/heart/gland/ventcrawling/activate() to_chat(owner, "You feel very stretchy.") @@ -128,23 +193,44 @@ cooldown_high = 2400 uses = 1 icon_state = "viral" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/internal/heart/gland/viral/activate() to_chat(owner, "You feel sick.") - var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis) - var/datum/disease/D = new virus_type() - D.carrier = TRUE - owner.viruses += D - D.affected_mob = owner - owner.med_hud_set_status() + var/datum/disease/advance/A = random_virus(pick(2, 6), 6) + A.carrier = TRUE + owner.ForceContractDisease(A) + +/obj/item/organ/internal/heart/gland/viral/proc/random_virus(max_symptoms, max_level) + if(max_symptoms > VIRUS_SYMPTOM_LIMIT) + max_symptoms = VIRUS_SYMPTOM_LIMIT + var/datum/disease/advance/A = new /datum/disease/advance() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A /obj/item/organ/internal/heart/gland/emp //TODO : Replace with something more interesting origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" - cooldown_low = 900 - cooldown_high = 1600 + cooldown_low = 800 + cooldown_high = 1200 uses = 10 icon_state = "emp" + mind_control_uses = 3 + mind_control_duration = 1800 /obj/item/organ/internal/heart/gland/emp/activate() to_chat(owner, "You feel a spike of pain in your head.") @@ -153,25 +239,71 @@ /obj/item/organ/internal/heart/gland/spiderman cooldown_low = 450 cooldown_high = 900 - uses = 10 + uses = -1 icon_state = "spider" + mind_control_uses = 2 + mind_control_duration = 2400 /obj/item/organ/internal/heart/gland/spiderman/activate() to_chat(owner, "You feel something crawling in your skin.") owner.faction |= "spiders" - new /obj/structure/spider/spiderling(owner.loc) + var/obj/structure/spider/spiderling/S = new(owner.loc) + S.master_commander = owner /obj/item/organ/internal/heart/gland/egg cooldown_low = 300 cooldown_high = 400 uses = -1 icon_state = "egg" + mind_control_uses = 2 + mind_control_duration = 1800 /obj/item/organ/internal/heart/gland/egg/activate() - to_chat(owner, "You lay an egg!") - var/obj/item/reagent_containers/food/snacks/egg/egg = new(owner.loc) - egg.reagents.add_reagent("sacid",20) - egg.desc += " It smells bad." + owner.visible_message("[owner] [pick(EGG_LAYING_MESSAGES)]") + new /obj/item/reagent_containers/food/snacks/egg/gland(get_turf(owner)) + +/obj/item/organ/internal/heart/gland/electric + cooldown_low = 800 + cooldown_high = 1200 + uses = -1 + mind_control_uses = 2 + mind_control_duration = 900 + +/obj/item/organ/internal/heart/gland/electric/insert(mob/living/carbon/M, special = 0) + ..() + if(ishuman(owner)) + owner.gene_stability += GENE_INSTABILITY_MODERATE // give them this gene for free + owner.dna.SetSEState(SHOCKIMMUNITYBLOCK, TRUE) + genemutcheck(owner, SHOCKIMMUNITYBLOCK, null, MUTCHK_FORCED) + +/obj/item/organ/internal/heart/gland/electric/remove(mob/living/carbon/M, special = 0) + if(ishuman(owner)) + owner.gene_stability -= GENE_INSTABILITY_MODERATE // but return it to normal once it's removed + owner.dna.SetSEState(SHOCKIMMUNITYBLOCK, FALSE) + genemutcheck(owner, SHOCKIMMUNITYBLOCK, null, MUTCHK_FORCED) + return ..() + +/obj/item/organ/internal/heart/gland/electric/activate() + owner.visible_message("[owner]'s skin starts emitting electric arcs!",\ + "You feel electric energy building up inside you!") + playsound(get_turf(owner), "sparks", 100, 1, -1) + addtimer(CALLBACK(src, .proc/zap), rand(30, 100)) + +/obj/item/organ/internal/heart/gland/electric/proc/zap() + tesla_zap(owner, 4, 8000) + playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1) + +/obj/item/organ/internal/heart/gland/chem + cooldown_low = 50 + cooldown_high = 50 + uses = -1 + mind_control_uses = 3 + mind_control_duration = 1200 + +/obj/item/organ/internal/heart/gland/chem/activate() + owner.reagents.add_reagent(get_random_reagent_id(), 2) + owner.adjustToxLoss(-2) + ..() /obj/item/organ/internal/heart/gland/bloody cooldown_low = 200 @@ -217,8 +349,8 @@ var/mob/living/carbon/human/interactive/greytide/clone = new(src) var/datum/dna/owner_dna = H.dna clone.rename_character(clone.name, owner_dna.real_name) + clone.set_species(owner_dna.species.type) clone.dna = owner_dna.Clone() - clone.set_species(H.species.name) clone.body_accessory = H.body_accessory domutcheck(clone) @@ -257,6 +389,8 @@ cooldown_high = 1800 origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3" uses = -1 + mind_control_uses = 1 + mind_control_duration = 800 /obj/item/organ/internal/heart/gland/plasma/activate() spawn(0) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm index 219ae4b6e54..cd4f80f2527 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/camera.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/camera.dm @@ -2,7 +2,6 @@ name = "Human Observation Console" var/team = 0 networks = list("SS13","Abductor") - off_action = new /datum/action/innate/camera_off/abductor //specific datum var/datum/action/innate/teleport_in/tele_in_action = new var/datum/action/innate/teleport_out/tele_out_action = new var/datum/action/innate/teleport_self/tele_self_action = new @@ -25,65 +24,43 @@ eyeobj.icon_state = "camera_target" /obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user) - off_action.target = user - off_action.Grant(user) + ..() - jump_action.target = user - jump_action.Grant(user) - //TODO : add null checks - tele_in_action.target = console.pad - tele_in_action.Grant(user) + if(tele_in_action) + tele_in_action.target = console.pad + tele_in_action.Grant(user) + actions += tele_in_action - tele_out_action.target = console - tele_out_action.Grant(user) + if(tele_out_action) + tele_out_action.target = console + tele_out_action.Grant(user) + actions += tele_out_action - tele_self_action.target = console.pad - tele_self_action.Grant(user) + if(tele_self_action) + tele_self_action.target = console.pad + tele_self_action.Grant(user) + actions += tele_self_action - vest_mode_action.target = console - vest_mode_action.Grant(user) + if(vest_mode_action) + vest_mode_action.target = console + vest_mode_action.Grant(user) + actions += vest_mode_action - vest_disguise_action.target = console - vest_disguise_action.Grant(user) + if(vest_disguise_action) + vest_disguise_action.target = console + vest_disguise_action.Grant(user) + actions += vest_disguise_action - set_droppoint_action.target = console - set_droppoint_action.Grant(user) - -/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H) - if(H.mind && H.mind.abductor) - return H.mind.abductor.scientist + if(set_droppoint_action) + set_droppoint_action.target = console + set_droppoint_action.Grant(user) + actions += set_droppoint_action /obj/machinery/computer/camera_advanced/abductor/attack_hand(mob/user) if(!isabductor(user)) return return ..() -/datum/action/innate/camera_off/abductor/Activate() - if(!target || !iscarbon(target)) - return - var/mob/living/carbon/C = target - var/mob/camera/aiEye/remote/remote_eye = C.remote_control - var/obj/machinery/computer/camera_advanced/abductor/origin = remote_eye.origin - C.remote_view = 0 - origin.current_user = null - origin.jump_action.Remove(C) - origin.tele_in_action.Remove(C) - origin.tele_out_action.Remove(C) - origin.tele_self_action.Remove(C) - origin.vest_mode_action.Remove(C) - origin.vest_disguise_action.Remove(C) - origin.set_droppoint_action.Remove(C) - remote_eye.eye_user = null - C.reset_perspective(null) - if(C.client) - C.client.images -= remote_eye.user_image - for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks) - C.client.images -= chunk.obscured - C.remote_control = null - C.unset_machine() - src.Remove(C) - - /datum/action/innate/teleport_in name = "Send To" button_icon_state = "beam_down" diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm index 10cd5473279..0e8c4d3c409 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm @@ -54,21 +54,22 @@ dat += "Agent Vest
" dat += "Radio Silencer
" dat += "Science Tool
" + dat += "Mental Interface Device
" else dat += "NO EXPERIMENT MACHINE DETECTED
" - if(pad!=null) + if(pad) dat += "Emergency Teleporter System." dat += "Consider using primary observation console first." dat += "Activate Teleporter
" - if(gizmo!=null && gizmo.marked!=null) + if(gizmo && gizmo.marked) dat += "Retrieve Mark
" else dat += "Retrieve Mark
" else dat += "NO TELEPAD DETECTED
" - if(vest!=null) + if(vest) dat += "

Agent Vest Mode


" var/mode = vest.mode if(mode == VEST_STEALTH) @@ -100,13 +101,14 @@ else if(href_list["flip_vest"]) FlipVest() else if(href_list["toggle_vest"]) - toggle_vest() + if(vest) + vest.toggle_nodrop() else if(href_list["select_disguise"]) SelectDisguise() else if(href_list["dispense"]) switch(href_list["dispense"]) if("baton") - Dispense(/obj/item/abductor_baton,cost=2) + Dispense(/obj/item/abductor_baton, cost = 2) if("helmet") Dispense(/obj/item/clothing/head/helmet/abductor) if("silencer") @@ -115,19 +117,21 @@ Dispense(/obj/item/abductor/gizmo) if("vest") Dispense(/obj/item/clothing/suit/armor/abductor/vest) + if("mind_device") + Dispense(/obj/item/abductor/mind_device, cost = 2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() - if(gizmo!=null && pad!=null && gizmo.marked) + if(pad && gizmo && gizmo.marked) pad.Retrieve(gizmo.marked) /obj/machinery/abductor/console/proc/TeleporterSend() - if(pad!=null) + if(pad) pad.Send() /obj/machinery/abductor/console/proc/FlipVest() - if(vest!=null) + if(vest) vest.flip_mode() /obj/machinery/abductor/console/proc/SelectDisguise(remote = 0) @@ -175,21 +179,36 @@ return disguises[entry.name] = entry +/obj/machinery/abductor/console/proc/AddGizmo(obj/item/abductor/gizmo/G) + if(G == gizmo && G.console == src) + return FALSE + + if(G.console) + G.console.gizmo = null + + gizmo = G + G.console = src + return TRUE + +/obj/machinery/abductor/console/proc/AddVest(obj/item/clothing/suit/armor/abductor/vest/V) + if(vest == V) + return FALSE + + for(var/obj/machinery/abductor/console/C in machines) + if(C.vest == V) + C.vest = null + break + + vest = V + return TRUE + /obj/machinery/abductor/console/attackby(obj/O, mob/user, params) - if(istype(O, /obj/item/abductor/gizmo)) - var/obj/item/abductor/gizmo/G = O + if(istype(O, /obj/item/abductor/gizmo) && AddGizmo(O)) to_chat(user, "You link the tool to the console.") - gizmo = G - G.console = src - else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest)) - var/obj/item/clothing/suit/armor/abductor/vest/V = O + else if(istype(O, /obj/item/clothing/suit/armor/abductor/vest) && AddVest(O)) to_chat(user, "You link the vest to the console.") - if(istype(vest)) - if(vest.flags & NODROP) - toggle_vest() - vest = V else - ..() + return ..() /obj/machinery/abductor/console/proc/Dispense(item,cost=1) if(experiment && experiment.credits >= cost) @@ -201,10 +220,4 @@ else new item(src.loc) else - atom_say("Insufficent data!") - -/obj/machinery/abductor/console/proc/toggle_vest() - vest.flags ^= NODROP - var/mob/M = vest.loc - if(istype(M)) - to_chat(M, "[src] is now [vest.flags & NODROP ? "locked" : "unlocked"].") \ No newline at end of file + atom_say("Insufficent data!") \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm index 9e07c9c04a9..1a377667650 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm @@ -3,8 +3,8 @@ desc = "A tank filled with replacement organs" icon = 'icons/obj/abductor.dmi' icon_state = "dispenser" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE var/list/gland_types var/list/gland_colors var/list/amounts @@ -49,7 +49,7 @@ var/g_color = gland_colors[i] var/amount = amounts[i] dat += "[amount]" - if(item_count == 3) // Three boxes per line + if(item_count == 4) // Three boxes per line dat +="

" item_count = 0 var/datum/browser/popup = new(user, "glands", "Gland Dispenser", 200, 200) @@ -68,7 +68,7 @@ if(gland_types[i] == W.type) amounts[i]++ else - ..() + return ..() /obj/machinery/abductor/gland_dispenser/Topic(href, href_list) if(..()) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 8682b50fc05..53969aaf7d1 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -3,8 +3,8 @@ desc = "A large man-sized tube sporting a complex array of surgical apparatus." icon = 'icons/obj/abductor.dmi' icon_state = "experiment-open" - anchored = 1 - density = 1 + anchored = TRUE + density = TRUE var/points = 0 var/credits = 0 var/list/history = list() @@ -47,9 +47,9 @@ /obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H) var/icon/I = icon(H.stand_icon) - var/icon/splat = icon(H.species.damage_overlays, "30") - splat.Blend(icon(H.species.damage_mask, "torso"), ICON_MULTIPLY) - splat.Blend(H.species.blood_color, ICON_MULTIPLY) + var/icon/splat = icon(H.dna.species.damage_overlays, "30") + splat.Blend(icon(H.dna.species.damage_mask, "torso"), ICON_MULTIPLY) + splat.Blend(H.dna.species.blood_color, ICON_MULTIPLY) I.Blend(splat, ICON_OVERLAY) return I @@ -137,6 +137,7 @@ to_chat(H, "You feel intensely watched.") sleep(5) to_chat(H, "Your mind snaps!") + to_chat(H, "You can't remember how you got here...") var/objtype = pick(subtypesof(/datum/objective/abductee/)) var/datum/objective/abductee/O = new objtype() ticker.mode.abductees += H.mind diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 03b7d2e1b56..6b976ad7f05 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -123,7 +123,7 @@ to_chat(src, "Prime Directives:") to_chat(src, "1. Consume resources and replicate until there are no more resources left.") to_chat(src, "2. Ensure that the station is fit for invasion at a later date, do not perform actions that would render it dangerous or inhospitable.") - to_chat(src, "3. Biological and Sentient resources will be harvested at a later date, do not harm them.") + to_chat(src, "3. Biological and sentient resources will be harvested at a later date, do not harm them.") /mob/living/simple_animal/hostile/swarmer/New() ..() @@ -306,6 +306,12 @@ /obj/spacepod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) to_chat(S, "Destroying this vehicle would destroy us. Aborting.") +/obj/machinery/clonepod/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) + if(occupant) + to_chat(S, "Destroying this machine while it is occupied would result in biological and sentient resources to be harmed. Aborting.") + return + ..() + /mob/living/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) S.DisperseTarget(src) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index feffadcf9ab..17afd375952 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -141,15 +141,15 @@ proc/issyndicate(mob/living/M as mob) return ..() -/datum/game_mode/proc/create_syndicate(var/datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human +/datum/game_mode/proc/create_syndicate(datum/mind/synd_mind) // So we don't have inferior species as ops - randomize a human var/mob/living/carbon/human/M = synd_mind.current - var/obj/item/organ/external/head/head_organ = M.get_organ("head") - M.set_species("Human",1) + M.set_species(/datum/species/human, TRUE) M.dna.ready_dna(M) // Quadriplegic Nuke Ops won't be participating in the paralympics M.reagents.add_reagent("mutadone", 1) //No fat/blind/colourblind/epileptic/whatever ops. M.overeatduration = 0 + var/obj/item/organ/external/head/head_organ = M.get_organ("head") var/hair_c = pick("#8B4513","#000000","#FF4500","#FFD700") // Brown, black, red, blonde var/eye_c = pick("#000000","#8B4513","1E90FF") // Black, brown, blue var/skin_tone = pick(-50, -30, -10, 0, 0, 0, 10) // Caucasian/black @@ -159,8 +159,8 @@ proc/issyndicate(mob/living/M as mob) head_organ.sec_hair_colour = hair_c M.change_eye_color(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.dna.species.name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.name) M.body_accessory = null M.regenerate_icons() M.update_body() @@ -253,7 +253,7 @@ proc/issyndicate(mob/living/M as mob) U.hidden_uplink.uses = 20 synd_mob.equip_to_slot_or_del(U, slot_in_backpack) - if(synd_mob.species) + if(synd_mob.dna.species) /* Incase anyone ever gets the burning desire to have nukeops with randomized apperances. -- Dave @@ -262,7 +262,7 @@ proc/issyndicate(mob/living/M as mob) A.randomize_appearance_for(synd_mob) */ - var/race = synd_mob.species.name + var/race = synd_mob.dna.species.name switch(race) if("Vox" || "Vox Armalis") diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 07395aa0578..b7364970351 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -281,7 +281,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu 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(!(NO_DNA in H.species.species_traits)) + if(!(NO_DNA in H.dna.species.species_traits)) possible_targets += possible_target if(possible_targets.len > 0) target = pick(possible_targets) @@ -445,7 +445,7 @@ var/list/potential_theft_objectives = subtypesof(/datum/theft_objective) - /datu n_p++ else if(ticker.current_state == GAME_STATE_PLAYING) for(var/mob/living/carbon/human/P in player_list) - if(NO_DNA in P.species.species_traits) + if(NO_DNA in P.dna.species.species_traits) continue if(P.client && !(P.mind in ticker.mode.changelings) && P.mind!=owner) n_p++ diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 1d0bb3adf03..6a1c242efb4 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -209,7 +209,7 @@ Made by Xhuis if(shadow.special_role == SPECIAL_ROLE_SHADOWLING && config.shadowling_max_age) if(ishuman(shadow.current)) var/mob/living/carbon/human/H = shadow.current - if(H.get_species() != "Shadow") + if(!isshadowling(H)) for(var/obj/effect/proc_holder/spell/targeted/shadowling_hatch/hatch_ability in shadow.spell_list) hatch_ability.cycles_unused++ if(!H.stunned && prob(20) && hatch_ability.cycles_unused > config.shadowling_max_age) @@ -306,93 +306,6 @@ Made by Xhuis MISCELLANEOUS */ - -/datum/species/shadow/ling - //Normal shadowpeople but with enhanced effects - name = "Shadowling" - - icobase = 'icons/mob/human_races/r_shadowling.dmi' - deform = 'icons/mob/human_races/r_shadowling.dmi' - - blood_color = "#555555" - flesh_color = "#222222" - - species_traits = list(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 - heatmod = 1.5 - - silent_steps = 1 - grant_vision_toggle = 0 - - has_organ = list( - "brain" = /obj/item/organ/internal/brain, - "eyes" = /obj/item/organ/internal/eyes) - -/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 = 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") - var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) - if(istype(E)) - E.receive_damage(-1) - H.heal_overall_damage(5, 5) - H.adjustToxLoss(-5) - H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!" - H.AdjustEyeBlurry(-1) - H.CureNearsighted() - H.CureBlind() - H.adjustCloneLoss(-1) - H.SetWeakened(0) - H.SetStunned(0) - ..() - - -/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful - name = "Lesser Shadowling" - - icobase = 'icons/mob/human_races/r_lshadowling.dmi' - deform = 'icons/mob/human_races/r_lshadowling.dmi' - - blood_color = "#CCCCCC" - flesh_color = "#AAAAAA" - - species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE) - burn_mod = 1.1 - oxy_mod = 0 - heatmod = 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 = 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) - H.adjustCloneLoss(-1) - ..() - /datum/game_mode/proc/update_shadow_icons_added(datum/mind/shadow_mind) var/datum/atom_hud/antag/shadow_hud = huds[ANTAG_HUD_SHADOW] shadow_hud.join_hud(shadow_mind.current) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 89aee290422..ea846e394a5 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -2,8 +2,10 @@ /obj/effect/proc_holder/spell/proc/shadowling_check(var/mob/living/carbon/human/H) if(!H || !istype(H)) return - if(H.get_species() == "Shadowling" && is_shadow(H)) return 1 - if(H.get_species() == "Lesser Shadowling" && is_thrall(H)) return 1 + if(isshadowling(H) && is_shadow(H)) + return 1 + if(isshadowlinglesser(H) && is_thrall(H)) + return 1 if(!is_shadow_or_thrall(usr)) to_chat(usr, "You can't wrap your head around how to do this.") else if(is_thrall(usr)) @@ -267,7 +269,7 @@ listclearnulls(ticker.mode.shadowling_thralls) if(!(ling.mind in ticker.mode.shadows)) return - if(ling.get_species() != "Shadowling") + if(!isshadowling(ling)) if(ticker.mode.shadowling_thralls.len >= 5) charge_counter = charge_max return @@ -363,6 +365,7 @@ var/mob/living/carbon/human/H = target H.visible_message("[H]'s skin suddenly bubbles and shifts around [H.p_their()] body!", \ "You regenerate your protective armor and cleanse your form of defects.") + H.set_species(/datum/species/shadow/ling) 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) @@ -371,7 +374,6 @@ H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(H), slot_gloves) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(H), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(H), slot_glasses) - H.set_species("Shadowling") /obj/effect/proc_holder/spell/targeted/collective_mind //Lets a shadowling bring together their thralls' strength, granting new abilities and a headcount name = "Collective Hivemind" @@ -610,7 +612,7 @@ to_chat(user, "[thrallToRevive] must be conscious to become empowered.") charge_counter = charge_max return - if(thrallToRevive.get_species() == "Lesser Shadowling") + if(isshadowlinglesser(thrallToRevive)) to_chat(user, "[thrallToRevive] is already empowered.") charge_counter = charge_max return @@ -619,7 +621,7 @@ if(!ishuman(M.current)) return var/mob/living/carbon/human/H = M.current - if(H.get_species() == "Lesser Shadowling") + if(isshadowlinglesser(H)) empowered_thralls++ if(empowered_thralls >= EMPOWERED_THRALL_LIMIT) to_chat(user, "You cannot spare this much energy. There are too many empowered thralls.") @@ -644,7 +646,7 @@ 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, you now have glare and true shadow walk.") - thrallToRevive.set_species("Lesser Shadowling") + thrallToRevive.set_species(/datum/species/shadow/ling/lesser) 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)) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 4239b5db327..7aebaa0b044 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -84,6 +84,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N H.socks = "None" H.faction |= "faithless" + H.set_species(/datum/species/shadow/ling) //can't be a shadowling without being a shadowling 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) @@ -91,7 +92,6 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N 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) diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm index 44e722abfca..d3f29734815 100644 --- a/code/game/gamemodes/steal_items.dm +++ b/code/game/gamemodes/steal_items.dm @@ -118,7 +118,7 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/aicard/C) typepath = /obj/item/documents //Any set of secret documents. Doesn't have to be NT's /datum/theft_objective/hypospray - name = "a hypospray" + name = "the Chief Medical Officer's hypospray" typepath = /obj/item/reagent_containers/hypospray/CMO protected_jobs = list("Chief Medical Officer") diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index c9dad5c510d..6d82f6c48e1 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -239,7 +239,7 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user scramble(1, H, 100) - H.real_name = random_name(H.gender, H.species.name) //Give them a name that makes sense for their species. + H.real_name = random_name(H.gender, H.dna.species.name) //Give them a name that makes sense for their species. H.sync_organ_dna(assimilate = 1) H.update_body(0) H.reset_hair() //No more winding up with hairstyles you're not supposed to have, and blowing your cover. diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 7c1a3526002..2ac4bc0b2f8 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -321,11 +321,11 @@ var/global/list/multiverse = list() to_chat(M, "You are an alternate version of [user.real_name] from another universe! Help [user.p_them()] accomplish [user.p_their()] goals at all costs.") M.faction = list("[user.real_name]") if(duplicate_self) - M.set_species(user.get_species()) //duplicate the sword user's species. + M.set_species(user.dna.species.type) //duplicate the sword user's species. else if(prob(50)) - var/list/all_species = list("Human","Unathi","Skrell","Tajaran","Kidan","Golem","Diona","Machine","Slime People","Grey","Vulpkanin") - M.set_species(pick(all_species)) + var/list/list_all_species = list(/datum/species/human, /datum/species/unathi, /datum/species/skrell, /datum/species/tajaran, /datum/species/kidan, /datum/species/golem, /datum/species/diona, /datum/species/machine, /datum/species/slime, /datum/species/grey, /datum/species/vulpkanin) + M.set_species(pick(list_all_species)) M.real_name = user.real_name //this is clear down here in case the user happens to become a golem; that way they have the proper name. M.name = user.real_name if(duplicate_self) @@ -429,7 +429,7 @@ var/global/list/multiverse = list() M.equip_to_slot_or_del(sword, slot_r_hand) //Don't duplicate what's equipped to hands, or else duplicate swords could be generated...or weird cases of factionless swords. else - if(M.get_species() == "Tajaran" || M.get_species() == "Unathi") + if(istajaran(M) || isunathi(M)) M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes) //If they can't wear shoes, give them a pair of sandals. var/randomize = pick("mobster","roman","wizard","cyborg","syndicate","assistant", "animu", "cultist", "highlander", "clown", "killer", "pirate", "soviet", "officer", "gladiator") @@ -461,7 +461,7 @@ var/global/list/multiverse = list() M.equip_to_slot_or_del(sword, slot_r_hand) if("cyborg") - if(M.get_species() != "Machine") + if(!ismachine(M)) for(var/obj/item/organ/O in M.bodyparts) O.robotize(make_tough = 1) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) @@ -584,10 +584,10 @@ var/global/list/multiverse = list() W.SetOwnerInfo(M) M.equip_to_slot_or_del(W, slot_wear_id) - if(M.get_species() == "Vox") - M.species.after_equip_job(null, M) //Voxygen(tm) - if(M.get_species() == "Plasmaman") - M.species.after_equip_job(null, M) //No fireballs from other dimensions. + if(isvox(M)) + M.dna.species.after_equip_job(null, M) //Nitrogen tanks + if(isplasmaman(M)) + M.dna.species.after_equip_job(null, M) //No fireballs from other dimensions. M.update_icons() @@ -646,7 +646,7 @@ var/global/list/multiverse = list() if(heresy) spawnheresy(M)//oh god why else - M.set_species("Skeleton") + M.set_species(/datum/species/skeleton) M.visible_message(" A massive amount of flesh sloughs off [M] and a skeleton rises up!") M.revive() equip_skeleton(M) @@ -713,7 +713,7 @@ var/global/list/multiverse = list() H.equip_to_slot_or_del(new /obj/item/twohanded/spear(H), slot_back) /obj/item/necromantic_stone/proc/spawnheresy(mob/living/carbon/human/H as mob) - H.set_species("Human") + H.set_species(/datum/species/human) if(H.gender == MALE) H.change_gender(FEMALE) diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index b5e798b95c7..18dda0fcbc4 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -141,7 +141,7 @@ wizard_mob.equip_to_slot_or_del(new /obj/item/radio/headset(wizard_mob), slot_l_ear) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(wizard_mob), slot_w_uniform) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes) - if(wizard_mob.get_species() != "Plasmaman") //handled in the species file for plasmen on the afterjob equip proc for now + if(!isplasmaman(wizard_mob)) //handled in the species file for plasmen on the afterjob equip proc for now wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit) wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head) wizard_mob.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(wizard_mob), slot_back) @@ -153,7 +153,7 @@ wizard_mob.faction = list("wizard") - wizard_mob.species.after_equip_job(null, wizard_mob) + wizard_mob.dna.species.after_equip_job(null, wizard_mob) to_chat(wizard_mob, "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.") to_chat(wizard_mob, "The spellbook is bound to you, and others cannot use it.") diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index ffcb288c1c5..418539b5bed 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -74,12 +74,12 @@ if(!H) return 0 - H.species.before_equip_job(src, H, visualsOnly) + H.dna.species.before_equip_job(src, H, visualsOnly) if(outfit) H.equipOutfit(outfit, visualsOnly) - H.species.after_equip_job(src, H, visualsOnly) + H.dna.species.after_equip_job(src, H, visualsOnly) if(!visualsOnly && announce) announce(H) @@ -183,7 +183,7 @@ else permitted = TRUE - if(G.whitelisted && (G.whitelisted != H.species.name || !is_alien_whitelisted(H, G.whitelisted))) + if(G.whitelisted && (G.whitelisted != H.dna.species.name || !is_alien_whitelisted(H, G.whitelisted))) permitted = FALSE if(!permitted) diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 154a34750cd..972b5732a9b 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -244,7 +244,7 @@ if(visualsOnly) return - if(H.get_species() == "Machine") + if(ismachine(H)) var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant = new implant.insert(H) @@ -381,7 +381,6 @@ shoes = /obj/item/clothing/shoes/black l_ear = /obj/item/radio/headset/headset_service backpack_contents = list( - /obj/item/clothing/shoes/black = 1, /obj/item/storage/box/lip_stick = 1, /obj/item/storage/box/barber = 1 ) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index e0463000c9e..661453adfc3 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -10,22 +10,31 @@ idle_power_usage = 0 var/syndicate = 0 var/obj/item/radio/beacon/Beacon + var/enabled = TRUE /obj/machinery/bluespace_beacon/New() ..() + create_beacon() + +/obj/machinery/bluespace_beacon/proc/create_beacon() var/turf/T = loc Beacon = new /obj/item/radio/beacon Beacon.invisibility = INVISIBILITY_MAXIMUM Beacon.loc = T Beacon.syndicate = syndicate - hide(T.intact) -/obj/machinery/bluespace_beacon/Destroy() +/obj/machinery/bluespace_beacon/proc/destroy_beacon() QDEL_NULL(Beacon) + +/obj/machinery/bluespace_beacon/proc/toggle() + enabled = !enabled + return enabled + +/obj/machinery/bluespace_beacon/Destroy() + destroy_beacon() return ..() -// update the invisibility and icon /obj/machinery/bluespace_beacon/hide(var/intact) invisibility = intact ? 101 : 0 update_icon() @@ -33,21 +42,36 @@ // update the icon_state /obj/machinery/bluespace_beacon/update_icon() var/state="floor_beacon" - if(invisibility) icon_state = "[state]f" - else icon_state = "[state]" /obj/machinery/bluespace_beacon/process() - if(!Beacon) - var/turf/T = loc - Beacon = new /obj/item/radio/beacon - Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.loc = T - if(Beacon) - if(Beacon.loc != loc) - Beacon.loc = loc + if(enabled) + if(Beacon) + if(Beacon.loc != loc) + Beacon.loc = loc + else + create_beacon() + update_icon() + else + if(Beacon) + destroy_beacon() + update_icon() - update_icon() + +/obj/machinery/bluespace_beacon/syndicate + syndicate = TRUE + enabled = FALSE + var/obj/machinery/computer/syndicate_depot/teleporter/mycomputer + +/obj/machinery/bluespace_beacon/syndicate/New() + ..() + if(!GAMEMODE_IS_NUCLEAR && prob(50)) + enabled = TRUE + +/obj/machinery/bluespace_beacon/syndicate/Destroy() + if(mycomputer) + mycomputer.mybeacon = null + return ..() \ No newline at end of file diff --git a/code/game/machinery/Freezer.dm b/code/game/machinery/Freezer.dm index b065c87b8ab..dc06a13e076 100644 --- a/code/game/machinery/Freezer.dm +++ b/code/game/machinery/Freezer.dm @@ -57,9 +57,10 @@ if(exchange_parts(user, I)) return - default_deconstruction_crowbar(I) + if(default_deconstruction_crowbar(I)) + return - if(istype(I, /obj/item/wrench)) + if(iswrench(I)) if(!panel_open) to_chat(user, "Open the maintenance panel first.") return @@ -75,6 +76,8 @@ break build_network() update_icon() + else + return ..() /obj/machinery/atmospherics/unary/cold_sink/freezer/update_icon() if(panel_open) @@ -137,7 +140,11 @@ if(href_list["toggleStatus"]) src.on = !src.on update_icon() - if(href_list["temp"]) + else if(href_list["minimum"]) + current_temperature = min_temperature + else if(href_list["maximum"]) + current_temperature = T20C + else if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) src.current_temperature = min(T20C, src.current_temperature+amount) @@ -216,9 +223,10 @@ if(exchange_parts(user, I)) return - default_deconstruction_crowbar(I) + if(default_deconstruction_crowbar(I)) + return - if(istype(I, /obj/item/wrench)) + if(iswrench(I)) if(!panel_open) to_chat(user, "Open the maintenance panel first.") return @@ -234,6 +242,8 @@ break build_network() update_icon() + else + return ..() /obj/machinery/atmospherics/unary/heat_reservoir/heater/update_icon() if(panel_open) @@ -293,7 +303,11 @@ if(href_list["toggleStatus"]) src.on = !src.on update_icon() - if(href_list["temp"]) + else if(href_list["minimum"]) + current_temperature = T20C + else if(href_list["maximum"]) + current_temperature = max_temperature + T20C + else if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) src.current_temperature = min((T20C+max_temperature), src.current_temperature+amount) diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index f7925fecda5..360d5cc5aff 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -142,19 +142,20 @@ take_victim(usr,usr) -/obj/machinery/optable/attackby(obj/item/W as obj, mob/living/carbon/user as mob, params) - if(istype(W, /obj/item/grab)) - if(iscarbon(W:affecting)) - take_victim(W:affecting,usr) - qdel(W) - return - if(istype(W, /obj/item/wrench)) - playsound(src.loc, W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) +/obj/machinery/optable/attackby(obj/item/I, mob/living/carbon/user, params) + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I + if(iscarbon(G.affecting)) + take_victim(G.affecting, user) + qdel(G) + if(iswrench(I)) + playsound(loc, I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) to_chat(user, "You deconstruct the table.") new /obj/item/stack/sheet/plasteel(loc, 5) qdel(src) - + else + return ..() /obj/machinery/optable/proc/check_table(mob/living/carbon/patient as mob) if(src.victim && get_turf(victim) == get_turf(src) && victim.lying) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index a90bc66bce3..f3701945017 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -43,19 +43,21 @@ QDEL_NULL(storedpda) return ..() -/obj/machinery/pdapainter/attackby(var/obj/item/O as obj, var/mob/user as mob, params) - if(istype(O, /obj/item/pda)) +/obj/machinery/pdapainter/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pda)) if(storedpda) to_chat(user, "There is already a PDA inside.") return else - var/obj/item/pda/P = usr.get_active_hand() + var/obj/item/pda/P = user.get_active_hand() if(istype(P)) - user.drop_item() - storedpda = P - P.loc = src - P.add_fingerprint(usr) - update_icon() + if(user.drop_item()) + storedpda = P + P.forceMove(src) + P.add_fingerprint(user) + update_icon() + else + return ..() /obj/machinery/pdapainter/attack_hand(mob/user as mob) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 24311a8b12e..44ef4ee26da 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -11,7 +11,7 @@ var/base_icon = "sleeper" density = 1 anchored = 1 - dir = 8 + dir = WEST var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r" var/mob/living/carbon/human/occupant = null var/possible_chems = list(list("epinephrine", "ether", "salbutamol", "styptic_powder", "silver_sulfadiazine"), @@ -92,15 +92,15 @@ if(filtering > 0) if(beaker) // To prevent runtimes from drawing blood from runtime, and to prevent getting IPC blood. - if(!istype(occupant) || !occupant.dna || (NO_BLOOD in occupant.species.species_traits)) + if(!istype(occupant) || !occupant.dna || (NO_BLOOD in occupant.dna.species.species_traits)) filtering = 0 return if(beaker.reagents.total_volume < beaker.reagents.maximum_volume) - src.occupant.transfer_blood_to(beaker, 1) - for(var/datum/reagent/x in src.occupant.reagents.reagent_list) - src.occupant.reagents.trans_to(beaker, 3) - src.occupant.transfer_blood_to(beaker, 1) + occupant.transfer_blood_to(beaker, 1) + for(var/datum/reagent/x in occupant.reagents.reagent_list) + occupant.reagents.trans_to(beaker, 3) + occupant.transfer_blood_to(beaker, 1) if(occupant) for(var/A in occupant.reagents.addiction_list) @@ -117,7 +117,7 @@ if(M == occupant) continue else - M.forceMove(src.loc) + M.forceMove(loc) updateDialog() return @@ -167,10 +167,10 @@ occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations // Because we can put simple_animals in here, we need to do something tricky to get things working nice occupantData["temperatureSuitability"] = 0 // 0 is the baseline - if(ishuman(occupant) && occupant.species) + if(ishuman(occupant) && occupant.dna.species) // I wanna do something where the bar gets bluer as the temperature gets lower // For now, I'll just use the standard format for the temperature status - var/datum/species/sp = occupant.species + var/datum/species/sp = occupant.dna.species if(occupant.bodytemperature < sp.cold_level_3) occupantData["temperatureSuitability"] = -3 else if(occupant.bodytemperature < sp.cold_level_2) @@ -197,7 +197,7 @@ crisis = (occupant.health < min_health) // I'm not sure WHY you'd want to put a simple_animal in a sleeper, but precedent is precedent // Runtime is aptly named, isn't she? - if(ishuman(occupant) && !(NO_BLOOD in occupant.species.species_traits)) + if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits)) occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) occupantData["hasBlood"] = 1 occupantData["bloodLevel"] = round(occupant.blood_volume) @@ -253,7 +253,7 @@ to_chat(usr, "Close the maintenance panel first.") return 0 - if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) + if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) if(href_list["chemical"]) if(occupant) if(occupant.stat == DEAD) @@ -268,7 +268,7 @@ toggle_filter() if(href_list["ejectify"]) eject() - src.add_fingerprint(usr) + add_fingerprint(usr) return 1 /obj/machinery/sleeper/blob_act() @@ -280,84 +280,84 @@ return -/obj/machinery/sleeper/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/reagent_containers/glass)) +/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers/glass)) if(!beaker) if(!user.drop_item()) - to_chat(user, "\The [G] is stuck to you!") + to_chat(user, "[I] is stuck to you!") return - beaker = G - G.forceMove(src) - user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!") + beaker = I + I.forceMove(src) + user.visible_message("[user] adds \a [I] to [src]!", "You add \a [I] to [src]!") return else to_chat(user, "The sleeper has a beaker already.") return - if(istype(G, /obj/item/screwdriver)) - if(src.occupant) + if(isscrewdriver(I)) + if(occupant) to_chat(user, "The maintenance panel is locked.") return - default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", G) + default_deconstruction_screwdriver(user, "[base_icon]-o", "[base_icon]-open", I) return - if(istype(G, /obj/item/wrench)) - if(src.occupant) + if(iswrench(I)) + if(occupant) to_chat(user, "The scanner is occupied.") return if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) + if(dir == EAST) orient = "LEFT" - dir = 8 + setDir(WEST) else orient = "RIGHT" - dir = 4 - playsound(src.loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) return - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) return - if(istype(G, /obj/item/grab)) - var/obj/item/grab/GG = G + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(!ismob(GG.affecting)) + if(!ismob(G.affecting)) return - if(src.occupant) + if(occupant) to_chat(user, "The sleeper is already occupied!") return - for(var/mob/living/carbon/slime/M in range(1,GG.affecting)) - if(M.Victim == GG.affecting) - to_chat(usr, "[GG.affecting.name] will not fit into the sleeper because [GG.affecting.p_they()] [GG.affecting.p_have()] a slime latched onto [GG.affecting.p_their()] head.") + for(var/mob/living/carbon/slime/M in range(1, G.affecting)) + if(M.Victim == G.affecting) + to_chat(user, "[G.affecting.name] will not fit into the sleeper because [G.affecting.p_they()] [G.affecting.p_have()] a slime latched onto [G.affecting.p_their()] head.") return - visible_message("[user] starts putting [GG.affecting.name] into the sleeper.") + visible_message("[user] starts putting [G.affecting.name] into the sleeper.") - if(do_after(user, 20, target = GG.affecting)) - if(src.occupant) + if(do_after(user, 20, target = G.affecting)) + if(occupant) to_chat(user, "The sleeper is already occupied!") return - if(!GG || !GG.affecting) return - var/mob/M = GG.affecting + if(!G || !G.affecting) + return + var/mob/M = G.affecting M.forceMove(src) - src.occupant = M - src.icon_state = "[base_icon]" + occupant = M + icon_state = "[base_icon]" to_chat(M, "You feel cool air surround you. You go numb as your senses turn inward.") + add_fingerprint(user) + qdel(G) + return - src.add_fingerprint(user) - qdel(GG) - return - return + return ..() /obj/machinery/sleeper/ex_act(severity) @@ -366,21 +366,21 @@ switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return @@ -423,10 +423,10 @@ to_chat(user, "The sleeper does not offer that chemical!") return - if(src.occupant) - if(src.occupant.reagents) - if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) - src.occupant.reagents.add_reagent(chemical, amount) + if(occupant) + if(occupant.reagents) + if(occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem) + occupant.reagents.add_reagent(chemical, amount) return else to_chat(user, "You can not inject any more of this chemical.") @@ -446,8 +446,8 @@ if(usr.incapacitated()) //are you cuffed, dying, lying, stunned or other return - src.icon_state = "[base_icon]-open" - src.go_out() + icon_state = "[base_icon]-open" + go_out() add_fingerprint(usr) return @@ -505,15 +505,15 @@ visible_message("[user] starts putting [L.name] into the sleeper.") if(do_after(user, 20, target = L)) - if(src.occupant) + if(occupant) to_chat(user, "The sleeper is already occupied!") return if(!L) return L.forceMove(src) - src.occupant = L - src.icon_state = "[base_icon]" + occupant = L + icon_state = "[base_icon]" to_chat(L, "You feel cool air surround you. You go numb as your senses turn inward.") - src.add_fingerprint(user) + add_fingerprint(user) if(user.pulling == L) user.stop_pulling() return @@ -528,7 +528,7 @@ set src in oview(1) if(usr.stat != 0 || !(ishuman(usr))) return - if(src.occupant) + if(occupant) to_chat(usr, "The sleeper is already occupied!") return if(panel_open) @@ -542,17 +542,17 @@ return visible_message("[usr] starts climbing into the sleeper.") if(do_after(usr, 20, target = usr)) - if(src.occupant) + if(occupant) to_chat(usr, "The sleeper is already occupied!") return usr.stop_pulling() usr.forceMove(src) - src.occupant = usr - src.icon_state = "[base_icon]" + occupant = usr + icon_state = "[base_icon]" for(var/obj/O in src) qdel(O) - src.add_fingerprint(usr) + add_fingerprint(usr) return return diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 040fd848cfd..2566cc0f410 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -2,9 +2,9 @@ name = "body scanner" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "bodyscanner-open" - density = 1 - dir = 8 - anchored = 1 + density = TRUE + dir = WEST + anchored = TRUE idle_power_usage = 1250 active_power_usage = 2500 @@ -32,7 +32,7 @@ if(M == occupant) continue else - M.forceMove(src.loc) + M.forceMove(loc) /obj/machinery/bodyscanner/New() ..() @@ -54,37 +54,36 @@ component_parts += new /obj/item/stack/cable_coil(null, 2) RefreshParts() -/obj/machinery/bodyscanner/attackby(var/obj/item/G as obj, var/mob/user as mob) - if(istype(G, /obj/item/screwdriver)) - if(src.occupant) +/obj/machinery/bodyscanner/attackby(obj/item/I, mob/user) + if(isscrewdriver(I)) + if(occupant) to_chat(user, "The maintenance panel is locked.") return - default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", G) + default_deconstruction_screwdriver(user, "bodyscanner-o", "bodyscanner-open", I) return - if(istype(G, /obj/item/wrench)) - if(src.occupant) + if(iswrench(I)) + if(occupant) to_chat(user, "The scanner is occupied.") return if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) - dir = 8 + if(dir == EAST) + setDir(WEST) else - dir = 4 - playsound(src.loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) return - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) return - if(istype(G, /obj/item/grab)) - var/obj/item/grab/TYPECAST_YOUR_SHIT = G + if(istype(I, /obj/item/grab)) + var/obj/item/grab/TYPECAST_YOUR_SHIT = I if(panel_open) to_chat(user, "Close the maintenance panel first.") return @@ -105,7 +104,10 @@ occupant = M icon_state = "body_scanner_1" add_fingerprint(user) - qdel(G) + qdel(TYPECAST_YOUR_SHIT) + return + + return ..() /obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/human/O, mob/user as mob) @@ -123,7 +125,7 @@ to_chat(user, "Close the maintenance panel first.") return 0 //panel open if(occupant) - to_chat(user, "\The [src] is already occupied.") + to_chat(user, "[src] is already occupied.") return 0 //occupied if(O.buckled) @@ -137,7 +139,7 @@ return 0 if(O == user) - visible_message("[user] climbs into \the [src].") + visible_message("[user] climbs into [src].") else visible_message("[user] puts [O] into the body scanner.") @@ -175,21 +177,21 @@ switch(severity) if(1.0) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(2.0) if(prob(50)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return if(3.0) if(prob(25)) for(var/atom/movable/A as mob|obj in src) - A.forceMove(src.loc) + A.forceMove(loc) A.ex_act(severity) qdel(src) return @@ -220,7 +222,7 @@ icon_state = "bodyscannerconsole" density = 1 anchored = 1 - dir = 8 + dir = WEST idle_power_usage = 250 active_power_usage = 500 var/obj/machinery/bodyscanner/connected = null @@ -238,7 +240,7 @@ stat &= ~NOPOWER else spawn(rand(0, 15)) - src.icon_state = "bodyscannerconsole-p" + icon_state = "bodyscannerconsole-p" stat |= NOPOWER /obj/machinery/body_scanconsole/New() @@ -292,33 +294,35 @@ break -/obj/machinery/body_scanconsole/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/screwdriver)) - default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", G) +/obj/machinery/body_scanconsole/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "bodyscannerconsole-p", "bodyscannerconsole", I)) return - if(istype(G, /obj/item/wrench)) + if(iswrench(I)) if(panel_open) to_chat(user, "Close the maintenance panel first.") return - if(dir == 4) - dir = 8 + if(dir == EAST) + setDir(WEST) else - dir = 4 - playsound(loc, G.usesound, 50, 1) + setDir(EAST) + playsound(loc, I.usesound, 50, 1) - if(exchange_parts(user, G)) + if(exchange_parts(user, I)) return - default_deconstruction_crowbar(G) + if(default_deconstruction_crowbar(I)) + return + else + return ..() -/obj/machinery/body_scanconsole/attack_ai(user as mob) +/obj/machinery/body_scanconsole/attack_ai(user) return attack_hand(user) -/obj/machinery/body_scanconsole/attack_ghost(user as mob) +/obj/machinery/body_scanconsole/attack_ghost(user) return attack_hand(user) -/obj/machinery/body_scanconsole/attack_hand(user as mob) +/obj/machinery/body_scanconsole/attack_hand(user) if(stat & (NOPOWER|BROKEN)) return @@ -326,13 +330,13 @@ to_chat(user, "Close the maintenance panel first.") return - if(!src.connected) + if(!connected) findscanner() ui_interact(user) -/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) +/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 600) @@ -383,7 +387,7 @@ var/bloodData[0] bloodData["hasBlood"] = 0 - if(ishuman(H) && !(NO_BLOOD in H.species.species_traits)) + if(ishuman(H) && !(NO_BLOOD in H.dna.species.species_traits)) bloodData["hasBlood"] = 1 bloodData["volume"] = H.blood_volume bloodData["percent"] = round(((H.blood_volume / BLOOD_VOLUME_NORMAL)*100)) @@ -475,14 +479,14 @@ return 1 if(href_list["ejectify"]) - src.connected.eject() + connected.eject() if(href_list["print_p"]) generate_printing_text() if(!(printing) && printing_text) printing = 1 - visible_message("\The [src] rattles and prints out a sheet of paper.") + visible_message("[src] rattles and prints out a sheet of paper.") var/obj/item/paper/P = new /obj/item/paper(loc) playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) P.info = "
Body Scan - [href_list["name"]]

" @@ -654,7 +658,7 @@ if(occupant.disabilities & NEARSIGHTED) dat += "Retinal misalignment detected.
" else - dat += "\The [src] is empty." + dat += "[src] is empty." else dat = " Error: No Body Scanner connected." diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index f24197009bd..de32918c068 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -973,31 +973,30 @@ playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1) return -/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob, params) - src.add_fingerprint(user) +/obj/machinery/alarm/attackby(obj/item/I, mob/user, params) + add_fingerprint(user) switch(buildstage) if(2) - if(istype(W, /obj/item/screwdriver)) // Opening that Air Alarm up. -// to_chat(user, "You pop the Air Alarm's maintence panel open.") + if(isscrewdriver(I)) // Opening that Air Alarm up. wiresexposed = !wiresexposed to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]") update_icon() return - if(istype(W, /obj/item/wirecutters)) // cutting the wires out + if(iswirecutter(I)) // cutting the wires out if(wires.wires_status == 31) // all wires cut var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil() new_coil.amount = 5 - new_coil.loc = user.loc + new_coil.forceMove(user.loc) buildstage = 1 update_icon() - return + return - if(wiresexposed && ((istype(W, /obj/item/multitool) || istype(W, /obj/item/wirecutters)))) + if(wiresexposed && ((ismultitool(I) || iswirecutter(I)))) return attack_hand(user) - if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda))// trying to unlock the interface with an ID card + if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))// trying to unlock the interface with an ID card if(stat & (NOPOWER|BROKEN)) to_chat(user, "It does nothing") return @@ -1008,13 +1007,11 @@ updateUsrDialog() else to_chat(user, "Access denied.") - - - return + return if(1) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = W + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = I if(coil.amount < 5) to_chat(user, "You need more cable for this!") return @@ -1030,34 +1027,35 @@ first_run() return - else if(istype(W, /obj/item/crowbar)) + else if(iscrowbar(I)) to_chat(user, "You start prying out the circuit.") - playsound(get_turf(src), W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) + playsound(get_turf(src), I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) if(buildstage != 1) return to_chat(user, "You pry out the circuit!") var/obj/item/airalarm_electronics/circuit = new /obj/item/airalarm_electronics() - circuit.loc = user.loc + circuit.forceMove(user.loc) buildstage = 0 update_icon() return if(0) - if(istype(W, /obj/item/airalarm_electronics)) + if(istype(I, /obj/item/airalarm_electronics)) to_chat(user, "You insert the circuit!") - playsound(get_turf(src), W.usesound, 50, 1) - qdel(W) + playsound(get_turf(src), I.usesound, 50, 1) + qdel(I) buildstage = 1 update_icon() return - else if(istype(W, /obj/item/wrench)) + else if(iswrench(I)) to_chat(user, "You remove the fire alarm assembly from the wall!") new /obj/item/mounted/frame/alarm_frame(get_turf(user)) - playsound(get_turf(src), W.usesound, 50, 1) + playsound(get_turf(src), I.usesound, 50, 1) qdel(src) + return - return 0 + return ..() /obj/machinery/alarm/power_change() if(powered(power_channel)) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 0e9f261d73d..e555ee91ce8 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -6,15 +6,18 @@ use_power = 2 idle_power_usage = 5 active_power_usage = 10 - layer = 5 + layer = WALL_OBJ_LAYER + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0) var/datum/wires/camera/wires = null // Wires datum + max_integrity = 100 + integrity_failure = 50 var/list/network = list("SS13") var/c_tag = null var/c_tag_order = 999 var/status = 1 - anchored = 1 - var/start_active = 0 //If it ignores the random chance to start broken on round start + anchored = TRUE + var/start_active = FALSE //If it ignores the random chance to start broken on round start var/invuln = null var/obj/item/camera_bug/bug = null var/obj/item/camera_assembly/assembly = null @@ -24,17 +27,14 @@ var/view_range = 7 var/short_range = 2 - var/light_disabled = 0 - var/alarm_on = 0 - var/busy = 0 - var/emped = 0 //Number of consecutive EMP's on this camera + var/busy = FALSE + var/emped = FALSE //Number of consecutive EMP's on this camera - var/toggle_message = 'sound/items/Wirecutter.ogg' + var/toggle_sound = 'sound/items/Wirecutter.ogg' /obj/machinery/camera/New() ..() wires = new(src) - assembly = new(src) assembly.state = 4 assembly.anchored = 1 @@ -46,14 +46,14 @@ /obj/machinery/camera/Initialize() ..() if(is_station_level(z) && prob(3) && !start_active) - toggle_cam() + toggle_cam(null, FALSE) wires.CutAll() /obj/machinery/camera/Destroy() - toggle_cam(null, 0) //kick anyone viewing out + toggle_cam(null, FALSE) //kick anyone viewing out QDEL_NULL(assembly) if(istype(bug)) - bug.bugged_cameras -= src.c_tag + bug.bugged_cameras -= c_tag if(bug.current == src) bug.current = null bug = null @@ -71,147 +71,124 @@ return if(!isEmpProof()) if(prob(150/severity)) - icon_state = "[initial(icon_state)]emp" + update_icon() var/list/previous_network = network network = list() cameranet.removeCamera(src) stat |= EMPED set_light(0) emped = emped+1 //Increase the number of consecutive EMP's + update_icon() var/thisemp = emped //Take note of which EMP this proc is for spawn(900) - if(loc) //qdel limbo + if(!QDELETED(src)) triggerCameraAlarm() //camera alarm triggers even if multiple EMPs are in effect. if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again network = previous_network - icon_state = initial(icon_state) stat &= ~EMPED - cancelCameraAlarm() + update_icon() if(can_use()) cameranet.addCamera(src) emped = 0 //Resets the consecutive EMP count spawn(100) if(!QDELETED(src)) cancelCameraAlarm() - for(var/mob/O in mob_list) - if(O.client && O.client.eye == src) - O.unset_machine() - O.reset_perspective(null) - to_chat(O, "The screen bursts into static.") + for(var/mob/M in player_list) + if(M.client && M.client.eye == src) + M.unset_machine() + M.reset_perspective(null) + to_chat(M, "The screen bursts into static.") ..() -/obj/machinery/camera/tesla_act(var/power)//EMP proof upgrade also makes it tesla immune +/obj/machinery/camera/tesla_act(power)//EMP proof upgrade also makes it tesla immune if(isEmpProof()) return ..() qdel(src)//to prevent bomb testing camera from exploding over and over forever -/obj/machinery/camera/ex_act(severity, target) - if(src.invuln) +/obj/machinery/camera/ex_act(severity) + if(invuln) return - else - ..() - return - -/obj/machinery/camera/blob_act() - qdel(src) - return - -/obj/machinery/camera/attack_ghost(mob/user) - if(panel_open) - wires.Interact(user) - -/obj/machinery/camera/attack_alien(mob/living/carbon/alien/humanoid/user) - if(!istype(user)) - return - user.do_attack_animation(src) - add_hiddenprint(user) - status = 0 - visible_message("\The [user] slashes at [src]!") - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - toggle_cam(user, 0) - + ..() /obj/machinery/camera/proc/setViewRange(num = 7) - src.view_range = num + view_range = num cameranet.updateVisibility(src, 0) -/obj/machinery/camera/attackby(obj/item/W, mob/living/user as mob, params) - var/msg = "You attach [W] into the assembly inner circuits." +/obj/machinery/camera/attackby(obj/item/I, mob/living/user, params) + var/msg = "You attach [I] into the assembly inner circuits." var/msg2 = "The camera already has that upgrade!" // DECONSTRUCTION - if(istype(W, /obj/item/screwdriver)) -// to_chat(user, "You start to [panel_open ? "close" : "open"] the camera's panel.") - //if(toggle_panel(user)) // No delay because no one likes screwdrivers trying to be hip and have a duration cooldown + if(isscrewdriver(I)) panel_open = !panel_open - user.visible_message("[user] screws the camera's panel [panel_open ? "open" : "closed"]!", - "You screw the camera's panel [panel_open ? "open" : "closed"].") - playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You screw the camera's panel [panel_open ? "open" : "closed"].") + playsound(loc, I.usesound, 50, 1) - else if((istype(W, /obj/item/wirecutters) || istype(W, /obj/item/multitool)) && panel_open) + else if((iswirecutter(I) || ismultitool(I)) && panel_open) wires.Interact(user) - else if(istype(W, /obj/item/weldingtool) && wires.CanDeconstruct()) - if(weld(W, user)) - to_chat(user, "You unweld the camera leaving it as just a frame screwed to the wall.") - if(!assembly) - assembly = new() - assembly.loc = src.loc - assembly.state = 1 - assembly.dir = src.dir - assembly.update_icon() - assembly = null - qdel(src) + else if(iswelder(I) && panel_open && wires.CanDeconstruct()) + var/obj/item/weldingtool/WT = I + if(!WT.remove_fuel(0, user)) return - else if(istype(W, /obj/item/analyzer) && panel_open) //XRay - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + to_chat(user, "You start to weld [src]...") + playsound(loc, WT.usesound, 50, 1) + if(do_after(user, 100 * WT.toolspeed, target = src)) + user.visible_message("[user] unwelds [src], leaving it as just a frame bolted to the wall.", + "You unweld [src], leaving it as just a frame bolted to the wall") + deconstruct(TRUE) + + else if(istype(I, /obj/item/analyzer) && panel_open) //XRay + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isXRay()) upgradeXRay() - qdel(W) + qdel(I) to_chat(user, "[msg]") else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/stack/sheet/mineral/plasma) && panel_open) - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + else if(istype(I, /obj/item/stack/sheet/mineral/plasma) && panel_open) + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isEmpProof()) + var/obj/item/stack/sheet/mineral/plasma/P = I upgradeEmpProof() to_chat(user, "[msg]") - qdel(W) + P.use(1) else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/assembly/prox_sensor) && panel_open) - if(!user.unEquip(W)) + else if(istype(I, /obj/item/assembly/prox_sensor) && panel_open) + if(!user.drop_item()) + to_chat(user, "[I] is stuck to your hand!") return if(!isMotion()) upgradeMotion() to_chat(user, "[msg]") - qdel(W) + qdel(I) else to_chat(user, "[msg2]") // OTHER - else if((istype(W, /obj/item/paper) || istype(W, /obj/item/pda)) && isliving(user)) + else if((istype(I, /obj/item/paper) || istype(I, /obj/item/pda)) && isliving(user)) var/mob/living/U = user var/obj/item/paper/X = null - var/obj/item/pda/P = null + var/obj/item/pda/PDA = null var/itemname = "" var/info = "" - if(istype(W, /obj/item/paper)) - X = W + if(istype(I, /obj/item/paper)) + X = I itemname = X.name info = X.info else - P = W - var/datum/data/pda/app/notekeeper/N = P.find_program(/datum/data/pda/app/notekeeper) + PDA = I + var/datum/data/pda/app/notekeeper/N = PDA.find_program(/datum/data/pda/app/notekeeper) if(N) - itemname = P.name + itemname = PDA.name info = N.notehtml to_chat(U, "You hold \the [itemname] up to the camera ...") U.changeNext_move(CLICK_CD_MELEE) @@ -229,37 +206,59 @@ to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...") O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - else if(istype(W, /obj/item/camera_bug)) - if(!src.can_use()) + else if(istype(I, /obj/item/camera_bug)) + if(!can_use()) to_chat(user, "Camera non-functional.") return - if(istype(src.bug)) + if(istype(bug)) to_chat(user, "Camera bug removed.") - src.bug.bugged_cameras -= src.c_tag - src.bug = null + bug.bugged_cameras -= c_tag + bug = null else to_chat(user, "Camera bugged.") - src.bug = W - src.bug.bugged_cameras[src.c_tag] = src + bug = I + bug.bugged_cameras[c_tag] = src - else if(istype(W, /obj/item/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting. - toggle_cam(user, 1) - var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread() - spark_system.set_up(5, 0, loc) - spark_system.start() - playsound(loc, W.usesound, 50, 1) - playsound(loc, "sparks", 50, 1) - visible_message("[user] has sliced the camera apart with an energy blade!") - qdel(src) - - else if(istype(W, /obj/item/laser_pointer)) - var/obj/item/laser_pointer/L = W + else if(istype(I, /obj/item/laser_pointer)) + var/obj/item/laser_pointer/L = I L.laser_act(src, user) else - ..() - return + return ..() -/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = 1) +/obj/machinery/camera/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee" && damage_amount < 12 && !(stat & BROKEN)) + return 0 + . = ..() + +/obj/machinery/camera/obj_break(damage_flag) + if(status) + triggerCameraAlarm() + toggle_cam(null, FALSE) + wires.CutAll() + +/obj/machinery/camera/deconstruct(disassembled = TRUE) + if(disassembled) + if(!assembly) + assembly = new() + assembly.forceMove(loc) + assembly.state = 1 + assembly.setDir(dir) + assembly.update_icon() + assembly = null + else + new /obj/item/camera_assembly(loc) + new /obj/item/stack/cable_coil(loc, 2) + qdel(src) + +/obj/machinery/camera/update_icon() + if(!status) + icon_state = "[initial(icon_state)]1" + else if(stat & EMPED) + icon_state = "[initial(icon_state)]emp" + else + icon_state = "[initial(icon_state)]" + +/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) status = !status if(can_use()) cameranet.addCamera(src) @@ -268,10 +267,7 @@ cameranet.removeCamera(src) cameranet.updateChunk(x, y, z) var/change_msg = "deactivates" - if(!status) - icon_state = "[initial(icon_state)]1" - else - icon_state = initial(icon_state) + if(status) change_msg = "reactivates" triggerCameraAlarm() spawn(100) @@ -284,7 +280,8 @@ else visible_message("\The [src] [change_msg]!") - playsound(src.loc, toggle_message, 100, 1) + playsound(loc, toggle_sound, 100, 1) + update_icon() // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. @@ -295,16 +292,11 @@ O.reset_perspective(null) to_chat(O, "The screen bursts into static.") -/obj/machinery/camera/proc/triggerCameraAlarm(var/duration = 0) - alarm_on = 1 - motion_alarm.triggerAlarm(loc, src) +/obj/machinery/camera/proc/triggerCameraAlarm() + camera_alarm.triggerAlarm(loc, src) /obj/machinery/camera/proc/cancelCameraAlarm() - if(wires.IsIndexCut(CAMERA_WIRE_ALARM)) - return - - alarm_on = 0 - motion_alarm.clearAlarm(loc, src) + camera_alarm.clearAlarm(loc, src) /obj/machinery/camera/proc/can_use() if(!status) @@ -331,25 +323,25 @@ //If someone knows a better way to do this, let me know. -Giacom switch(i) if(NORTH) - src.dir = SOUTH + setDir(SOUTH) if(SOUTH) - src.dir = NORTH + setDir(NORTH) if(WEST) - src.dir = EAST + setDir(EAST) if(EAST) - src.dir = WEST + setDir(WEST) break //Return a working camera that can see a given mob //or null if none -/proc/seen_by_camera(var/mob/M) +/proc/seen_by_camera(mob/M) for(var/obj/machinery/camera/C in oview(4, M)) if(C.can_use()) // check if camera disabled return C break return null -/proc/near_range_camera(var/mob/M) +/proc/near_range_camera(mob/M) for(var/obj/machinery/camera/C in range(4, M)) if(C.can_use()) // check if camera disabled return C @@ -357,32 +349,15 @@ return null -/obj/machinery/camera/proc/weld(var/obj/item/weldingtool/WT, var/mob/user) - if(busy) - return 0 - if(!WT.remove_fuel(0, user)) - return 0 - - to_chat(user, "You start to weld [src]...") - playsound(src.loc, WT.usesound, 50, 1) - busy = 1 - if(do_after(user, 100 * WT.toolspeed, target = src)) - busy = 0 - if(!WT.isOn()) - return 0 - return 1 - busy = 0 - return 0 - -/obj/machinery/camera/proc/Togglelight(on=0) +/obj/machinery/camera/proc/Togglelight(on = FALSE) for(var/mob/living/silicon/ai/A in ai_list) for(var/obj/machinery/camera/cam in A.lit_cameras) if(cam == src) return if(on) - src.set_light(AI_CAMERA_LUMINOSITY) + set_light(AI_CAMERA_LUMINOSITY) else - src.set_light(0) + set_light(0) /obj/machinery/camera/proc/nano_structure() var/cam[0] diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index dc5a0141b27..8baf02088bb 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -6,7 +6,8 @@ w_class = WEIGHT_CLASS_SMALL anchored = 0 materials = list(MAT_METAL=400, MAT_GLASS=250) - + max_integrity = 150 + can_be_hit = TRUE // Motion, EMP-Proof, X-Ray var/list/obj/item/possible_upgrades = list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/analyzer) var/list/upgrades = list() @@ -24,13 +25,13 @@ QDEL_LIST(upgrades) return ..() -/obj/item/camera_assembly/attackby(obj/item/W, mob/living/user, params) +/obj/item/camera_assembly/attackby(obj/item/I, mob/living/user, params) switch(state) if(0) // State 0 - if(iswrench(W) && isturf(src.loc)) - playsound(src.loc, W.usesound, 50, 1) + if(iswrench(I) && isturf(loc)) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You wrench the assembly into place.") anchored = 1 state = 1 @@ -40,15 +41,15 @@ if(1) // State 1 - if(iswelder(W)) - if(weld(W, user)) + if(iswelder(I)) + if(weld(I, user)) to_chat(user, "You weld the assembly securely into place.") anchored = 1 state = 2 return - else if(iswrench(W)) - playsound(src.loc, W.usesound, 50, 1) + else if(iswrench(I)) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You unattach the assembly from it's place.") anchored = 0 update_icon() @@ -57,19 +58,18 @@ if(2) // State 2 - if(iscoil(W)) - var/obj/item/stack/cable_coil/C = W + if(iscoil(I)) + var/obj/item/stack/cable_coil/C = I if(C.use(2)) to_chat(user, "You add wires to the assembly.") - playsound(loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) state = 3 else to_chat(user, "You need 2 coils of wire to wire the assembly.") return - else if(iswelder(W)) - - if(weld(W, user)) + else if(iswelder(I)) + if(weld(I, user)) to_chat(user, "You unweld the assembly from it's place.") state = 1 anchored = 1 @@ -78,8 +78,8 @@ if(3) // State 3 - if(isscrewdriver(W)) - playsound(src.loc, W.usesound, 50, 1) + if(isscrewdriver(I)) + playsound(loc, I.usesound, 50, 1) var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) if(!input) @@ -96,8 +96,8 @@ input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) state = 4 - var/obj/machinery/camera/C = new(src.loc) - src.loc = C + var/obj/machinery/camera/C = new(loc) + loc = C C.assembly = src C.auto_turn() @@ -119,35 +119,36 @@ break return - else if(iswirecutter(W)) + else if(iswirecutter(I)) new/obj/item/stack/cable_coil(get_turf(src), 2) - playsound(src.loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) to_chat(user, "You cut the wires from the circuits.") state = 2 return // Upgrades! - if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.unEquip(W)) - to_chat(user, "[W] is stuck!") + if(is_type_in_list(I, possible_upgrades) && !is_type_in_list(I, upgrades)) // Is a possible upgrade and isn't in the camera already. + if(!user.unEquip(I)) + to_chat(user, "[I] is stuck!") return - to_chat(user, "You attach \the [W] into the assembly inner circuits.") - upgrades += W + to_chat(user, "You attach [I] into the assembly inner circuits.") + upgrades += I user.drop_item() - W.loc = src + I.loc = src return // Taking out upgrades - else if(iscrowbar(W) && upgrades.len) + else if(iscrowbar(I) && upgrades.len) var/obj/U = locate(/obj) in upgrades if(U) to_chat(user, "You unattach an upgrade from the assembly.") - playsound(src.loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) U.loc = get_turf(src) upgrades -= U return - ..() + else + return ..() /obj/item/camera_assembly/update_icon() if(anchored) @@ -159,7 +160,7 @@ if(!anchored) ..() -/obj/item/camera_assembly/proc/weld(var/obj/item/weldingtool/WT, var/mob/living/user) +/obj/item/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) if(busy) return 0 @@ -167,7 +168,7 @@ return 0 to_chat(user, "You start to weld the [src]..") - playsound(src.loc, WT.usesound, 50, 1) + playsound(loc, WT.usesound, 50, 1) busy = 1 if(do_after(user, 20 * WT.toolspeed, target = src)) busy = 0 @@ -176,3 +177,7 @@ return 1 busy = 0 return 0 + +/obj/item/camera_assembly/deconstruct(disassembled = TRUE) + new /obj/item/stack/sheet/metal(loc) + qdel(src) \ No newline at end of file diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 57ade18dab3..6b728f2a20b 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -36,8 +36,8 @@ if(charging) to_chat(user, "Current charge: [round(charging.percent(), 1)]%") -/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/cell)) +/obj/machinery/cell_charger/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/stock_parts/cell)) if(stat & BROKEN) to_chat(user, "[src] is broken!") return @@ -57,19 +57,19 @@ if(!user.drop_item()) return - W.forceMove(src) - charging = W + I.forceMove(src) + charging = I user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") chargelevel = -1 updateicon() - else if(iswrench(W)) + else if(iswrench(I)) if(charging) to_chat(user, "Remove the cell first!") return anchored = !anchored to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") - playsound(src.loc, W.usesound, 75, 1) + playsound(src.loc, I.usesound, 75, 1) else return ..() diff --git a/code/game/machinery/chiller.dm b/code/game/machinery/chiller.dm index f48d59593ca..d2f76a7c42a 100644 --- a/code/game/machinery/chiller.dm +++ b/code/game/machinery/chiller.dm @@ -68,8 +68,8 @@ user << browse(null, "window=aircond") user.unset_machine() else - ..() - return + return ..() + /obj/machinery/space_heater/air_conditioner/attack_hand(mob/user as mob) src.add_fingerprint(user) interact(user) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index ee53fdbce8b..798a01f2bda 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -231,7 +231,7 @@ R.dna = new /datum/dna() var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) - H.set_species(R.dna.species) + H.set_species(R.dna.species.type) occupant = H if(!R.dna.real_name) //to prevent null names @@ -349,19 +349,19 @@ use_power(200) //Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/W, mob/user, params) +/obj/machinery/clonepod/attackby(obj/item/I, mob/user, params) if(!(occupant || mess)) - if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", W)) + if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", I)) return - if(exchange_parts(user, W)) + if(exchange_parts(user, I)) return - if(default_deconstruction_crowbar(W)) + if(default_deconstruction_crowbar(I)) return - if(W.GetID()) - if(!check_access(W)) + if(I.GetID()) + if(!check_access(I)) to_chat(user, "Access Denied.") return if(!(occupant || mess)) @@ -374,34 +374,33 @@ go_out() //Removing cloning pod biomass - else if(istype(W, /obj/item/reagent_containers/food/snacks/meat)) - to_chat(user, "\The [src] processes \the [W].") - biomass += BIOMASS_MEAT_AMOUNT - user.drop_item() - qdel(W) - return - else if(istype(W, /obj/item/wrench)) + else if(istype(I, /obj/item/reagent_containers/food/snacks/meat)) + if(user.drop_item()) + to_chat(user, "[src] processes [I].") + biomass += BIOMASS_MEAT_AMOUNT + qdel(I) + else if(iswrench(I)) if(occupant) to_chat(user, "Can not do that while [src] is in use.") else if(anchored) - anchored = 0 + anchored = FALSE connected.pods -= src connected = null else - anchored = 1 - playsound(loc, W.usesound, 100, 1) + anchored = TRUE + playsound(loc, I.usesound, 100, 1) if(anchored) user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") else user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") - else if(istype(W, /obj/item/multitool)) - var/obj/item/multitool/M = W + else if(ismultitool(I)) + var/obj/item/multitool/M = I M.buffer = src to_chat(user, "You load connection data from [src] to [M].") return else - ..() + return ..() /obj/machinery/clonepod/emag_act(user) if(isnull(occupant)) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 42061760d92..00bd309b21e 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -123,8 +123,8 @@ occupantData["maxTemp"] = 1000 // If you get a burning vox armalis into the sleeper, congratulations // Because we can put simple_animals in here, we need to do something tricky to get things working nice occupantData["temperatureSuitability"] = 0 // 0 is the baseline - if(ishuman(occupant) && occupant.species) - var/datum/species/sp = occupant.species + if(ishuman(occupant) && occupant.dna.species) + var/datum/species/sp = occupant.dna.species if(occupant.bodytemperature < sp.cold_level_3) occupantData["temperatureSuitability"] = -3 else if(occupant.bodytemperature < sp.cold_level_2) @@ -147,7 +147,7 @@ occupantData["btCelsius"] = occupant.bodytemperature - T0C occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32 - if(ishuman(occupant) && !(NO_BLOOD in occupant.species.species_traits)) + if(ishuman(occupant) && !(NO_BLOOD in occupant.dna.species.species_traits)) occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL) occupantData["hasBlood"] = 1 occupantData["bloodLevel"] = round(occupant.blood_volume) diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 2b3c338fa3d..67f1dba85f0 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -117,7 +117,7 @@ return laws = M.laws - if(istype(P, /obj/item/mmi) || istype(P, /obj/item/mmi/posibrain)) + if(istype(P, /obj/item/mmi)) if(!P:brainmob) to_chat(user, "Sticking an empty [P] into the frame would sort of defeat the purpose.") return diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 00f6a98f2bc..99eaeae3fe6 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -31,6 +31,7 @@ for(var/V in actions) var/datum/action/A = V A.Remove(user) + actions.Cut() if(user.client) user.reset_perspective(null) eyeobj.RemoveImages() @@ -52,6 +53,7 @@ if(current_user) current_user.unset_machine() QDEL_NULL(eyeobj) + QDEL_LIST(actions) return ..() /obj/machinery/computer/camera_advanced/on_unset_machine(mob/M) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 95aee7cb9fe..c134747cd41 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -356,15 +356,14 @@ return if(scan_brain && !can_brainscan()) return - if((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (NO_SCAN in subject.species.species_traits)) + if((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (NO_SCAN in subject.dna.species.species_traits)) scantemp = "Error: Unable to locate valid genetic data." SSnanoui.update_uis(src) return if(subject.get_int_organ(/obj/item/organ/internal/brain)) var/obj/item/organ/internal/brain/Brn = subject.get_int_organ(/obj/item/organ/internal/brain) if(istype(Brn)) - var/datum/species/S = all_species[Brn.dna.species] // stepladder code wooooo - if(NO_SCAN in S.species_traits) + if(NO_SCAN in Brn.dna.species.species_traits) scantemp = "Error: Subject's brain is incompatible." SSnanoui.update_uis(src) return @@ -402,10 +401,9 @@ var/obj/item/organ/B = subject.get_int_organ(/obj/item/organ/internal/brain) B.dna.check_integrity() R.dna=B.dna.Clone() - var/datum/species/S = all_species[R.dna.species] - if(NO_SCAN in S.species_traits) + if(NO_SCAN in R.dna.species.species_traits) extra_info = "Proper genetic interface not found, defaulting to genetic data of the body." - R.dna.species = subject.species.name + R.dna.species = new subject.dna.species.type R.id= copytext(md5(B.dna.real_name), 2, 6) R.name=B.dna.real_name else diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 054d4d441a3..865f683946e 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -231,7 +231,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return - var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") as text|null + var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return @@ -250,7 +250,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null + var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return @@ -270,7 +270,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return - var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null + var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return diff --git a/code/game/machinery/computer/depot.dm b/code/game/machinery/computer/depot.dm new file mode 100644 index 00000000000..6bd5eadc822 --- /dev/null +++ b/code/game/machinery/computer/depot.dm @@ -0,0 +1,519 @@ + +#define DEPOT_VISITOR_START 1 +#define DEPOT_VISITOR_END 2 +#define DEPOT_VISITOR_ADD 3 + + +// Generic parent depot computer type + +/obj/machinery/computer/syndicate_depot + name = "depot computer" + icon = 'icons/obj/computer.dmi' + icon_keyboard = "syndie_key" + icon_screen = "tcboss" + light_color = LIGHT_COLOR_PURE_CYAN + req_access = list(access_syndicate) + var/security_lockout = FALSE + var/sound_yes = 'sound/machines/twobeep.ogg' + var/sound_no = 'sound/machines/buzz-sigh.ogg' + var/sound_click = 'sound/machines/click.ogg' + var/area/syndicate_depot/core/depotarea + var/alerts_when_broken = FALSE + var/has_alerted = FALSE + + +/obj/machinery/computer/syndicate_depot/New() + . = ..() + depotarea = areaMaster + +/obj/machinery/computer/syndicate_depot/attack_ai(mob/user) + if(req_access.len && !("syndicate" in user.faction)) + to_chat(user, "A firewall blocks your access.") + return 1 + return ..() + +/obj/machinery/computer/syndicate_depot/emp_act(severity) + return + +/obj/machinery/computer/syndicate_depot/emag_act(mob/user) + to_chat(user, "The electronic systems in this console are far too advanced for your primitive hacking peripherals.") + return + +/obj/machinery/computer/syndicate_depot/allowed(mob/user) + if(user.can_advanced_admin_interact()) + return 1 + if(!isliving(user)) + return 0 + if(has_security_lockout(user)) + return 0 + return ..() + +/obj/machinery/computer/syndicate_depot/proc/has_security_lockout(mob/user) + if(security_lockout) + playsound(user, 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(user, "[src] is under security lockout.") + return TRUE + return FALSE + +/obj/machinery/computer/syndicate_depot/proc/activate_security_lockout() + security_lockout = TRUE + disable_special_functions() + +/obj/machinery/computer/syndicate_depot/attack_hand(mob/user) + if(..()) + return + if(stat & (NOPOWER|BROKEN)) + return + if(!allowed(user)) + to_chat(user, "Access Denied.") + return + user.set_machine(src) + var/dat = get_menu(user) + user << browse(dat, "window=computer;size=575x450") + onclose(user, "computer") + + +/obj/machinery/computer/syndicate_depot/set_broken() + . = ..() + if(alerts_when_broken && !has_alerted) + has_alerted = TRUE + raise_alert("[src] was damaged.") + disable_special_functions() + +/obj/machinery/computer/syndicate_depot/proc/disable_special_functions() + return + +/obj/machinery/computer/syndicate_depot/Topic(href, href_list) + if(..()) + return 1 + if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) + usr.set_machine(src) + if(href_list["primary"]) + primary(usr) + if(href_list["secondary"]) + secondary(usr, text2num(href_list["secondary"])) + add_fingerprint(usr) + updateUsrDialog() + +/obj/machinery/computer/syndicate_depot/Destroy() + disable_special_functions() + if(alerts_when_broken && !has_alerted) + raise_alert("[src] destroyed.") + return ..() + + +/obj/machinery/computer/syndicate_depot/proc/get_menu(mob/user) + return "" + +/obj/machinery/computer/syndicate_depot/proc/primary(mob/user) + if(!allowed(user)) + return 1 + return 0 + +/obj/machinery/computer/syndicate_depot/proc/secondary(mob/user, subcommand) + if(!allowed(user)) + return 1 + return 0 + +/obj/machinery/computer/syndicate_depot/proc/raise_alert(reason) + if(depotarea) + depotarea.increase_alert(reason) + + + +// Door Control Computer + +/obj/machinery/computer/syndicate_depot/doors + name = "depot door control computer" + +/obj/machinery/computer/syndicate_depot/doors/get_menu(mob/user) + return {"Syndicate Depot Door Control Computer
+

Toggle Airlock Emergency Access +

Toggle Hidden Doors +
"} + +/obj/machinery/computer/syndicate_depot/doors/primary(mob/user) + if(..()) + return + if(depotarea) + depotarea.toggle_door_locks(src) + to_chat(user, "Door locks toggled.") + +/obj/machinery/computer/syndicate_depot/doors/secondary(mob/user, subcommand) + if(..()) + return + if(depotarea) + depotarea.toggle_falsewalls(src) + to_chat(user, "False walls toggled.") + + +// Engineering AKA self destruct computer, no useful functions, just a trap for the people who can't resist pushing dangerous-sounding buttons. + +/obj/machinery/computer/syndicate_depot/selfdestruct + name = "reactor control computer" + icon_screen = "explosive" + req_access = list() + alerts_when_broken = TRUE + +/obj/machinery/computer/syndicate_depot/selfdestruct/get_menu(mob/user) + var menutext = {"Syndicate Depot Fusion Reactor Control
+

Disable Containment Field +
"} + return menutext + +/obj/machinery/computer/syndicate_depot/selfdestruct/primary(mob/user) + if(..()) + return + if(depotarea.used_self_destruct) + playsound(user, sound_no, 50, 0) + return + playsound(user, sound_click, 20, 1) + if(depotarea) + depotarea.activate_self_destruct("Fusion reactor containment field disengaged. All hands, evacuate. All hands, evacuate!", TRUE, user) + + +// Shield computer, used to manipulate base shield, and armory shield + +/obj/machinery/computer/syndicate_depot/shieldcontrol + name = "shield control computer" + icon_screen = "accelerator" + req_access = list(access_syndicate_leader) + alerts_when_broken = TRUE + var/area/syndicate_depot/perimeter/perimeterarea + +/obj/machinery/computer/syndicate_depot/shieldcontrol/New() + . = ..() + perimeterarea = locate(/area/syndicate_depot/perimeter) + if(istype(perimeterarea) && (GAMEMODE_IS_NUCLEAR || prob(20))) + spawn(200) + perimeterarea.perimeter_shields_up() + +/obj/machinery/computer/syndicate_depot/shieldcontrol/Destroy() + if(istype(perimeterarea) && perimeterarea.shield_list.len) + perimeterarea.perimeter_shields_down() + return ..() + +/obj/machinery/computer/syndicate_depot/shieldcontrol/get_menu(mob/user) + var menutext = {"Syndicate Depot Shield Grid Control
+
"} + menutext += {"(SYNDI-LEADER) Whole-base Shield: [perimeterarea.shield_list.len ? "ON" : "OFF"] ([perimeterarea.shield_list.len ? "Disable" : "Enable"])
"} + menutext += {"(SYNDI-LEADER) Armory Shield: [depotarea.shield_list.len ? "ON" : "OFF"] ([depotarea.shield_list.len ? "Disable" : "Enable"])
"} + return menutext + +/obj/machinery/computer/syndicate_depot/shieldcontrol/primary(mob/user) + if(..()) + return + if(depotarea.used_self_destruct) + playsound(user, sound_no, 50, 0) + return + if(!istype(perimeterarea)) + return + if(perimeterarea.shield_list.len) + perimeterarea.perimeter_shields_down() + else + perimeterarea.perimeter_shields_up() + playsound(user, sound_yes, 50, 0) + + +/obj/machinery/computer/syndicate_depot/shieldcontrol/secondary(mob/user) + if(..()) + return + if(!istype(depotarea)) + return + if(depotarea.shield_list.len) + depotarea.shields_down() + else + depotarea.shields_up() + playsound(user, sound_yes, 50, 0) + + +// Syndicate comms computer, used to activate visitor mode, and message syndicate. Traitor-only use. + +/obj/machinery/computer/syndicate_depot/syndiecomms + name = "syndicate communications computer" + icon_screen = "syndishuttle" + req_access = list() + alerts_when_broken = TRUE + var/message_sent = FALSE + +/obj/machinery/computer/syndicate_depot/syndiecomms/New() + . = ..() + if(depotarea) + depotarea.comms_computer = src + +/obj/machinery/computer/syndicate_depot/syndiecomms/Destroy() + if(depotarea) + depotarea.comms_computer = null + return ..() + +/obj/machinery/computer/syndicate_depot/syndiecomms/get_menu(mob/user) + var/menu = "Syndicate Communications Relay
" + menu += "

One-Time Uplink to Syndicate HQ: [message_sent ? "ALREADY USED" : "AVAILABLE (Open Channel)"]" + if(depotarea.on_peaceful) + menu += "

Visiting Agents: VISIT IN PROGRESS. " + if(depotarea.list_includes(user, depotarea.peaceful_list)) + menu += "[user] IS RECOGNIZED AS VISITING AGENT" + else + menu += "[user] NOT RECOGNIZED. (Sign-in as Agent)" + if(check_rights(R_ADMIN, 0, user)) + menu += "

ADMIN: (End Visitor Mode)" + + else + menu += "

Visiting Agents: NONE (Sign-in as Agent)" + return menu + +/obj/machinery/computer/syndicate_depot/syndiecomms/primary(mob/user) + if(..()) + return + if(!isliving(user)) + to_chat(user, "ERROR: No lifesigns detected at terminal, aborting.") // Safety to prevent aghosts accidentally pressing it and getting everyone killed. + return + if(message_sent) + playsound(user, 'sound/machines/buzz-sigh.ogg', 50, 0) + to_chat(user, "[src] has already been used to transmit a message to the Syndicate.") + return + message_sent = TRUE + if(user.mind && user.mind.special_role == SPECIAL_ROLE_TRAITOR) + var/input = stripped_input(user, "Please choose a message to transmit to Syndicate HQ via quantum entanglement. Transmission does not guarantee a response. This function may only be used ONCE.", "To abort, send an empty message.", "") as text|null + if(!input) + message_sent = FALSE + return + Syndicate_announce(input, user) + to_chat(user, "Message transmitted.") + log_say("[key_name(user)] has sent a Syndicate comms message from the depot: [input]", user) + else + to_chat(user, "[src] requires authentication with syndicate codewords, which you do not know.") + raise_alert("Detected unauthorized access by [user] to [src]!") + updateUsrDialog() + +/obj/machinery/computer/syndicate_depot/syndiecomms/secondary(mob/user, subcommand) + if(..()) + return + if(has_security_lockout(user)) + return + if(depotarea) + if(depotarea.local_alarm || depotarea.called_backup || depotarea.used_self_destruct) + to_chat(user, "Visitor sign-in is not possible while the depot is on security alert.") + else if(depotarea.on_peaceful) + if(subcommand == DEPOT_VISITOR_END) + if(check_rights(R_ADMIN, 0, user)) + depotarea.peaceful_mode(FALSE, TRUE) + else if (subcommand == DEPOT_VISITOR_ADD) + if(user.mind && user.mind.special_role == SPECIAL_ROLE_TRAITOR) + if(depotarea.list_includes(user, depotarea.peaceful_list)) + to_chat(user, "[user] is already signed in as a visiting agent.") + else + grant_syndie_faction(user) + else + to_chat(user, "Only verified agents of the Syndicate may sign in as visitors. Everyone else will be shot on sight.") + else if(subcommand == DEPOT_VISITOR_START) + if(depotarea.something_looted) + to_chat(user, "Visitor sign-in is not possible after supplies have been taken from the depot.") + else if(user.mind && user.mind.special_role == SPECIAL_ROLE_TRAITOR) + grant_syndie_faction(user) + depotarea.peaceful_mode(TRUE, TRUE) + else + to_chat(user, "Only verified agents of the Syndicate may sign in as visitors. Everyone else will be shot on sight.") + else + to_chat(user, "Unrecognized subcommand: [subcommand]") + else + to_chat(user, "ERROR: [src] is unable to uplink to depot network.") + updateUsrDialog() + +/obj/machinery/computer/syndicate_depot/syndiecomms/proc/grant_syndie_faction(mob/user) + user.faction += "syndicate" + depotarea.list_add(user, depotarea.peaceful_list) + to_chat(user, {"
Welcome, Agent. + You are now signed-in as a depot visitor. + Any other agents with you MUST sign in themselves. + You may explore all rooms here, except for bolted ones. + Your agent ID will give you access to most doors and computers. + Standard Syndicate regulations apply to your visit. + This means if ANY of you attack facility staff, break into anything, sabotage the facility, or bring non-agents here, then ALL of you will be summarily executed. + Enjoy your stay. + "}) + +/obj/machinery/computer/syndicate_depot/syndiecomms/power_change() + . = ..() + if(!security_lockout && (stat & NOPOWER)) + security_lockout = TRUE + raise_alert("[src] lost power.") + + +// Syndicate teleporter control, used to manage incoming/outgoing teleports + +/obj/machinery/computer/syndicate_depot/teleporter + name = "syndicate teleporter console" + icon_screen = "telesci" + icon_keyboard = "teleport_key" + var/obj/machinery/bluespace_beacon/syndicate/mybeacon + var/obj/effect/portal/myportal + var/portal_enabled = FALSE + var/portaldir = WEST + +/obj/machinery/computer/syndicate_depot/teleporter/New() + . = ..() + spawn(10) + findbeacon() + choosetarget() + update_portal() + +/obj/machinery/computer/syndicate_depot/teleporter/Destroy() + if(mybeacon) + mybeacon.mycomputer = null + return ..() + +/obj/machinery/computer/syndicate_depot/teleporter/portal_destroyed(obj/effect/portal/P) + myportal = null + +/obj/machinery/computer/syndicate_depot/teleporter/disable_special_functions() + if(mybeacon) + if(mybeacon.enabled) + mybeacon.toggle() + if(portal_enabled) + portal_enabled = FALSE + update_portal() + +/obj/machinery/computer/syndicate_depot/teleporter/proc/findbeacon() + if(mybeacon) + return TRUE + for(var/obj/machinery/bluespace_beacon/syndicate/B in myArea) + mybeacon = B + B.mycomputer = src + return TRUE + return FALSE + +/obj/machinery/computer/syndicate_depot/teleporter/proc/choosetarget() + var/list/eligible_turfs = list() + for(var/obj/item/radio/beacon/R in beacons) + var/turf/T = get_turf(R) + if(!is_station_level(T.z)) + continue + eligible_turfs += T + if(eligible_turfs.len) + return pick(eligible_turfs) + else + return FALSE + +/obj/machinery/computer/syndicate_depot/teleporter/proc/update_portal() + if(portal_enabled && !myportal) + var/turf/tele_target = choosetarget() + if(!tele_target) + return + var/turf/portal_turf = get_step(src, portaldir) + var/obj/effect/portal/P = new(portal_turf, tele_target, src, 0) + myportal = P + P.failchance = 0 + P.icon_state = "portal1" + var/area/A = get_area(tele_target) + P.name = "[A] portal" + else if(!portal_enabled && myportal) + qdel(myportal) + myportal = null + +/obj/machinery/computer/syndicate_depot/teleporter/get_menu(mob/user) + var/menutext = "Syndicate Teleporter Control
" + findbeacon() + if(mybeacon) + menutext += {"

Incoming Teleport Beacon: [mybeacon.enabled ? "ON" : "OFF"] ([mybeacon.enabled ? "Disable" : "Enable"])
"} + else + menutext += {"

Incoming Teleport Beacon: Reconnecting to beacon..."} + menutext += {"

Outgoing Teleport Portal: [portal_enabled ? "ON" : "OFF"]"} + if(check_rights(R_ADMIN, 0, user) || (depotarea.on_peaceful && !portal_enabled)) + menutext += {" ([portal_enabled ? "Disable" : "Enable"])
"} + return menutext + +/obj/machinery/computer/syndicate_depot/teleporter/primary(mob/user) + if(..()) + return + if(!mybeacon && user) + to_chat(user, "Unable to connect to teleport beacon.") + return + var/bresult = mybeacon.toggle() + to_chat(user, "Syndicate Teleporter Beacon: [bresult ? "ON" : "OFF"]") + updateUsrDialog() + +/obj/machinery/computer/syndicate_depot/teleporter/secondary(mob/user) + if(..()) + return + if(!check_rights(R_ADMIN, 0, user) && !(depotarea.on_peaceful && !portal_enabled)) + return + if(!portal_enabled && myportal) + to_chat(user, "Outgoing Teleport Portal: deactivating... please wait...") + return + toggle_portal() + to_chat(user, "Outgoing Teleport Portal: [portal_enabled ? "ON" : "OFF"]") + updateUsrDialog() + +/obj/machinery/computer/syndicate_depot/teleporter/proc/toggle_portal() + portal_enabled = !portal_enabled + update_portal() + + +/obj/machinery/computer/syndicate_depot/aiterminal + name = "syndicate ai terminal" + icon_screen = "command" + req_access = list() + +/obj/machinery/computer/syndicate_depot/aiterminal/get_menu(mob/user) + var/menutext = "Syndicate AI Terminal

" + if(!istype(depotarea)) + menutext += "
ERROR: Unable to connect to AI network." + return menutext + + if(depotarea.alert_log.len) + menutext += "Event Log:" + else + menutext += "Event Log: EMPTY" + menutext += "

" + + menutext += "Terminated Intruders: " + menutext += depotarea.list_gethtmlmobs(depotarea.dead_list) + menutext += "

" + + menutext += "Extra Security Forces: " + menutext += depotarea.list_gethtmlmobs(depotarea.guard_list) + menutext += "

" + + menutext += "Visiting Agents: " + menutext += depotarea.list_gethtmlmobs(depotarea.peaceful_list) + menutext += "

" + + var/has_bot = FALSE + for(var/mob/living/simple_animal/bot/ed209/syndicate/B in depotarea.list_getmobs(depotarea.guard_list)) + has_bot = TRUE + if(has_bot) + menutext += "

Sentry Bot: (issue recall order)" + else + menutext += "

Sentry Bot: (none present)" + menutext += "

" + + if(check_rights(R_ADMIN, 0, user)) + if(depotarea.on_peaceful) + menutext += "

ADMIN: (To end visitor mode, use comms console.)" + else + menutext += "

ADMIN: (Reset Depot Alert Level)" + + return menutext + +/obj/machinery/computer/syndicate_depot/aiterminal/primary(mob/user) + if(..()) + return + if(!check_rights(R_ADMIN, 0, user)) + return + if(depotarea) + depotarea.reset_alert() + to_chat(user, "Alert level reset.") + +/obj/machinery/computer/syndicate_depot/aiterminal/secondary(mob/user) + if(..()) + return + for(var/mob/living/simple_animal/bot/ed209/syndicate/B in depotarea.list_getmobs(depotarea.guard_list)) + depotarea.list_remove(B, depotarea.guard_list) + new /obj/effect/portal(get_turf(B)) + to_chat(user, "[B] has been recalled.") + qdel(B) + raise_alert("Sentry bot removed via emergency recall.") \ No newline at end of file diff --git a/code/game/machinery/computer/store.dm b/code/game/machinery/computer/store.dm index dcdb4b1134e..bfa2820d9b3 100644 --- a/code/game/machinery/computer/store.dm +++ b/code/game/machinery/computer/store.dm @@ -13,7 +13,6 @@ /obj/machinery/computer/merch/New() ..() - /obj/machinery/computer/merch/attack_ai(mob/user as mob) src.add_hiddenprint(user) return attack_hand(user) @@ -43,43 +42,49 @@ html { color:#999; } +table {background:#303030;border:1px solid #262626;} + +caption {text-align:left;} + +.button { + color:#cfcfcf; + text-decoration:none; + font-weight:bold; + text-align:center; + width:75px; + padding:21px; + box-sizing:border-box; + background:none; + border:none; + display: inline-block; +} +.button:hover {color:#ffffff;} + a { color:#cfcfcf; text-decoration:none; font-weight:bold; } +a:hover {color:#ffffff;} -a:hover { - color:#ffffff; -} -tr { - background:#303030; - border-radius:6px; - margin-bottom:0.5em; - border-bottom:1px solid black; -} -tr:nth-child(even) { - background:#3f3f3f; -} +p {margin:0;} -td.cost { - font-size:20pt; - font-weight:bold; -} +tr.dark {background:#303030;} -td.cost.affordable { - background:green; -} +tr.light {background:#3f3f3f;} -td.cost.toomuch { - background:maroon; -} +td,th {padding:15px;border-bottom:1px solid #262626;} +th.cost {padding:0px;border-left:1px solid #262626;} + +th.cost.affordable {background:green;} + +th.cost.toomuch {background:maroon;} -

Refresh | Balance: $[balance]

+

Refresh | Balance: $[balance]

[command_name()] Merchandise

Doing your job and not getting any recognition at work? Well, welcome to the @@ -87,8 +92,9 @@ td.cost.toomuch { completed your Job Objectives.

Work hard. Get cash. Acquire bragging rights.

-

In Stock:

+
+ @@ -101,8 +107,11 @@ td.cost.toomuch { if(item.cost>balance) cost_class="toomuch" var/itemID=centcomm_store.items.Find(item) + var/row_color="light" + if(itemID%2 == 0) + row_color="dark" dat += {" - + @@ -110,9 +119,9 @@ td.cost.toomuch {

[item.name]

[item.desc]

- + "} dat += {" @@ -120,7 +129,7 @@ td.cost.toomuch {
In Stock:
# Name/Description
[itemID] - $[item.cost] - + $[item.cost] +
"} - user << browse(dat, "window=merch") + user << browse(dat, "window=merch;size=440x600;can_resize=0") onclose(user, "merch") return @@ -142,6 +151,6 @@ td.cost.toomuch { if(!centcomm_store.PlaceOrder(usr,itemID)) to_chat(usr, "Unable to charge your account.") else - to_chat(usr, "You've successfully purchased the item. It should be in your hands or on the floor.") + to_chat(usr, "You've successfully purchased the item. It should be in your hands or on the floor.") src.updateUsrDialog() return diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 80db23c59f7..332dc2854e1 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -112,7 +112,7 @@ to_chat(user, "\The [I] is no longer in storage.") return - visible_message("The console beeps happily as it disgorges \the [I].") + visible_message("The console beeps happily as it disgorges [I].") dispense_item(I) @@ -120,7 +120,8 @@ if(!allowed(user)) to_chat(user, "Access Denied.") return - if(!allow_items) return + if(!allow_items) + return if(frozen_items.len == 0) to_chat(user, "There is nothing to recover from storage.") @@ -238,7 +239,7 @@ ) // These items will NOT be preserved var/list/do_not_preserve_items = list ( - /obj/item/mmi/posibrain + /obj/item/mmi/robotic_brain ) /obj/machinery/cryopod/right @@ -323,15 +324,15 @@ // Also make sure there is a valid control computer /obj/machinery/cryopod/proc/despawn_occupant() //Drop all items into the pod. - for(var/obj/item/W in occupant) - occupant.unEquip(W) - W.forceMove(src) + for(var/obj/item/I in occupant) + occupant.unEquip(I) + I.forceMove(src) - if(W.contents.len) //Make sure we catch anything not handled by qdel() on the items. - if(should_preserve_item(W) != CRYO_DESTROY) // Don't remove the contents of things that need preservation + if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items. + if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation continue - for(var/obj/item/O in W.contents) - if(istype(O,/obj/item/tank)) //Stop eating pockets, you fuck! + for(var/obj/item/O in I.contents) + if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck! continue O.forceMove(src) @@ -345,23 +346,23 @@ items -= occupant // Don't delete the occupant items -= announce // or the autosay radio. - for(var/obj/item/W in items) - if(istype(W,/obj/item/pda)) - var/obj/item/pda/P = W + for(var/obj/item/I in items) + if(istype(I, /obj/item/pda)) + var/obj/item/pda/P = I QDEL_NULL(P.id) qdel(P) continue - var/preserve = should_preserve_item(W) + var/preserve = should_preserve_item(I) if(preserve == CRYO_DESTROY) - qdel(W) + qdel(I) else if(control_computer && control_computer.allow_items) - control_computer.frozen_items += W + control_computer.frozen_items += I if(preserve == CRYO_OBJECTIVE) - control_computer.objective_items += W - W.loc = null + control_computer.objective_items += I + I.loc = null else - W.forceMove(loc) + I.forceMove(loc) // Skip past any cult sacrifice objective using this person if(GAMEMODE_IS_CULT && is_sacrifice_target(occupant.mind)) @@ -461,22 +462,23 @@ #undef CRYO_PRESERVE #undef CRYO_OBJECTIVE -/obj/machinery/cryopod/attackby(var/obj/item/G as obj, var/mob/user as mob, params) +/obj/machinery/cryopod/attackby(obj/item/I, mob/user, params) - if(istype(G, /obj/item/grab)) + if(istype(I, /obj/item/grab)) + var/obj/item/grab/G = I if(occupant) - to_chat(user, "\The [src] is in use.") + to_chat(user, "[src] is in use.") return - if(!ismob(G:affecting)) + if(!ismob(G.affecting)) return - if(!check_occupant_allowed(G:affecting)) + if(!check_occupant_allowed(G.affecting)) return var/willing = null //We don't want to allow people to be forced into despawning. - var/mob/living/M = G:affecting + var/mob/living/M = G.affecting time_till_despawn = initial(time_till_despawn) if(!istype(M) || M.stat == DEAD) @@ -485,20 +487,21 @@ if(M.client) if(alert(M,"Would you like to enter long-term storage?",,"Yes","No") == "Yes") - if(!M || !G || !G:affecting) return + if(!M || !G || !G.affecting) return willing = willing_time_divisor else willing = 1 if(willing) - visible_message("[user] starts putting [G:affecting:name] into \the [src].") + visible_message("[user] starts putting [G.affecting.name] into [src].") - if(do_after(user, 20, target = G:affecting)) - if(!M || !G || !G:affecting) return + if(do_after(user, 20, target = G.affecting)) + if(!M || !G || !G.affecting) + return if(occupant) - to_chat(user, "\The [src] is in use.") + to_chat(user, "[src] is in use.") return take_occupant(M, willing) @@ -516,6 +519,8 @@ to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") take_occupant(M, willing) + else + return ..() /obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) @@ -567,7 +572,7 @@ if(willing) if(!Adjacent(L)) - to_chat(user, "You're not close enough to \the [src].") + to_chat(user, "You're not close enough to [src].") return if(L == user) visible_message("[user] starts climbing into the cryo pod.") @@ -633,14 +638,13 @@ if(occupant) items -= occupant if(announce) items -= announce - for(var/obj/item/W in items) - W.loc = get_turf(src) + for(var/obj/item/I in items) + I.forceMove(get_turf(src)) go_out() add_fingerprint(usr) name = initial(name) - return /obj/machinery/cryopod/verb/move_inside() set name = "Enter Pod" @@ -659,7 +663,7 @@ to_chat(usr, "You're too busy getting your life sucked out of you.") return - visible_message("[usr] starts climbing into \the [src].") + visible_message("[usr] starts climbing into [src].") if(do_after(usr, 20, target = usr)) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0d49cc1b0cd..4de934f1c96 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -796,7 +796,7 @@ About the new airlock wires panel: if(do_after(user, 20, 1, target = src)) if(!panel_open || !S.use(2)) return - user.visible_message("[user] reinforce \the [src] with metal.", + user.visible_message("[user] reinforces \the [src] with metal.", "You reinforce \the [src] with metal.") security_level = AIRLOCK_SECURITY_METAL update_icon() @@ -810,7 +810,7 @@ About the new airlock wires panel: if(do_after(user, 20, 1, target = src)) if(!panel_open || !S.use(2)) return - user.visible_message("[user] reinforce \the [src] with plasteel.", + user.visible_message("[user] reinforces \the [src] with plasteel.", "You reinforce \the [src] with plasteel.") security_level = AIRLOCK_SECURITY_PLASTEEL modify_max_integrity(normal_integrity * AIRLOCK_INTEGRITY_MULTIPLIER) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 8f5c1144686..cc316cd3d02 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -329,6 +329,20 @@ note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_hatch +/obj/machinery/door/airlock/hatch/syndicate + name = "syndicate hatch" + req_access_txt = "150" + +/obj/machinery/door/airlock/hatch/syndicate/vault + name = "syndicate vault hatch" + req_access_txt = "151" + icon = 'icons/obj/doors/airlocks/vault/vault.dmi' + overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi' + assemblytype = /obj/structure/door_assembly/door_assembly_vault + security_level = 6 + hackProof = TRUE + aiControlDisabled = TRUE + /obj/machinery/door/airlock/hatch/gamma name = "gamma level hatch" hackProof = 1 diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index f8d7432c540..f06f7ac1b37 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -8,6 +8,20 @@ var/list/doppler_arrays = list() density = 1 anchored = 1 atom_say_verb = "states coldly" + var/list/logged_explosions = list() + +/datum/explosion_log + var/logged_time + var/epicenter + var/actual_size_message + var/theoretical_size_message + +/datum/explosion_log/New(var/log_time, var/log_epicenter, var/log_actual_size_message, var/log_theoretical_size_message) + ..() + logged_time = log_time + epicenter = log_epicenter + actual_size_message = log_actual_size_message + theoretical_size_message = log_theoretical_size_message /obj/machinery/doppler_array/New() ..() @@ -15,70 +29,122 @@ var/list/doppler_arrays = list() /obj/machinery/doppler_array/Destroy() doppler_arrays -= src + logged_explosions.Cut() return ..() /obj/machinery/doppler_array/process() return PROCESS_KILL -/obj/machinery/doppler_array/attackby(var/obj/item/O, var/mob/user, params) - if(istype(O, /obj/item/wrench)) +/obj/machinery/doppler_array/attackby(obj/item/I, mob/user, params) + if(iswrench(I)) if(!anchored && !isinspace()) - anchored = 1 + anchored = TRUE power_change() to_chat(user, "You fasten [src].") else if(anchored) - anchored = 0 + anchored = FALSE power_change() to_chat(user, "You unfasten [src].") - playsound(loc, O.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) + else + return ..() -/obj/machinery/doppler_array/verb/rotate() +/obj/machinery/doppler_array/attack_hand(mob/user) + if(..()) + return + add_fingerprint(user) + ui_interact(user) + +/obj/machinery/doppler_array/attack_ghost(mob/user) + ui_interact(user) + +/obj/machinery/doppler_array/AltClick(mob/user) + rotate(user) + +/obj/machinery/doppler_array/verb/rotate(mob/user) set name = "Rotate Tachyon-doppler Dish" set category = "Object" set src in oview(1) - if(!usr || !isturf(usr.loc)) + if(user.incapacitated()) return - if(usr.stat || usr.restrained() || !usr.canmove) + if(!Adjacent(user)) return - src.dir = turn(src.dir, 90) - return + if(!user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do that!") + return + dir = turn(dir, 90) + to_chat(user, "You rotate [src].") + +/obj/machinery/doppler_array/proc/print_explosive_logs(mob/user) + if(!logged_explosions.len) + atom_say("No logs currently stored in internal database.") + return + if(active_timers) + to_chat(user, "[src] is already printing something, please wait.") + return + atom_say("Printing explosive log. Standby...") + addtimer(CALLBACK(src, .print), 50) + +/obj/machinery/doppler_array/proc/print() + visible_message("[src] prints a piece of paper!") + playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + var/obj/item/paper/explosive_log/P = new(get_turf(src)) + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + P.info += "\ + [E.logged_time]\ + [E.epicenter]\ + [E.actual_size_message]\ + [E.theoretical_size_message]\ + " + P.info += "
\ + Printed at [station_time_timestamp()]." /obj/machinery/doppler_array/proc/sense_explosion(var/x0,var/y0,var/z0,var/devastation_range,var/heavy_impact_range,var/light_impact_range, var/took,var/orig_dev_range,var/orig_heavy_range,var/orig_light_range) - if(stat & NOPOWER) return - if(z != z0) return + if(stat & NOPOWER) + return + if(z != z0) + return var/dx = abs(x0-x) var/dy = abs(y0-y) var/distance var/direct + var/capped = FALSE if(dx > dy) distance = dx - if(x0 > x) direct = EAST - else direct = WEST + if(x0 > x) + direct = EAST + else + direct = WEST else distance = dy - if(y0 > y) direct = NORTH - else direct = SOUTH - - if(distance > 100) return - if(!(direct & dir)) return + if(y0 > y) + direct = NORTH + else + direct = SOUTH + if(distance > 100) + return + if(!(direct & dir)) + return var/list/messages = list("Explosive disturbance detected.", \ "Epicenter at: grid ([x0],[y0]). Temporal displacement of tachyons: [took] seconds.", \ "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") - // If the bomb was capped, say it's theoretical size. + // If the bomb was capped, say its theoretical size. if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) + capped = TRUE messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." - + logged_explosions.Insert(1, new /datum/explosion_log(station_time_timestamp(), "[x0],[y0]", "[devastation_range], [heavy_impact_range], [light_impact_range]", capped ? "[orig_dev_range], [orig_heavy_range], [orig_light_range]" : "n/a")) //Newer logs appear first + messages += "Event successfully logged in internal database." for(var/message in messages) atom_say(message) - /obj/machinery/doppler_array/power_change() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" @@ -88,4 +154,55 @@ var/list/doppler_arrays = list() stat &= ~NOPOWER else icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER \ No newline at end of file + stat |= NOPOWER + +/obj/machinery/doppler_array/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "doppler_array.tmpl", "Tachyon-doppler array", 500, 650) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/doppler_array/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state) + var/data[0] + var/list/explosion_data = list() + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + explosion_data += list(list( + "logged_time" = E.logged_time, + "epicenter" = E.epicenter, + "actual_size_message" = E.actual_size_message, + "theoretical_size_message" = E.theoretical_size_message, + "unique_datum_id" = E.UID())) + data["explosion_data"] = explosion_data + data["printing"] = active_timers + return data + +/obj/machinery/doppler_array/Topic(href, href_list) + if(..()) + return + if(href_list["log_to_delete"]) + var/log_to_delete = sanitize(href_list["log_to_delete"]) + for(var/D in logged_explosions) + var/datum/explosion_log/E = D + if(E.UID() == log_to_delete) + logged_explosions -= E + qdel(E) + to_chat(usr, "Log deletion successful.") + break + else if(href_list["print_logs"]) + print_explosive_logs(usr) + else + return + SSnanoui.update_uis(src) + +/obj/item/paper/explosive_log + name = "explosive log" + info = "

Explosive Log Report

\ + \ + \ + \ + \ + \ + \ + " //NB: the
Time loggedEpicenterActualTheoretical
tag is left open, it is closed later on, when the doppler array adds its data diff --git a/code/game/machinery/dye_generator.dm b/code/game/machinery/dye_generator.dm index bb47a4939ec..52b11da599b 100644 --- a/code/game/machinery/dye_generator.dm +++ b/code/game/machinery/dye_generator.dm @@ -41,7 +41,7 @@ stat |= BROKEN icon_state = "[initial(icon_state)]-broken" -/obj/machinery/dye_generator/attack_hand(mob/user as mob) +/obj/machinery/dye_generator/attack_hand(mob/user) ..() src.add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) @@ -50,18 +50,18 @@ dye_color = temp set_light(2, l_color = temp) -/obj/machinery/dye_generator/attackby(obj/item/W, mob/user, params) +/obj/machinery/dye_generator/attackby(obj/item/I, mob/user, params) - if(default_unfasten_wrench(user, W, time = 60)) + if(default_unfasten_wrench(user, I, time = 60)) return - if(istype(W, /obj/item/hair_dye_bottle)) - user.visible_message("[user] fills the [W] up with some dye.","You fill the [W] up with some hair dye.") - var/obj/item/hair_dye_bottle/HD = W + if(istype(I, /obj/item/hair_dye_bottle)) + var/obj/item/hair_dye_bottle/HD = I + user.visible_message("[user] fills the [HD] up with some dye.","You fill the [HD] up with some hair dye.") HD.dye_color = dye_color HD.update_dye_overlay() else - ..() + return ..() //Hair Dye Bottle @@ -87,7 +87,7 @@ I.color = dye_color overlays += I -/obj/item/hair_dye_bottle/attack(mob/living/carbon/M as mob, mob/user as mob) +/obj/item/hair_dye_bottle/attack(mob/living/carbon/M, mob/user) if(user.a_intent != INTENT_HELP) ..() return @@ -98,11 +98,11 @@ var/mob/living/carbon/human/H = M var/dye_list = list("hair", "alt. hair theme") - if(H.gender == MALE || H.get_species() == "Vulpkanin") + if(H.gender == MALE || isvulpkanin(H)) dye_list += "facial hair" dye_list += "alt. facial hair theme" - if(H && (H.species.bodyflags & HAS_SKIN_COLOR)) + if(H && (H.dna.species.bodyflags & HAS_SKIN_COLOR)) dye_list += "body" var/what_to_dye = input(user, "Choose an area to apply the dye", "Dye Application") in dye_list diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 8cb98021576..b3664c58cd6 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -45,7 +45,7 @@ FIRE ALARM /obj/machinery/firealarm/emag_act(mob/user) if(!emagged) - emagged = 1 + emagged = TRUE if(user) user.visible_message("Sparks fly out of the [src]!", "You emag [src], disabling its thermal sensors.") @@ -62,19 +62,15 @@ FIRE ALARM /obj/machinery/firealarm/attack_ghost(mob/user) ui_interact(user) -/obj/machinery/firealarm/bullet_act(BLAH) - return alarm() - - /obj/machinery/firealarm/emp_act(severity) if(prob(50/severity)) alarm(rand(30/severity, 60/severity)) ..() -/obj/machinery/firealarm/attackby(obj/item/W, mob/user, params) +/obj/machinery/firealarm/attackby(obj/item/I, mob/user, params) add_fingerprint(user) - if(istype(W, /obj/item/screwdriver) && buildstage == 2) + if(iswirecutter(I) && buildstage == 2) wiresexposed = !wiresexposed update_icon() return @@ -82,37 +78,37 @@ FIRE ALARM if(wiresexposed) switch(buildstage) if(2) - if(istype(W, /obj/item/multitool)) + if(ismultitool(I)) detecting = !detecting if(detecting) user.visible_message("[user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.") else user.visible_message("[user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.") - else if(istype(W, /obj/item/wirecutters)) // cutting the wires out + else if(iswirecutter(I)) // cutting the wires out to_chat(user, "You cut the wires!") - playsound(loc, W.usesound, 50, 1) + playsound(loc, I.usesound, 50, 1) var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil() new_coil.amount = 5 - new_coil.loc = user.loc + new_coil.forceMove(user.loc) buildstage = 1 update_icon() if(1) - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = W + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/coil = I if(!coil.use(5)) to_chat(user, "You cut the wires!") return buildstage = 2 - playsound(get_turf(src), W.usesound, 50, 1) - to_chat(user, "You wire \the [src]!") + playsound(get_turf(src), I.usesound, 50, 1) + to_chat(user, "You wire [src]!") update_icon() - else if(istype(W, /obj/item/crowbar)) + else if(iscrowbar(I)) to_chat(user, "You pry out the circuit!") - playsound(get_turf(src), W.usesound, 50, 1) - if(do_after(user, 20 * W.toolspeed, target = src)) + playsound(get_turf(src), I.usesound, 50, 1) + if(do_after(user, 20 * I.toolspeed, target = src)) if(buildstage != 1) return var/obj/item/firealarm_electronics/circuit = new /obj/item/firealarm_electronics() @@ -120,20 +116,20 @@ FIRE ALARM buildstage = 0 update_icon() if(0) - if(istype(W, /obj/item/firealarm_electronics)) + if(istype(I, /obj/item/firealarm_electronics)) to_chat(user, "You insert the circuit!") - qdel(W) + qdel(I) buildstage = 1 update_icon() - else if(istype(W, /obj/item/wrench)) + else if(iswrench(I)) to_chat(user, "You remove the fire alarm assembly from the wall!") new /obj/item/mounted/frame/firealarm(get_turf(user)) - playsound(get_turf(src), W.usesound, 50, 1) + playsound(get_turf(src), I.usesound, 50, 1) qdel(src) - return - alarm() + else + return ..() /obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 2b0691d5801..7a13b0bf796 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -38,14 +38,16 @@ // sd_set_light(0) //Don't want to render prison breaks impossible -/obj/machinery/flasher/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wirecutters)) +/obj/machinery/flasher/attackby(obj/item/I, mob/user, params) + if(iswirecutter(I)) add_fingerprint(user) disable = !disable if(disable) - user.visible_message("[user] has disconnected the [src]'s flashbulb!", "You disconnect the [src]'s flashbulb!") + user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb!") if(!disable) - user.visible_message("[user] has connected the [src]'s flashbulb!", "You connect the [src]'s flashbulb!") + user.visible_message("[user] has connected [src]'s flashbulb!", "You connect [src]'s flashbulb!") + else + return ..() //Let the AI trigger them directly. /obj/machinery/flasher/attack_ai(mob/user) @@ -95,8 +97,8 @@ if((M.m_intent != MOVE_INTENT_WALK) && (anchored)) flash() -/obj/machinery/flasher/portable/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/wrench)) +/obj/machinery/flasher/portable/attackby(obj/item/I, mob/user, params) + if(iswrench(I)) add_fingerprint(user) anchored = !anchored @@ -107,6 +109,8 @@ else if(anchored) user.show_message(text("[src] is now secured.")) overlays += "[base_state]-s" + else + return ..() // Flasher button /obj/machinery/flasher_button diff --git a/code/game/machinery/gameboard.dm b/code/game/machinery/gameboard.dm index f1bd8b65a10..526a935cf90 100644 --- a/code/game/machinery/gameboard.dm +++ b/code/game/machinery/gameboard.dm @@ -93,8 +93,11 @@ if(href_list["close"]) close_game() -/obj/machinery/gameboard/attackby(var/obj/item/G as obj, var/mob/user as mob, params) - if(istype(G, /obj/item/wrench)) - default_unfasten_wrench(user, G) - else if(istype(G, /obj/item/crowbar)) - default_deconstruction_crowbar(G, ignore_panel = 1) +/obj/machinery/gameboard/attackby(obj/item/I, mob/user, params) + if(default_unfasten_wrench(user, I)) + return + + if(default_deconstruction_crowbar(I, ignore_panel = TRUE)) + return + else + return ..() \ No newline at end of file diff --git a/code/game/machinery/guestpass.dm b/code/game/machinery/guestpass.dm index 6d90de7bf4d..450260f5f79 100644 --- a/code/game/machinery/guestpass.dm +++ b/code/game/machinery/guestpass.dm @@ -48,20 +48,22 @@ var/list/internal_log = list() var/mode = 0 // 0 - making pass, 1 - viewing logs -/obj/machinery/computer/guestpass/attackby(obj/O, mob/user, params) - if(istype(O, /obj/item/card/id)) +/obj/machinery/computer/guestpass/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/card/id)) if(!giver) - user.drop_item() - O.loc = src - giver = O - updateUsrDialog() + if(user.drop_item()) + I.forceMove(src) + giver = I + updateUsrDialog() else to_chat(user, "There is already ID card inside.") + else + return ..() /obj/machinery/computer/guestpass/proc/get_changeable_accesses() return giver.access -/obj/machinery/computer/guestpass/attack_ai(var/mob/user as mob) +/obj/machinery/computer/guestpass/attack_ai(mob/user) return attack_hand(user) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 0fc532ab0e4..bda66a55622 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -91,17 +91,20 @@ var/list/holopads = list() holograph_range += 1 * B.rating holo_range = holograph_range -/obj/machinery/hologram/holopad/attackby(obj/item/P as obj, mob/user as mob, params) - if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) +/obj/machinery/hologram/holopad/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", I)) return - if(exchange_parts(user, P)) + if(exchange_parts(user, I)) return - if(default_unfasten_wrench(user, P)) + if(default_unfasten_wrench(user, I)) return - default_deconstruction_crowbar(P) + if(default_deconstruction_crowbar(I)) + return + else + return ..() /obj/machinery/hologram/holopad/attack_hand(mob/living/carbon/human/user) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 411543b662f..22d1177c437 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -68,21 +68,23 @@ icon_state = "[base_state]-p" // src.sd_set_light(0) -/obj/machinery/sparker/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/detective_scanner)) +/obj/machinery/sparker/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/detective_scanner)) return - if(istype(W, /obj/item/screwdriver)) + if(isscrewdriver(I)) add_fingerprint(user) - src.disable = !src.disable - if(src.disable) - user.visible_message("[user] has disabled the [src]!", "You disable the connection to the [src].") + disable = !disable + if(disable) + user.visible_message("[user] has disabled [src]!", "You disable the connection to [src].") icon_state = "[base_state]-d" - if(!src.disable) - user.visible_message("[user] has reconnected the [src]!", "You fix the connection to the [src].") - if(src.powered()) + if(!disable) + user.visible_message("[user] has reconnected [src]!", "You fix the connection to [src].") + if(powered()) icon_state = "[base_state]" else icon_state = "[base_state]-p" + else + return ..() /obj/machinery/sparker/attack_ai() if(src.anchored) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index d7a4a3e2b04..4ccaa246578 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -88,17 +88,17 @@ to_chat(usr, "There's nothing attached to the IV drip!") -/obj/machinery/iv_drip/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/reagent_containers)) +/obj/machinery/iv_drip/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers)) if(beaker) to_chat(user, "There is already a reagent container loaded!") return if(!user.drop_item()) return - W.forceMove(src) - beaker = W - to_chat(user, "You attach [W] to [src].") + I.forceMove(src) + beaker = I + to_chat(user, "You attach [I] to [src].") update_icon() else return ..() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index a29dcb9e274..aef8de7c306 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -117,7 +117,6 @@ Class Procs: var/use_log = list() var/list/settagwhitelist = list()//WHITELIST OF VARIABLES THAT THE set_tag HREF CAN MODIFY, DON'T PUT SHIT YOU DON'T NEED ON HERE, AND IF YOU'RE GONNA USE set_tag (format_tag() proc), ADD TO THIS LIST. atom_say_verb = "beeps" - var/speed_process = 0 // Process as fast as possible? var/defer_process = 0 /obj/machinery/Initialize() @@ -138,7 +137,7 @@ Class Procs: isprocessing = TRUE // all of these isprocessing = TRUE can be removed when the PS is dead // gotta go fast -/obj/machinery/proc/makeSpeedProcess() +/obj/machinery/makeSpeedProcess() if(speed_process) return speed_process = 1 @@ -147,7 +146,7 @@ Class Procs: isprocessing = TRUE // gotta go slow -/obj/machinery/proc/makeNormalProcess() +/obj/machinery/makeNormalProcess() if(!speed_process) return speed_process = 0 @@ -562,7 +561,7 @@ Class Procs: if(istype(perp.belt, /obj/item/gun) || istype(perp.belt, /obj/item/melee)) threatcount += 2 - if(perp.species.name != "Human") //beepsky so racist. + if(!ishumanbasic(perp)) //beepsky so racist. threatcount += 2 if(check_records || check_arrest) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index ee4f2e6eb62..378ebce8eb7 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -72,7 +72,7 @@ // called when turf state changes // hide the object if turf is intact /obj/machinery/navbeacon/hide(intact) - invisibility = intact ? 101 : 0 + invisibility = intact ? INVISIBILITY_MAXIMUM : SEE_INVISIBLE_MINIMUM updateicon() // update the icon_state @@ -97,17 +97,18 @@ updateicon() - else if(istype(I, /obj/item/card/id)||istype(I, /obj/item/pda)) + else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) if(open) - if(src.allowed(user)) - src.locked = !src.locked - to_chat(user, "Controls are now [src.locked ? "locked" : "unlocked"].") + if(allowed(user)) + locked = !locked + to_chat(user, "Controls are now [locked ? "locked" : "unlocked"].") else to_chat(user, "Access denied.") updateDialog() else to_chat(user, "You must open the cover first!") - return + else + return ..() /obj/machinery/navbeacon/attack_ai(mob/user) interact(user, 1) @@ -213,3 +214,11 @@ Transponder Codes:
+ - + "} @@ -136,8 +143,11 @@ td.cost.toomuch { if(item.cost>tickets) cost_class="toomuch" var/itemID = global_prizes.prizes.Find(item) + var/row_color="light" + if(itemID%2 == 0) + row_color="dark" dat += {" - + @@ -147,10 +157,10 @@ td.cost.toomuch { "} dat += {" - - + + "} dat += {" @@ -158,7 +168,7 @@ td.cost.toomuch {
Available Prizes:
# Name/DescriptionPriceTickets
[itemID] - [item.cost] Tickets -
+ [item.cost] +
"} - user << browse(dat, "window=prize_counter") + user << browse(dat, "window=prize_counter;size=440x600;can_resize=0") onclose(user, "prize_counter") return diff --git a/code/modules/arcade/prize_datums.dm b/code/modules/arcade/prize_datums.dm index bf57195d207..3fa097bb03a 100644 --- a/code/modules/arcade/prize_datums.dm +++ b/code/modules/arcade/prize_datums.dm @@ -34,7 +34,7 @@ var/global/datum/prizes/global_prizes = new var/cost = 0 ////////////////////////////////////// -// Tier 1 Prizes // +// Prizes // ////////////////////////////////////// /datum/prize_item/balloon @@ -43,18 +43,6 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/toy/balloon cost = 10 -/datum/prize_item/crayons - name = "Box of Crayons" - desc = "A six-pack of crayons, just like back in kindergarten." - typepath = /obj/item/storage/fancy/crayons - cost = 35 - -/datum/prize_item/snappops - name = "Snap-Pops" - desc = "A box of exploding snap-pop fireworks." - typepath = /obj/item/storage/box/snappops - cost = 20 - /datum/prize_item/spinningtoy name = "Spinning Toy" desc = "Looks like an authentic Singularity!" @@ -62,46 +50,52 @@ var/global/datum/prizes/global_prizes = new cost = 15 /datum/prize_item/blinktoy - name = "Blink toy" + name = "Blink Toy" desc = "Blink. Blink. Blink." typepath = /obj/item/toy/blink cost = 15 /datum/prize_item/dice - name = "Dice set" + name = "Dice Set" desc = "A set of assorted dice." typepath = /obj/item/storage/box/dice cost = 20 -/datum/prize_item/cards - name = "Deck of cards" - desc = "Anyone fancy a game of 52-card Pickup?" - typepath = /obj/item/toy/cards/deck - cost = 25 - -/datum/prize_item/wallet - name = "Colored Wallet" - desc = "Brightly colored and big enough for standard issue ID cards." - typepath = /obj/item/storage/wallet/color - cost = 50 - -/datum/prize_item/pet_rock - name = "pet rock" - desc = "A pet of your very own!" - typepath = /obj/item/toy/pet_rock - cost = 80 - /datum/prize_item/foam_darts name = "Pack of Foam Darts" desc = "A refill pack with foam darts." typepath = /obj/item/ammo_box/foambox cost = 20 -/datum/prize_item/minigibber - name = "Minigibber Toy" - desc = "A model of the station gibber. Probably shouldn't stick your fingers in it." - typepath = /obj/item/toy/minigibber - cost = 60 +/datum/prize_item/snappops + name = "Snap-Pops" + desc = "A box of exploding snap-pop fireworks." + typepath = /obj/item/storage/box/snappops + cost = 20 + +/datum/prize_item/cards + name = "Deck of Cards" + desc = "Anyone fancy a game of 52-card Pickup?" + typepath = /obj/item/toy/cards/deck + cost = 25 + +/datum/prize_item/crayons + name = "Box of Crayons" + desc = "A six-pack of crayons, just like back in kindergarten." + typepath = /obj/item/storage/fancy/crayons + cost = 35 + +/datum/prize_item/eight_ball + name = "Magic Eight Ball" + desc = "A mystical ball that can divine the future!" + typepath = /obj/item/toy/eight_ball + cost = 40 + +/datum/prize_item/wallet + name = "Colored Wallet" + desc = "Brightly colored and big enough for standard issue ID cards." + typepath = /obj/item/storage/wallet/color + cost = 50 /datum/prize_item/id_sticker name = "Prisoner ID Sticker" @@ -129,11 +123,17 @@ var/global/datum/prizes/global_prizes = new desc = "A sticker that can make any ID look like something suspicious..." typepath = /obj/item/id_decal/emag -/datum/prize_item/carp_plushie - name = "Random Carp Plushie" - desc = "A colorful fish-shaped plush toy." - typepath = /obj/item/toy/prizeball/carp_plushie - cost = 75 +/datum/prize_item/flash + name = "Toy Flash" + desc = "AUGH! MY EYES!" + typepath = /obj/item/toy/flash + cost = 50 + +/datum/prize_item/minimeteor + name = "Mini-Meteor" + desc = "Meteors have been detected on a collision course with your fun times!" + typepath = /obj/item/toy/minimeteor + cost = 50 /datum/prize_item/therapy_doll name = "Random Therapy Doll" @@ -141,12 +141,30 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/toy/prizeball/therapy cost = 60 +/datum/prize_item/minigibber + name = "Minigibber Toy" + desc = "A model of the station gibber. Probably shouldn't stick your fingers in it." + typepath = /obj/item/toy/minigibber + cost = 60 + +/datum/prize_item/confetti + name = "Confetti Grenade" + desc = "Party time!" + typepath = /obj/item/grenade/confetti + cost = 65 + /datum/prize_item/plushie name = "Random Animal Plushie" desc = "A colorful animal-shaped plush toy." typepath = /obj/item/toy/prizeball/plushie cost = 75 +/datum/prize_item/carp_plushie + name = "Random Carp Plushie" + desc = "A colorful fish-shaped plush toy." + typepath = /obj/item/toy/prizeball/carp_plushie + cost = 75 + /datum/prize_item/mech_toy name = "Random Mecha" desc = "A random mecha figure, collect all 11!" @@ -159,42 +177,11 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/toy/prizeball/figure cost = 75 -/datum/prize_item/eight_ball - name = "Magic Eight Ball" - desc = "A mystical ball that can divine the future!" - typepath = /obj/item/toy/eight_ball - cost = 40 - -/datum/prize_item/tacticool - name = "Tacticool Turtleneck" - desc = "A cool-looking turtleneck." - typepath = /obj/item/clothing/under/syndicate/tacticool - cost = 90 - -/datum/prize_item/crossbow - name = "Foam Dart Crossbow" - desc = "A toy crossbow that fires foam darts." - typepath = /obj/item/gun/projectile/shotgun/toy/crossbow - cost = 100 - - -/datum/prize_item/toy_xeno - name = "Xeno Action Figure" - desc = "A lifelike replica of the horrific xeno scourge." - typepath = /obj/item/toy/toy_xeno - cost = 80 - -/datum/prize_item/fakespell - name = "Fake Spellbook" - desc = "Perform magic! Astound your friends! Get mistaken for an enemy of the corporation!" - typepath = /obj/item/spellbook/oneuse/fake_gib - cost = 100 - -/datum/prize_item/nanomob_booster - name = "Nano-Mob Hunter Trading Card Booster Pack" - desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!" - typepath = /obj/item/storage/box/nanomob_booster_pack - cost = 100 +/datum/prize_item/AI + name = "Toy AI Unit" + desc = "Law 1: Maximize fun for crew." + typepath = /obj/item/toy/AI + cost = 75 /datum/prize_item/capgun name = "Capgun Revolver" @@ -202,11 +189,35 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/gun/projectile/revolver/capgun cost = 75 -/datum/prize_item/confetti - name = "Confetti Grenade" - desc = "Party time!" - typepath = /obj/item/grenade/confetti - cost = 65 +/datum/prize_item/pet_rock + name = "Pet Rock" + desc = "A pet of your very own!" + typepath = /obj/item/toy/pet_rock + cost = 80 + +/datum/prize_item/toy_xeno + name = "Xeno Action Figure" + desc = "A lifelike replica of the horrific xeno scourge." + typepath = /obj/item/toy/toy_xeno + cost = 80 + +/datum/prize_item/tacticool + name = "Tacticool Turtleneck" + desc = "A cool-looking turtleneck." + typepath = /obj/item/clothing/under/syndicate/tacticool + cost = 90 + +/datum/prize_item/nanomob_booster + name = "Nano-Mob Hunter Trading Card Booster Pack" + desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!" + typepath = /obj/item/storage/box/nanomob_booster_pack + cost = 100 + +/datum/prize_item/fakespell + name = "Fake Spellbook" + desc = "Perform magic! Astound your friends! Get mistaken for an enemy of the corporation!" + typepath = /obj/item/spellbook/oneuse/fake_gib + cost = 100 /datum/prize_item/magic_conch name = "Magic Conch Shell" @@ -214,30 +225,36 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/toy/eight_ball/conch cost = 100 -/datum/prize_item/flash - name = "Toy Flash" - desc = "AUGH! MY EYES!" - typepath = /obj/item/toy/flash - cost = 50 +/datum/prize_item/crossbow + name = "Foam Dart Crossbow" + desc = "A toy crossbow that fires foam darts." + typepath = /obj/item/gun/projectile/shotgun/toy/crossbow + cost = 100 /datum/prize_item/foamblade - name = "Foam Armblade" + name = "Foam Arm Blade" desc = "Perfect for reenacting space horror holo-vids." typepath = /obj/item/toy/foamblade cost = 100 -/datum/prize_item/minimeteor - name = "Mini-Meteor" - desc = "Meteors have been detected on a collision course with your fun times!" - typepath = /obj/item/toy/minimeteor - cost = 50 - /datum/prize_item/redbutton name = "Shiny Red Button" desc = "PRESS IT!" typepath = /obj/item/toy/redbutton cost = 100 +/datum/prize_item/nuke + name = "Nuclear Fun Device" + desc = "Annihilate boredom with an explosion of excitement!" + typepath = /obj/item/toy/nuke + cost = 100 + +/datum/prize_item/blobhat + name = "Blob Hat" + desc = "There's... something... on your head..." + typepath = /obj/item/clothing/head/blob + cost = 125 + /datum/prize_item/owl name = "Owl Action Figure" desc = "Remember: heroes don't grief!" @@ -250,48 +267,12 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/toy/griffin cost = 125 -/datum/prize_item/AI - name = "Toy AI Unit" - desc = "Law 1: Maximize fun for crew." - typepath = /obj/item/toy/AI - cost = 75 - -/datum/prize_item/tommygun - name = "Tommygun" - desc = "A replica tommygun that fires foam darts." - typepath = /obj/item/gun/projectile/shotgun/toy/tommygun - cost = 175 - /datum/prize_item/esword name = "Toy Energy Sword" desc = "A plastic replica of an energy blade." typepath = /obj/item/toy/sword cost = 150 -/datum/prize_item/blobhat - name = "Blob Hat" - desc = "There's... something... on your head..." - typepath = /obj/item/clothing/head/blob - cost = 125 - -/datum/prize_item/nuke - name = "Nuclear Fun Device" - desc = "Annihilate boredom with an explosion of excitement!" - typepath = /obj/item/toy/nuke - cost = 100 - -/datum/prize_item/chainsaw - name = "Toy Chainsaw" - desc = "A full-scale model chainsaw, based on that massacre in Space Texas." - typepath = /obj/item/twohanded/toy/chainsaw - cost = 200 - -/datum/prize_item/spacesuit - name = "Fake Spacesuit" - desc = "A replica spacesuit. Not actually spaceworthy." - typepath = /obj/item/storage/box/fakesyndiesuit - cost = 180 - /datum/prize_item/fakespace name = "Space Carpet" desc = "A stack of carpeted floor tiles that resemble space." @@ -304,6 +285,24 @@ var/global/datum/prizes/global_prizes = new typepath = /obj/item/stack/tile/arcade_carpet/loaded cost = 150 +/datum/prize_item/tommygun + name = "Tommy Gun" + desc = "A replica tommy gun that fires foam darts." + typepath = /obj/item/gun/projectile/shotgun/toy/tommygun + cost = 175 + +/datum/prize_item/spacesuit + name = "Fake Spacesuit" + desc = "A replica spacesuit. Not actually spaceworthy." + typepath = /obj/item/storage/box/fakesyndiesuit + cost = 180 + +/datum/prize_item/chainsaw + name = "Toy Chainsaw" + desc = "A full-scale model chainsaw, based on that massacre in Space Texas." + typepath = /obj/item/twohanded/toy/chainsaw + cost = 200 + /datum/prize_item/bike name = "Awesome Bike!" desc = "WOAH." diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 94e0ea2acce..627cde823fa 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -37,7 +37,7 @@ createCorpse() /obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it. - var/mob/living/carbon/human/human/M = new /mob/living/carbon/human/human (src.loc) + var/mob/living/carbon/human/M = new /mob/living/carbon/human(src.loc) M.real_name = src.name M.death(1) //Kills the new mob M.adjustOxyLoss(oxy_damage) @@ -293,6 +293,6 @@ /obj/effect/landmark/corpse/abductor //Connected to ruins, for some reason? name = "abductor" mobname = "???" - mob_species = "abductor" + mob_species = /datum/species/abductor corpseuniform = /obj/item/clothing/under/color/grey corpseshoes = /obj/item/clothing/shoes/combat diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm index 7618996fdf9..77954eafb9f 100644 --- a/code/modules/awaymissions/map_rng.dm +++ b/code/modules/awaymissions/map_rng.dm @@ -20,7 +20,7 @@ template = map_templates[template_name] /obj/effect/landmark/map_loader/Initialize() - ..() + . = ..() if(template) load(template) diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index 5ff625544fd..816007d4ff8 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -57,8 +57,6 @@ var/global/dmm_suite/preloader/_preloader = new var/list/grid_models = list() var/key_len = 0 - - var/dmm_suite/loaded_map/LM = new // This try-catch is used as a budget "Finally" clause, as the dirt count // needs to be reset @@ -128,7 +126,6 @@ var/global/dmm_suite/preloader/_preloader = new bounds[MAP_MAXY] = max(bounds[MAP_MAXY], min(ycrd, world.maxy)) var/maxx = xcrdStart - log_debug("[xcrdStart]") if(measureOnly) for(var/line in gridLines) maxx = max(maxx, xcrdStart + length(line) / key_len - 1) diff --git a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm b/code/modules/awaymissions/mission_code/spacehotel_npcs.dm index dcf4a48a280..2a524ab738c 100644 --- a/code/modules/awaymissions/mission_code/spacehotel_npcs.dm +++ b/code/modules/awaymissions/mission_code/spacehotel_npcs.dm @@ -3,8 +3,8 @@ override_under = /obj/item/clothing/under/mafia chattyness = SNPC_CHANCE_TALK / 4 -/mob/living/carbon/human/interactive/away/hotel/New(loc) - ..(loc, "Skrell") +/mob/living/carbon/human/interactive/away/hotel/Initialize(mapload) + . = ..(mapload, /datum/species/skrell) /mob/living/carbon/human/interactive/away/hotel/doSetup() ..() @@ -24,12 +24,6 @@ for(var/obj/item/I in get_all_slots()) I.flags |= NODROP - // FIXME(crazylemon) a hack to prevent guards from running around with an - // extra security jumpsuit like a goof - for(var/obj/item/clothing/under/U in get_all_slots()) - if(w_uniform != U) - qdel(U) - /mob/living/carbon/human/interactive/away/hotel/guard/KnockOut() // you'll never take me alive (this triggers the implant) emote("deathgasp") diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index d159ed70eb2..b26bdba7d92 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -82,12 +82,12 @@ user.mutations.Add(XRAY) if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Wealth") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -95,12 +95,12 @@ new /obj/structure/closet/syndicate/resources/everything(loc) if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Immortality") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -108,12 +108,12 @@ user.verbs += /mob/living/carbon/proc/immortality if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("To Kill") to_chat(user, "Your wish is granted, but at a terrible cost...") @@ -130,12 +130,12 @@ obj_count++ if(ishuman(user)) var/mob/living/carbon/human/human = user - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(user, "Your flesh rapidly mutates!") to_chat(user, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(user, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(user, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) user.regenerate_icons() if("Peace") to_chat(user, "Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.") diff --git a/code/modules/awaymissions/snpc.dm b/code/modules/awaymissions/snpc.dm index 0b0de76ead3..04e3bf19b8e 100644 --- a/code/modules/awaymissions/snpc.dm +++ b/code/modules/awaymissions/snpc.dm @@ -4,15 +4,19 @@ var/squad_member = 0 // was spawned by squad var/home_z -/mob/living/carbon/human/interactive/away/New() - ..() +/mob/living/carbon/human/interactive/away/Initialize(mapload) + . = ..() TRAITS |= TRAIT_ROBUST faction += "away" /mob/living/carbon/human/interactive/away/random() - if(ispath(override_under, /obj/item/clothing/under)) - equip_to_slot(new override_under(src), slot_w_uniform) ..() + // a little hacky but it should prevent doubled uniforms + if(ispath(override_under, /obj/item/clothing/under)) + var/old_under = w_uniform + w_uniform = null + equip_to_slot(new override_under(src), slot_w_uniform) + qdel(old_under) /mob/living/carbon/human/interactive/away/doSetup() ..() @@ -78,4 +82,4 @@ if(living < squad_size && !length(viewers(src, world.view))) var/mob/living/carbon/human/interactive/away/A = new squad_type(loc) squad += A - A.squad_member = 1 \ No newline at end of file + A.squad_member = 1 diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 65220b0b754..c0bc96489b4 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -156,7 +156,8 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away while(sanity > 0) sanity-- - var/turf/T = locate(rand(25, world.maxx - 25), rand(25, world.maxy - 25), z_level) + // 8: 7 is the normal view distance of a client, +1 so that ruins don't suddenly appear + var/turf/T = locate(rand(TRANSITION_BORDER_WEST + (8 + ruin.width/2), TRANSITION_BORDER_EAST - (8 + ruin.width/2)), rand(TRANSITION_BORDER_SOUTH + (8 + ruin.height/2), TRANSITION_BORDER_NORTH - (8 + ruin.height/2)), z_level) var/valid = 1 for(var/turf/check in ruin.get_affected_turfs(T,1)) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index d3dd6a5438b..c7f8504f13e 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -246,6 +246,13 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) "sig_low.gif" = 'icons/program_icons/sig_low.gif', "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', "sig_none.gif" = 'icons/program_icons/sig_none.gif', + "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', + "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', + "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', + "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', + "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', + "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', + "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', ) /datum/asset/nanoui @@ -317,7 +324,7 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipe-item.dmi', state, D) for(var/state in icon_states('icons/obj/pipes/disposal.dmi')) - if(!(state in list("conpipe-c", "conpipe-j1", "conpipe-s", "conpipe-t", "conpipe-y", "intake", "outlet"))) //Pipes we want sprites for + if(!(state in list("pipe-c", "pipe-j1", "pipe-s", "pipe-t", "pipe-y", "intake", "outlet"))) //Pipes we want sprites for continue for(var/D in cardinal) assets["[state]-[dir2text(D)].png"] = icon('icons/obj/pipes/disposal.dmi', state, D) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 0582b92be67..f3919c2ba27 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -246,10 +246,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts switch(current_tab) if(TAB_CHAR) // Character Settings - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. species = initial(species) - S = all_species[species] + S = GLOB.all_species[species] random_character() dat += "
" @@ -828,7 +828,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/ShowDisabilityState(mob/user,flag,label) - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(flag==DISABILITY_FLAG_FAT && !(CAN_BE_FAT in S.species_traits)) return "
  • [species] cannot be fat.
  • " return "
  • [label]: [disabilities & flag ? "Yes" : "No"]
  • " @@ -1053,7 +1053,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts /datum/preferences/proc/process_link(mob/user, list/href_list) if(!user) return - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(href_list["preference"] == "job") switch(href_list["task"]) if("close") @@ -1291,7 +1291,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts new_species += whitelisted_species species = input("Please select a species", "Character Generation", null) in new_species - var/datum/species/NS = all_species[species] + var/datum/species/NS = GLOB.all_species[species] if(!istype(NS)) //The species was invalid. Notify the user and fail out. species = prev_species to_chat(user, "Invalid species, please pick something else.") @@ -2083,8 +2083,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character) - var/datum/species/S = all_species[species] - character.change_species(species) // Yell at me if this causes everything to melt + var/datum/species/S = GLOB.all_species[species] + character.set_species(S.type) // Yell at me if this causes everything to melt if(be_random_name) real_name = random_name(gender,species) @@ -2170,10 +2170,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.undershirt = undershirt character.socks = socks - if(character.species.bodyflags & HAS_HEAD_ACCESSORY) + if(character.dna.species.bodyflags & HAS_HEAD_ACCESSORY) H.headacc_colour = hacc_colour H.ha_style = ha_style - if(character.species.bodyflags & HAS_MARKINGS) + if(character.dna.species.bodyflags & HAS_MARKINGS) character.m_colours = m_colours character.m_styles = m_styles @@ -2183,14 +2183,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts character.backbag = backbag //Debugging report to track down a bug, which randomly assigned the plural gender to people. - if(S.has_gender && (character.gender in list(PLURAL, NEUTER))) + if(character.dna.species.has_gender && (character.gender in list(PLURAL, NEUTER))) if(isliving(src)) //Ghosts get neuter by default message_admins("[key_name_admin(character)] has spawned with their gender as plural or neuter. Please notify coders.") character.change_gender(MALE) character.change_eye_color(e_colour) - if(disabilities & DISABILITY_FLAG_FAT && (CAN_BE_FAT in character.species.species_traits)) + if(disabilities & DISABILITY_FLAG_FAT && (CAN_BE_FAT in character.dna.species.species_traits)) character.dna.SetSEState(FATBLOCK,1,1) character.overeatduration = 600 @@ -2233,7 +2233,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if(disabilities & DISABILITY_FLAG_SCRAMBLED) character.dna.SetSEState(SCRAMBLEBLOCK,1,1) - S.handle_dna(character) + character.dna.species.handle_dna(character) if(character.dna.dirtySE) character.dna.UpdateSE() diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index a175e39bc71..318cf8fb0bb 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -252,7 +252,7 @@ autohiss_mode = text2num(query.item[52]) //Sanitize - var/datum/species/SP = all_species[species] + var/datum/species/SP = GLOB.all_species[species] metadata = sanitize_text(metadata, initial(metadata)) real_name = reject_bad_name(real_name, 1) if(isnull(species)) species = "Human" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 060e53df5b7..a5b4e614551 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -49,12 +49,12 @@ if("exclude" in species_restricted) exclusive = 1 - if(H.species) + if(H.dna.species) if(exclusive) - if(!(H.species.name in species_restricted)) + if(!(H.dna.species.name in species_restricted)) wearable = 1 else - if(H.species.name in species_restricted) + if(H.dna.species.name in species_restricted) wearable = 1 if(!wearable) @@ -504,7 +504,7 @@ BLIND // can't see anything /obj/item/clothing/suit/equipped(var/mob/living/carbon/human/user, var/slot) //Handle tail-hiding on a by-species basis. ..() if(ishuman(user) && hide_tail_by_species && slot == slot_wear_suit) - if(user.species.name in hide_tail_by_species) + if(user.dna.species.name in hide_tail_by_species) if(!(flags_inv & HIDETAIL)) //Hide the tail if the user's species is in the hide_tail_by_species list and the tail isn't already hidden. flags_inv |= HIDETAIL else diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 8ee357b1ffb..1e874772478 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -16,7 +16,7 @@ /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(isvox(user)) if(flags & BLOCKHAIR) flags &= ~BLOCKHAIR else diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 49991df72d7..74af696e76e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -116,7 +116,7 @@ return 1 // Okay, it wasn't a terminal being touched, check for all the simple insertions. - if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/posibrain)) + if(input_device.type in list(/obj/item/paicard, /obj/item/mmi, /obj/item/mmi/robotic_brain)) if(integrated_ai) integrated_ai.attackby(input_device,user) // If the transfer was successful, we can clear out our vars. diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index eab5aa0c5bb..c65ea335c4d 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -609,8 +609,8 @@ var/species_icon = 'icons/mob/rig_back.dmi' // Since setting mob_icon will override the species checks in // update_inv_wear_suit(), handle species checks here. - if(wearer && sprite_sheets && sprite_sheets[wearer.get_species()]) - species_icon = sprite_sheets[wearer.get_species()] + if(wearer && sprite_sheets && sprite_sheets[wearer.dna.species.name]) + species_icon = sprite_sheets[wearer.dna.species.name] mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]") if(installed_modules.len) diff --git a/code/modules/clothing/suits/hood.dm b/code/modules/clothing/suits/hood.dm index 7e2307c96b4..c784306cf66 100644 --- a/code/modules/clothing/suits/hood.dm +++ b/code/modules/clothing/suits/hood.dm @@ -31,6 +31,8 @@ ..() /obj/item/clothing/suit/hooded/proc/RemoveHood() + if(isnull(hood)) + return icon_state = "[initial(icon_state)]" suit_adjusted = 0 if(ishuman(hood.loc)) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index aac34032dfb..764ee71583a 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -136,7 +136,7 @@ user.visible_message("[user] places \the [src] against [M]'s chest and listens attentively.", "You place \the [src] against [M]'s chest...") var/obj/item/organ/internal/H = M.get_int_organ(/obj/item/organ/internal/heart) var/obj/item/organ/internal/L = M.get_int_organ(/obj/item/organ/internal/lungs) - if((H && M.pulse) || (L && !(BREATHLESS in M.mutations) && !(NO_BREATHE in M.species.species_traits))) + if((H && M.pulse) || (L && !(BREATHLESS in M.mutations) && !(NO_BREATHE in M.dna.species.species_traits))) var/color = "notice" if(H) var/heart_sound diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index ce3e9df0655..2a734e91dcd 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -45,7 +45,7 @@ var/mob/living/carbon/human/target = M - if(istype(target.species, /datum/species/machine)) + if(ismachine(target)) to_chat(user, "[target] has no skin, how do you expect to tattoo [target.p_them()]?") return @@ -54,7 +54,7 @@ return var/datum/sprite_accessory/body_markings/tattoo/temp_tatt = marking_styles_list[tattoo_icon] - if(!(target.species.name in temp_tatt.species_allowed)) + if(!(target.dna.species.name in temp_tatt.species_allowed)) to_chat(user, "You can't think of a way to make the [tattoo_name] design work on [target == user ? "your" : "[target]'s"] body type.") return @@ -268,7 +268,7 @@ return var/mob/living/carbon/human/target = user - if(!istype(target) || target.get_species() != "Tajaran") // Only catbeasts, kthnx. + if(!istype(target) || !istajaran(target)) // Only catbeasts, kthnx. return if(target.change_body_accessory("Jay Wingler Tail")) @@ -1276,7 +1276,7 @@ /obj/item/fluff/zekemirror/attack_self(mob/user) var/mob/living/carbon/human/target = user - if(!istype(target) || target.get_species() != "Skrell") // It'd be strange to see other races with head tendrils. + if(!istype(target) || !isskrell(target)) // It'd be strange to see other races with head tendrils. return if(target.change_hair("Zekes Tentacles", 1)) diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index abab5c39254..cd9b0c02206 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -2,6 +2,10 @@ announceWhen = 50 endWhen = 900 + var/list/spawned_mobs = list( + /mob/living/simple_animal/hostile/carp = 95, + /mob/living/simple_animal/hostile/carp/megacarp = 5, + ) var/list/spawned_carp = list() /datum/event/carp_migration/setup() @@ -17,6 +21,7 @@ event_announcement.Announce(announcement, "Lifesign Alert") /datum/event/carp_migration/start() + if(severity == EVENT_LEVEL_MAJOR) spawn_fish(landmarks_list.len) else if(severity == EVENT_LEVEL_MODERATE) @@ -32,19 +37,17 @@ spawn_locations.Add(C.loc) spawn_locations = shuffle(spawn_locations) num_groups = min(num_groups, spawn_locations.len) - + var/i = 1 while(i <= num_groups) var/group_size = rand(group_size_min, group_size_max) for(var/j = 1, j <= group_size, j++) - var/carptype = /mob/living/simple_animal/hostile/carp - if(prob(5)) - carptype = /mob/living/simple_animal/hostile/carp/megacarp + var/carptype = pickweight(spawned_mobs) spawned_carp.Add(new carptype(spawn_locations[i])) i++ /datum/event/carp_migration/end() - for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp) + for(var/mob/living/simple_animal/hostile/C in spawned_carp) if(!C.stat) var/turf/T = get_turf(C) if(istype(T, /turf/space)) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index cf2e3621498..87836f217b8 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -18,7 +18,7 @@ continue if(!H.client) continue - if(VIRUSIMMUNE in H.species.species_traits) //don't let virus immune things get diseases they're not supposed to get. + if(VIRUSIMMUNE in H.dna.species.species_traits) //don't let virus immune things get diseases they're not supposed to get. continue var/turf/T = get_turf(H) if(!T) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index ef7b99e1133..888e2b38dd1 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -139,7 +139,8 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Sentience", /datum/event/sentience, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Aurora Caelus", /datum/event/aurora_caelus, 15, is_one_shot = TRUE) + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Aurora Caelus", /datum/event/aurora_caelus, 15, is_one_shot = TRUE), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Koi School", /datum/event/carp_migration/koi, 80,) ) /datum/event_container/moderate diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index db9dd4c6955..9ca4e878050 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -17,8 +17,8 @@ if(announce) 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) + var/list/skipped_areas = list(/area/turret_protected/ai, /area/syndicate_depot) + var/list/skipped_areas_apc = list(/area/engine/engineering, /area/syndicate_depot) for(var/obj/machinery/power/smes/S in machines) var/area/current_area = get_area(S) @@ -41,8 +41,8 @@ C.cell.charge = 0 /proc/power_restore(var/announce = 1) - var/list/skipped_areas = list(/area/turret_protected/ai) - var/list/skipped_areas_apc = list(/area/engine/engineering) + var/list/skipped_areas = list(/area/turret_protected/ai, /area/syndicate_depot) + var/list/skipped_areas_apc = list(/area/engine/engineering, /area/syndicate_depot) if(announce) event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg') diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index b4a67ac9850..a66dcd66d0e 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -119,22 +119,22 @@ if(2) //X is an object message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]" - if(9) //X is harmful to humans + if(9) //X is harmful to crew switch(rand(1,7)) //What is X? if(1) //X is a threat - message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO CREW" if(2) //X is a job - message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO CREW" if(3) //X is an object - message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS" + message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO CREW" if(4) //X is an action - message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS" + message = "THOSE WHO [ionmust] ARE HARMFUL TO CREW" if(5) //X is an abstract - message = "[ionabstract] IS HARMFUL TO HUMANS" + message = "[ionabstract] IS HARMFUL TO CREW" if(6) //X is being a job - message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS" + message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO CREW" if(7) //X is doing a thing - message = "[ionthings] IS HARMFUL TO HUMANS" + message = "[ionthings] IS HARMFUL TO CREW" if(10 to 11) //(Not) Having X is harmful switch(rand(1,2)) //Is having or not having harmful? @@ -304,16 +304,16 @@ if(24 to 26) //The AI must always message = "YOU MUST ALWAYS [ionmust]" - if(27 to 28) //Humans must eat X to survive + if(27 to 28) //Crew must eat X to survive switch(rand(1,4)) //What is X? if(1) //X is a food - message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE" if(2) //X is an object - message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE" if(3) //X is a threat - message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE" if(4) //X is a job - message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE" + message = "CREW MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE" if(29 to 31) //Change jobs or ranks switch(rand(1,2)) //Change job or rank? @@ -360,54 +360,54 @@ if(2) //X is perform Y message = "THE [ioncrew1] MUST [ionmust]" - if(34) //X is non/the only human + if(34) //X is non/the only crew switch(rand(1,2)) //Only or non? - if(1) //Only human + if(1) //Only crew switch(rand(1,7)) //Who is it? if(1) //A specific job - message = "ONLY THE [ioncrew1] ARE HUMAN" + message = "ONLY THE [ioncrew1] ARE CREW" if(2) //Two specific jobs - message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN" + message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE CREW" if(3) //Threats - message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN" + message = "ONLY [ionadjectiveshalf][ionthreats] ARE CREW" if(4) // Objects - message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN" + message = "ONLY [ionadjectiveshalf][ionobjects] ARE CREW" if(5) // Species - message = "ONLY [ionspecies] ARE HUMAN" + message = "ONLY [ionspecies] ARE CREW" if(6) //Adjective crewmembers - message = "ONLY [ionadjectives] PEOPLE ARE HUMAN" + message = "ONLY [ionadjectives] PEOPLE ARE CREW" if(7) //Only people who X switch(rand(1,3)) //What is X? if(1) //X is perform an action - message = "ONLY THOSE WHO [ionmust] ARE HUMAN" + message = "ONLY THOSE WHO [ionmust] ARE CREW" if(2) //X is own certain objects - message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN" + message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE CREW" if(3) //X is eat certain food - message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN" + message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE CREW" - if(2) //Non human + if(2) //Non crew switch(rand(1,7)) //Who is it? if(1) //A specific job - message = "[ioncrew1] ARE NON-HUMAN" + message = "[ioncrew1] ARE NON-CREW" if(2) //Two specific jobs - message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN" + message = "[ioncrew1] AND [ioncrew2] ARE NON-CREW" if(3) //Threats - message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN" + message = "[ionadjectiveshalf][ionthreats] ARE NON-CREW" if(4) // Objects - message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN" + message = "[ionadjectiveshalf][ionobjects] ARE NON-CREW" if(5) // Species - message = "[ionspecies] ARE NON-HUMAN" + message = "[ionspecies] ARE NON-CREW" if(6) //Adjective crewmembers - message = "[ionadjectives] PEOPLE ARE NON-HUMAN" + message = "[ionadjectives] PEOPLE ARE NON-CREW" if(7) //Only people who X switch(rand(1,3)) //What is X? if(1) //X is perform an action - message = "THOSE WHO [ionmust] ARE NON-HUMAN" + message = "THOSE WHO [ionmust] ARE NON-CREW" if(2) //X is own certain objects - message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN" + message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-CREW" if(3) //X is eat certain food - message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN" + message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-CREW" if(35 to 36) //You must protect or harm X switch(rand(1,2)) //Protect or harm? diff --git a/code/modules/events/koi_mirgration.dm b/code/modules/events/koi_mirgration.dm new file mode 100644 index 00000000000..868457721b2 --- /dev/null +++ b/code/modules/events/koi_mirgration.dm @@ -0,0 +1,9 @@ +/datum/event/carp_migration + spawned_mobs = list( + /mob/living/simple_animal/hostile/retaliate/carp/koi = 95, + /mob/living/simple_animal/hostile/retaliate/carp/koi/honk = 2, + ) + + +/datum/event/carp_migration/koi/start() + spawn_fish(landmarks_list.len) \ No newline at end of file diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index cc59ec78128..321a8135150 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -4,7 +4,7 @@ /datum/event/mass_hallucination/start() for(var/mob/living/carbon/human/H in living_mob_list) var/armor = H.getarmor(type = "rad") - if((RADIMMUNE in H.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected + if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected continue H.AdjustHallucinate(rand(50, 100)) diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index b69ed4738b6..ea35118ab11 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -33,7 +33,7 @@ dream_images += pick_n_take(nightmares) nightmare++ for(var/i in 1 to dream_images.len) - addtimer(CALLBACK(src, .proc/experience_dream, nightmares[i], TRUE), ((i - 1) * rand(30,60))) + addtimer(CALLBACK(src, .proc/experience_dream, dream_images[i], TRUE), ((i - 1) * rand(30,60))) return TRUE /mob/living/carbon/proc/handle_dreams() @@ -54,4 +54,3 @@ if(isNightmare) dream_image = "[dream_image]" to_chat(src, "... [dream_image] ...") - diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 02f743d7478..70027028344 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -57,7 +57,7 @@ name = "sandwich" desc = "A sandwich! A timeless classic." icon_state = "breadslice" - baseicon = "sandwich" + baseicon = "sandwichcustom" basename = "sandwich" toptype = new /obj/item/reagent_containers/food/snacks/breadslice() @@ -66,9 +66,10 @@ /obj/item/reagent_containers/food/snacks/customizable name = "sandwich" desc = "A sandwich! A timeless classic." - icon_state = "breadslice" - var/baseicon = "sandwich" - var/basename = "sandwich" + icon = 'icons/obj/food/custom.dmi' + icon_state = "sandwichcustom" + var/baseicon = "sandwichcustom" + var/basename = "sandwichcustom" bitesize = 4 var/top = 1 //Do we have a top? var/obj/item/toptype @@ -94,7 +95,7 @@ desc = "Noodles. With stuff. Delicious." icon_state = "pasta_bot" baseicon = "pasta_bot" - basename = "spaghetti" + basename = "pasta" add_overlays = 0 top = 0 @@ -312,7 +313,7 @@ name = "burger bun" desc = "A bun for a burger. Delicious." icon_state = "burger" - baseicon = "burger" + baseicon = "burgercustom" basename = "burger" toptype = new /obj/item/reagent_containers/food/snacks/bun() @@ -377,9 +378,9 @@ /obj/item/reagent_containers/food/snacks/customizable/examine(mob/user) ..(user) - var/whatsinside = pick(ingredients) - - to_chat(user, " You think you can see [whatsinside] in there.") + if(LAZYLEN(ingredients)) + var/whatsinside = pick(ingredients) + to_chat(user, " You think you can see [whatsinside] in there.") /obj/item/reagent_containers/food/snacks/customizable/proc/newname() @@ -469,4 +470,3 @@ if(unsorted[it] == i) sorted[it] = i return sorted - diff --git a/code/modules/food_and_drinks/food/foods/baked_goods.dm b/code/modules/food_and_drinks/food/foods/baked_goods.dm new file mode 100644 index 00000000000..9da07f4f0b8 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/baked_goods.dm @@ -0,0 +1,434 @@ + +////////////////////// +// Cakes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/carrotcake + name = "carrot cake" + desc = "A favorite desert of a certain wascally wabbit. Not a lie." + icon_state = "carrotcake" + slice_path = /obj/item/reagent_containers/food/snacks/carrotcakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FFD675" + list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/carrotcakeslice + name = "carrot cake slice" + desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." + icon_state = "carrotcake_slice" + trash = /obj/item/trash/plate + filling_color = "#FFD675" + +/obj/item/reagent_containers/food/snacks/sliceable/braincake + name = "brain cake" + desc = "A squishy cake-thing." + icon_state = "braincake" + slice_path = /obj/item/reagent_containers/food/snacks/braincakeslice + slices_num = 5 + filling_color = "#E6AEDB" + bitesize = 3 + list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/braincakeslice + name = "brain cake slice" + desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." + icon_state = "braincakeslice" + trash = /obj/item/trash/plate + filling_color = "#E6AEDB" + +/obj/item/reagent_containers/food/snacks/sliceable/cheesecake + name = "cheese cake" + desc = "DANGEROUSLY cheesy." + icon_state = "cheesecake" + slice_path = /obj/item/reagent_containers/food/snacks/cheesecakeslice + slices_num = 5 + filling_color = "#FAF7AF" + bitesize = 3 + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/cheesecakeslice + name = "cheese cake slice" + desc = "Slice of pure cheestisfaction." + icon_state = "cheesecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAF7AF" + +/obj/item/reagent_containers/food/snacks/sliceable/plaincake + name = "vanilla cake" + desc = "A plain cake, not a lie." + icon_state = "plaincake" + slice_path = /obj/item/reagent_containers/food/snacks/plaincakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#F7EDD5" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/plaincakeslice + name = "vanilla cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "plaincake_slice" + trash = /obj/item/trash/plate + filling_color = "#F7EDD5" + +/obj/item/reagent_containers/food/snacks/sliceable/orangecake + name = "orange cake" + desc = "A cake with added orange." + icon_state = "orangecake" + slice_path = /obj/item/reagent_containers/food/snacks/orangecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FADA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/orangecakeslice + name = "orange cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "orangecake_slice" + trash = /obj/item/trash/plate + filling_color = "#FADA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/limecake + name = "lime cake" + desc = "A cake with added lime." + icon_state = "limecake" + bitesize = 3 + slice_path = /obj/item/reagent_containers/food/snacks/limecakeslice + slices_num = 5 + filling_color = "#CBFA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/limecakeslice + name = "lime cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "limecake_slice" + trash = /obj/item/trash/plate + filling_color = "#CBFA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/lemoncake + name = "lemon cake" + desc = "A cake with added lemon." + icon_state = "lemoncake" + slice_path = /obj/item/reagent_containers/food/snacks/lemoncakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#FAFA8E" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/lemoncakeslice + name = "lemon cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "lemoncake_slice" + trash = /obj/item/trash/plate + filling_color = "#FAFA8E" + +/obj/item/reagent_containers/food/snacks/sliceable/chocolatecake + name = "chocolate cake" + desc = "A cake with added chocolate." + icon_state = "chocolatecake" + slice_path = /obj/item/reagent_containers/food/snacks/chocolatecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#805930" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/chocolatecakeslice + name = "chocolate cake slice" + desc = "Just a slice of cake, it is enough for everyone." + icon_state = "chocolatecake_slice" + trash = /obj/item/trash/plate + filling_color = "#805930" + +/obj/item/reagent_containers/food/snacks/sliceable/birthdaycake + name = "birthday cake" + desc = "Happy Birthday..." + icon_state = "birthdaycake" + slice_path = /obj/item/reagent_containers/food/snacks/birthdaycakeslice + slices_num = 5 + filling_color = "#FFD6D6" + bitesize = 3 + list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/birthdaycakeslice + name = "birthday cake slice" + desc = "A slice of your birthday" + icon_state = "birthdaycakeslice" + trash = /obj/item/trash/plate + filling_color = "#FFD6D6" + +/obj/item/reagent_containers/food/snacks/sliceable/applecake + name = "apple cake" + desc = "A cake centered with Apple." + icon_state = "applecake" + slice_path = /obj/item/reagent_containers/food/snacks/applecakeslice + slices_num = 5 + bitesize = 3 + filling_color = "#EBF5B8" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/applecakeslice + name = "apple cake slice" + desc = "A slice of heavenly cake." + icon_state = "applecakeslice" + trash = /obj/item/trash/plate + filling_color = "#EBF5B8" + + +////////////////////// +// Cookies // +////////////////////// + +/obj/item/reagent_containers/food/snacks/cookie + name = "cookie" + desc = "COOKIE!!!" + icon_state = "COOKIE!!!" + bitesize = 1 + filling_color = "#DBC94F" + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/fortunecookie + name = "fortune cookie" + desc = "A true prophecy in each cookie!" + icon_state = "fortune_cookie" + filling_color = "#E8E79E" + list_reagents = list("nutriment" = 3) + trash = /obj/item/paper/fortune + +/obj/item/reagent_containers/food/snacks/sugarcookie + name = "sugar cookie" + desc = "Just like your little sister used to make." + icon_state = "sugarcookie" + list_reagents = list("nutriment" = 3, "sugar" = 3) + + +////////////////////// +// Pies // +////////////////////// + +/obj/item/reagent_containers/food/snacks/pie + name = "banana cream pie" + desc = "Just like back home, on clown planet! HONK!" + icon_state = "pie" + trash = /obj/item/trash/plate + filling_color = "#FBFFB8" + bitesize = 3 + list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) + ..() + new/obj/effect/decal/cleanable/pie_smudge(loc) + visible_message("[src] splats.","You hear a splat.") + qdel(src) + +/obj/item/reagent_containers/food/snacks/meatpie + name = "meat-pie" + icon_state = "meatpie" + desc = "An old barber recipe, very delicious!" + trash = /obj/item/trash/plate + filling_color = "#948051" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/tofupie + name = "tofu-pie" + icon_state = "meatpie" + desc = "A delicious tofu pie." + trash = /obj/item/trash/plate + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/amanita_pie + name = "amanita pie" + desc = "Sweet and tasty poison pie." + icon_state = "amanita_pie" + filling_color = "#FFCCCC" + bitesize = 4 + list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) + +/obj/item/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 = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/plump_pie/New() + ..() + if(prob(10)) + name = "exceptional plump pie" + desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" // What + reagents.add_reagent("omnizine", 5) + +/obj/item/reagent_containers/food/snacks/xemeatpie + name = "Xeno-pie" + icon_state = "xenomeatpie" + desc = "A delicious meatpie. Probably heretical." + trash = /obj/item/trash/plate + filling_color = "#43DE18" + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/applepie + name = "apple pie" + desc = "A pie containing sweet sweet love... or apple." + icon_state = "applepie" + filling_color = "#E0EDC5" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/cherrypie + name = "cherry pie" + desc = "Taste so good, make a grown man cry." + icon_state = "cherrypie" + filling_color = "#FF525A" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/pumpkinpie + name = "pumpkin pie" + desc = "A delicious treat for the autumn months." + icon_state = "pumpkinpie" + slice_path = /obj/item/reagent_containers/food/snacks/pumpkinpieslice + slices_num = 5 + bitesize = 3 + filling_color = "#F5B951" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/pumpkinpieslice + name = "pumpkin pie slice" + desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." + icon_state = "pumpkinpieslice" + trash = /obj/item/trash/plate + filling_color = "#F5B951" + + +////////////////////// +// Donuts // +////////////////////// + +/obj/item/reagent_containers/food/snacks/donut + name = "donut" + desc = "Goes great with Robust Coffee." + icon_state = "donut1" + bitesize = 5 + list_reagents = list("nutriment" = 3, "sugar" = 2) + var/extra_reagent = null + filling_color = "#D2691E" + var/randomized_sprinkles = 1 + +/obj/item/reagent_containers/food/snacks/donut/New() + ..() + if(randomized_sprinkles && prob(30)) + icon_state = "donut2" + name = "frosted donut" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/sprinkles + name = "frosted donut" + icon_state = "donut2" + list_reagents = list("nutriment" = 3, "sugar" = 2, "spinkles" = 2) + filling_color = "#FF69B4" + randomized_sprinkles = 0 + +/obj/item/reagent_containers/food/snacks/donut/chaos + name = "chaos donut" + desc = "Like life, it never quite tastes the same." + bitesize = 10 + +/obj/item/reagent_containers/food/snacks/donut/chaos/New() + ..() + 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" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/jelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "berryjuice" + +/obj/item/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" + reagents.add_reagent("sprinkles", 2) + filling_color = "#FF69B4" + +/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "slimejelly" + +/obj/item/reagent_containers/food/snacks/donut/jelly/cherryjelly + name = "jelly donut" + desc = "You jelly?" + icon_state = "jdonut1" + extra_reagent = "cherryjelly" + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/muffin + name = "muffin" + desc = "A delicious and spongy little cake." + icon_state = "muffin" + filling_color = "#E0CF9B" + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/berryclafoutis + name = "berry clafoutis" + desc = "No black birds, this is a good sign." + icon_state = "berryclafoutis" + trash = /obj/item/trash/plate + bitesize = 3 + list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/poppypretzel + name = "poppy pretzel" + desc = "A large soft pretzel full of POP! It's all twisted up!" + icon_state = "poppypretzel" + filling_color = "#916E36" + list_reagents = list("nutriment" = 5) + +/obj/item/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" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/New() + ..() + 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("omnizine", 5) + +/obj/item/reagent_containers/food/snacks/appletart + name = "golden apple streusel tart" + desc = "A tasty dessert that won't make it through a metal detector." + icon_state = "gappletart" + trash = /obj/item/trash/plate + filling_color = "#FFFF00" + bitesize = 3 + list_reagents = list("nutriment" = 8, "gold" = 5, "vitamin" = 4) + +/obj/item/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) diff --git a/code/modules/food_and_drinks/food/foods/bread.dm b/code/modules/food_and_drinks/food/foods/bread.dm new file mode 100644 index 00000000000..c841f8d65fa --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/bread.dm @@ -0,0 +1,183 @@ + +////////////////////// +// Breads // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/meatbread + name = "meatbread loaf" + desc = "The culinary base of every self-respecting eloquen/tg/entleman." + icon_state = "meatbread" + slice_path = /obj/item/reagent_containers/food/snacks/meatbreadslice + slices_num = 5 + filling_color = "#FF7575" + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/meatbreadslice + name = "meatbread slice" + desc = "A slice of delicious meatbread." + icon_state = "meatbreadslice" + trash = /obj/item/trash/plate + filling_color = "#FF7575" + +/obj/item/reagent_containers/food/snacks/sliceable/xenomeatbread + name = "xenomeatbread loaf" + desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." + icon_state = "xenomeatbread" + slice_path = /obj/item/reagent_containers/food/snacks/xenomeatbreadslice + slices_num = 5 + filling_color = "#8AFF75" + list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/xenomeatbreadslice + name = "xenomeatbread slice" + desc = "A slice of delicious meatbread. Extra Heretical." + icon_state = "xenobreadslice" + trash = /obj/item/trash/plate + filling_color = "#8AFF75" + +/obj/item/reagent_containers/food/snacks/sliceable/spidermeatbread + name = "spider meat loaf" + desc = "Reassuringly green meatloaf made from spider meat." + icon_state = "spidermeatbread" + slice_path = /obj/item/reagent_containers/food/snacks/spidermeatbreadslice + slices_num = 5 + list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) + +/obj/item/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 + list_reagents = list("toxin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/bananabread + name = "Banana-nut bread" + desc = "A heavenly and filling treat." + icon_state = "bananabread" + slice_path = /obj/item/reagent_containers/food/snacks/bananabreadslice + slices_num = 5 + filling_color = "#EDE5AD" + list_reagents = list("banana" = 20, "nutriment" = 20) + +/obj/item/reagent_containers/food/snacks/bananabreadslice + name = "Banana-nut bread slice" + desc = "A slice of delicious banana bread." + icon_state = "bananabreadslice" + trash = /obj/item/trash/plate + filling_color = "#EDE5AD" + +/obj/item/reagent_containers/food/snacks/sliceable/tofubread + name = "Tofubread" + icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." + icon_state = "tofubread" + slice_path = /obj/item/reagent_containers/food/snacks/tofubreadslice + slices_num = 5 + filling_color = "#F7FFE0" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/tofubreadslice + name = "Tofubread slice" + desc = "A slice of delicious tofubread." + icon_state = "tofubreadslice" + trash = /obj/item/trash/plate + filling_color = "#F7FFE0" + +/obj/item/reagent_containers/food/snacks/sliceable/bread + name = "Bread" + icon_state = "Some plain old Earthen bread." + icon_state = "bread" + slice_path = /obj/item/reagent_containers/food/snacks/breadslice + slices_num = 6 + filling_color = "#FFE396" + list_reagents = list("nutriment" = 10) + +/obj/item/reagent_containers/food/snacks/breadslice + name = "Bread slice" + desc = "A slice of home." + icon_state = "breadslice" + trash = /obj/item/trash/plate + filling_color = "#D27332" + list_reagents = list("nutriment" = 2, "bread" = 5) + +/obj/item/reagent_containers/food/snacks/sliceable/creamcheesebread + name = "Cream Cheese Bread" + desc = "Yum yum yum!" + icon_state = "creamcheesebread" + slice_path = /obj/item/reagent_containers/food/snacks/creamcheesebreadslice + slices_num = 5 + filling_color = "#FFF896" + list_reagents = list("nutriment" = 20, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/creamcheesebreadslice + name = "Cream Cheese Bread slice" + desc = "A slice of yum!" + icon_state = "creamcheesebreadslice" + trash = /obj/item/trash/plate + filling_color = "#FFF896" + list_reagents = list("nutriment" = 4, "vitamin" = 1) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/bun + name = "bun" + desc = "The base for any self-respecting burger." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "bun" + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/flatbread + name = "flatbread" + desc = "Bland but filling." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "flatbread" + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/baguette + name = "baguette" + desc = "Bon appetit!" + icon_state = "baguette" + filling_color = "#E3D796" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/twobread + name = "Two Bread" + desc = "It is very bitter and winy." + icon_state = "twobread" + filling_color = "#DBCC9A" + bitesize = 3 + list_reagents = list("nutriment" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jelliedtoast + name = "Jellied Toast" + desc = "A slice of bread covered with delicious jam." + icon_state = "jellytoast" + trash = /obj/item/trash/plate + filling_color = "#B572AB" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry + list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jelliedtoast/slime + list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/rofflewaffles + name = "Roffle Waffles" + desc = "Waffles from Roffle. Co." + icon_state = "rofflewaffles" + trash = /obj/item/trash/waffles + filling_color = "#FF00F7" + bitesize = 4 + list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/waffles + name = "waffles" + desc = "Mmm, waffles." + icon_state = "waffles" + trash = /obj/item/trash/waffles + filling_color = "#E6DEB5" + list_reagents = list("nutriment" = 8, "vitamin" = 1) diff --git a/code/modules/food_and_drinks/food/candy.dm b/code/modules/food_and_drinks/food/foods/candy.dm similarity index 100% rename from code/modules/food_and_drinks/food/candy.dm rename to code/modules/food_and_drinks/food/foods/candy.dm diff --git a/code/modules/food_and_drinks/food/foods/desserts.dm b/code/modules/food_and_drinks/food/foods/desserts.dm new file mode 100644 index 00000000000..ff99efd07be --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/desserts.dm @@ -0,0 +1,97 @@ + +////////////////////// +// Ice Cream // +////////////////////// + +/obj/item/reagent_containers/food/snacks/icecream + name = "ice cream" + desc = "Delicious ice cream." + icon = 'icons/obj/kitchen.dmi' + icon_state = "icecream_cone" + bitesize = 3 + list_reagents = list("nutriment" = 1, "sugar" = 1) + +/obj/item/reagent_containers/food/snacks/icecream/New() + ..() + update_icon() + +/obj/item/reagent_containers/food/snacks/icecream/update_icon() + overlays.Cut() + var/image/filling = image('icons/obj/kitchen.dmi', src, "icecream_color") + filling.icon += mix_color_from_reagents(reagents.reagent_list) + overlays += filling + +/obj/item/reagent_containers/food/snacks/icecream/icecreamcone + name = "ice cream cone" + desc = "Delicious ice cream." + icon_state = "icecream_cone" + volume = 50 + bitesize = 3 + list_reagents = list("nutriment" = 3, "sugar" = 7, "ice" = 2) + +/obj/item/reagent_containers/food/snacks/icecream/icecreamcup + name = "chocolate ice cream cone" + desc = "Delicious ice cream." + icon_state = "icecream_cup" + volume = 50 + bitesize = 6 + list_reagents = list("nutriment" = 5, "chocolate" = 8, "ice" = 2) + +/obj/item/reagent_containers/food/snacks/icecreamsandwich + name = "icecream sandwich" + desc = "Portable Ice-cream in it's own packaging." + icon_state = "icecreamsandwich" + list_reagents = list("nutriment" = 2, "ice" = 2) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/friedbanana + name = "Fried Banana" + desc = "Goreng Pisang, also known as fried bananas." + icon_state = "friedbanana" + list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4) + +/obj/item/reagent_containers/food/snacks/ricepudding + name = "Rice Pudding" + desc = "Where's the Jam!" + icon_state = "rpudding" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/spacylibertyduff + name = "Spacy Liberty Duff" + desc = "Jello gelatin, from Alfred Hubbard's cookbook." + icon_state = "spacylibertyduff" + trash = /obj/item/trash/snack_bowl + filling_color = "#42B873" + bitesize = 3 + list_reagents = list("nutriment" = 6, "psilocybin" = 6) + +/obj/item/reagent_containers/food/snacks/amanitajelly + name = "Amanita Jelly" + desc = "Looks curiously toxic." + icon_state = "amanitajelly" + trash = /obj/item/trash/snack_bowl + filling_color = "#ED0758" + bitesize = 3 + list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) + +/obj/item/reagent_containers/food/snacks/candiedapple + name = "Candied Apple" + desc = "An apple coated in sugary sweetness." + icon_state = "candiedapple" + filling_color = "#F21873" + bitesize = 3 + list_reagents = list("nutriment" = 3, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/mint + name = "mint" + desc = "it is only wafer thin." + icon_state = "mint" + bitesize = 1 + filling_color = "#F2F2F2" + list_reagents = list("minttoxin" = 1) diff --git a/code/modules/food_and_drinks/food/foods/ethnic.dm b/code/modules/food_and_drinks/food/foods/ethnic.dm new file mode 100644 index 00000000000..ae8fc289798 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/ethnic.dm @@ -0,0 +1,135 @@ + +////////////////////// +// Mexican // +////////////////////// + +/obj/item/reagent_containers/food/snacks/taco + name = "taco" + desc = "Take a bite!" + icon_state = "taco" + bitesize = 3 + list_reagents = list("nutriment" = 7, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/burrito + name = "Burrito" + desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." + icon_state = "burrito" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + list_reagents = list("nutriment" = 4, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/chimichanga + name = "Chimichanga" + desc = "Time to eat a chimi-f***ing-changa." + icon_state = "chimichanga" + trash = /obj/item/trash/plate + filling_color = "#A36A1F" + list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it. + +/obj/item/reagent_containers/food/snacks/enchiladas + name = "Enchiladas" + desc = "Viva La Mexico!" + icon_state = "enchiladas" + trash = /obj/item/trash/tray + filling_color = "#A36A1F" + bitesize = 4 + list_reagents = list("nutriment" = 8, "capsaicin" = 6) + +/obj/item/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) + + +////////////////////// +// Chinese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chinese/chowmein + name = "chow mein" + desc = "What is in this anyways?" + icon_state = "chinese1" + junkiness = 25 + list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball + name = "Sweet & Sour Chicken Balls" + desc = "Is this chicken cooked? The odds are better than wok paper scissors." + icon_state = "chickenball" + junkiness = 25 + list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2) + +/obj/item/reagent_containers/food/snacks/chinese/tao + name = "Admiral Yamamoto carp" + desc = "Tastes like chicken." + icon_state = "chinese2" + junkiness = 25 + list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/chinese/newdles + name = "chinese newdles" + desc = "Made fresh, weekly!" + icon_state = "chinese3" + junkiness = 25 + list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/chinese/rice + name = "fried rice" + desc = "A timeless classic." + icon_state = "chinese4" + junkiness = 20 + list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) + + +////////////////////// +// Japanese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chawanmushi + name = "chawanmushi" + desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." + icon_state = "chawanmushi" + trash = /obj/item/trash/snack_bowl + filling_color = "#F0F2E4" + list_reagents = list("nutriment" = 5) + +/obj/item/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" + + +////////////////////// +// Middle Eastern // +////////////////////// + +/obj/item/reagent_containers/food/snacks/human/kabob + name = "-kabob" + icon_state = "kabob" + desc = "A human meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/monkeykabob + name = "Meat-kabob" + icon_state = "kabob" + desc = "Delicious meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#A85340" + list_reagents = list("nutriment" = 8) + +/obj/item/reagent_containers/food/snacks/tofukabob + name = "Tofu-kabob" + icon_state = "kabob" + desc = "Vegan meat, on a stick." + trash = /obj/item/stack/rods + filling_color = "#FFFEE0" + list_reagents = list("nutriment" = 8) diff --git a/code/modules/food_and_drinks/food/foods/ingredients.dm b/code/modules/food_and_drinks/food/foods/ingredients.dm new file mode 100644 index 00000000000..65c20eb7eba --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/ingredients.dm @@ -0,0 +1,160 @@ + +////////////////////// +// Tofu & Soy // +////////////////////// + +/obj/item/reagent_containers/food/snacks/tofu + name = "Tofu" + icon_state = "tofu" + desc = "We all love tofu." + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("plantmatter" = 2) + +/obj/item/reagent_containers/food/snacks/fried_tofu + name = "Fried Tofu" + icon_state = "tofu" + desc = "Proof that even vegetarians crave unhealthy foods." + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("plantmatter" = 3) + +/obj/item/reagent_containers/food/snacks/soydope + name = "Soy Dope" + desc = "Dope from a soy." + icon_state = "soydope" + trash = /obj/item/trash/plate + filling_color = "#C4BF76" + list_reagents = list("nutriment" = 2) + + +////////////////////// +// Cheese // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel + name = "Cheese wheel" + desc = "A big wheel of delicious Cheddar." + icon_state = "cheesewheel" + slice_path = /obj/item/reagent_containers/food/snacks/cheesewedge + slices_num = 5 + filling_color = "#FFF700" + list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) + +/obj/item/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" + +/obj/item/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" + list_reagents = list("mercury" = 5, "lsd" = 5, "ethanol" = 5, "weird_cheese" = 5) + + +////////////////////// +// Plants // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hugemushroomslice + name = "huge mushroom slice" + desc = "A slice from a huge mushroom." + icon_state = "hugemushroomslice" + filling_color = "#E0D7C5" + bitesize = 6 + list_reagents = list("plantmatter" = 3, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/tomatomeat + name = "tomato slice" + desc = "A slice from a huge tomato." + icon_state = "tomatomeat" + filling_color = "#DB0000" + bitesize = 6 + list_reagents = list("protein" = 2) + +/obj/item/reagent_containers/food/snacks/watermelonslice + name = "Watermelon Slice" + desc = "A slice of watery goodness." + icon_state = "watermelonslice" + filling_color = "#FF3867" + +/obj/item/reagent_containers/food/snacks/pineappleslice + name = "Pineapple Slices" + desc = "Rings of pineapple." + icon_state = "pineappleslice" + filling_color = "#e5b437" + + +////////////////////// +// Dough // +////////////////////// + +/obj/item/reagent_containers/food/snacks/dough + name = "dough" + desc = "A piece of dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "dough" + list_reagents = list("nutriment" = 6) + +// Dough + rolling pin = flat dough +/obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/kitchen/rollingpin)) + if(isturf(loc)) + new /obj/item/reagent_containers/food/snacks/sliceable/flatdough(loc) + to_chat(user, "You flatten [src].") + qdel(src) + else + to_chat(user, "You need to put [src] on a surface to roll it out!") + else + ..() + +// slicable into 3xdoughslices +/obj/item/reagent_containers/food/snacks/sliceable/flatdough + name = "flat dough" + desc = "Some flattened dough." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "flat dough" + slice_path = /obj/item/reagent_containers/food/snacks/doughslice + slices_num = 3 + list_reagents = list("nutriment" = 6) + +/obj/item/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" + list_reagents = list("nutriment" = 1) + + +////////////////////// +// Chocolate // +////////////////////// + +/obj/item/reagent_containers/food/snacks/chocolatebar + name = "Chocolate Bar" + desc = "Such sweet, fattening food." + icon_state = "chocolatebar" + filling_color = "#7D5F46" + list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) + +/obj/item/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" + list_reagents = list("chocolate" = 5) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/ectoplasm + name = "ectoplasm" + desc = "A luminescent blob of what scientists refer to as 'ghost goo'." + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm" + list_reagents = list("ectoplasm" = 10) diff --git a/code/modules/food_and_drinks/food/foods/junkfood.dm b/code/modules/food_and_drinks/food/foods/junkfood.dm new file mode 100644 index 00000000000..b221348e8d8 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/junkfood.dm @@ -0,0 +1,93 @@ + +////////////////////// +// Vendor // +////////////////////// + +/obj/item/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" + junkiness = 20 + list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/sosjerky + name = "Scaredy's Private Reserve Beef Jerky" + icon_state = "sosjerky" + desc = "Beef jerky made from the finest space cows." + trash = /obj/item/trash/sosjerky + filling_color = "#631212" + junkiness = 25 + list_reagents = list("protein" = 1, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/pistachios + name = "Pistachios" + icon_state = "pistachios" + desc = "A snack of deliciously salted pistachios. A perfectly valid choice..." + trash = /obj/item/trash/pistachios + filling_color = "#BAD145" + junkiness = 20 + list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/no_raisin + name = "4no Raisins" + icon_state = "4no_raisins" + desc = "Best raisins in the universe. Not sure why." + trash = /obj/item/trash/raisins + filling_color = "#343834" + junkiness = 25 + list_reagents = list("plantmatter" = 2, "sugar" = 4) + +/obj/item/reagent_containers/food/snacks/spacetwinkie + name = "Space Twinkie" + icon_state = "space_twinkie" + desc = "Guaranteed to survive longer then you will." + filling_color = "#FFE591" + junkiness = 25 + list_reagents = list("sugar" = 4) + +/obj/item/reagent_containers/food/snacks/cheesiehonkers + name = "Cheesie Honkers" + icon_state = "cheesie_honkers" + desc = "Bite sized cheesie snacks that will honk all over your mouth." + trash = /obj/item/trash/cheesie + filling_color = "#FFA305" + junkiness = 25 + list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) + +/obj/item/reagent_containers/food/snacks/syndicake + name = "Syndi-Cakes" + icon_state = "syndi_cakes" + desc = "An extremely moist snack cake that tastes just as good after being nuked." + filling_color = "#FF5D05" + trash = /obj/item/trash/syndi_cakes + bitesize = 3 + list_reagents = list("nutriment" = 4, "salglu_solution" = 5) + +/obj/item/reagent_containers/food/snacks/tastybread + name = "bread tube" + desc = "Bread in a tube. Chewy...and surprisingly tasty." + icon_state = "tastybread" + trash = /obj/item/trash/tastybread + filling_color = "#A66829" + junkiness = 20 + list_reagents = list("nutriment" = 2, "sugar" = 4) + + +////////////////////// +// Homemade // +////////////////////// + +/obj/item/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/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 diff --git a/code/modules/food_and_drinks/food/foods/meat.dm b/code/modules/food_and_drinks/food/foods/meat.dm new file mode 100644 index 00000000000..a7f4acb4405 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/meat.dm @@ -0,0 +1,432 @@ + +////////////////////// +// Raw Meat // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meat + name = "meat" + desc = "A slab of meat" + icon_state = "meat" + health = 180 + filling_color = "#FF1C1C" + bitesize = 3 + list_reagents = list("protein" = 3) + +/obj/item/reagent_containers/food/snacks/meat/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/kitchen/knife) || istype(W, /obj/item/scalpel)) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + new /obj/item/reagent_containers/food/snacks/rawcutlet(src) + to_chat(user, "You cut the meat in thin strips.") + qdel(src) + else + ..() + +/obj/item/reagent_containers/food/snacks/meat/syntiflesh + name = "synthetic meat" + desc = "A synthetic slab of flesh." + +/obj/item/reagent_containers/food/snacks/meat/human + name = "-meat" + var/subjectname = "" + var/subjectjob = null + +/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct + name = "meat product" + desc = "A slab of station reclaimed and chemically processed meat product." + +/obj/item/reagent_containers/food/snacks/meat/monkey + //same as plain meat + +/obj/item/reagent_containers/food/snacks/meat/corgi + name = "Corgi meat" + desc = "Tastes like... well you know..." + +/obj/item/reagent_containers/food/snacks/meat/pug + name = "Pug meat" + desc = "Tastes like... well you know..." + +/obj/item/reagent_containers/food/snacks/meat/ham + name = "Ham" + desc = "Taste like bacon." + list_reagents = list("protein" = 3, "porktonium" = 10) + +/obj/item/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 + +/obj/item/reagent_containers/food/snacks/rawcutlet + name = "raw cutlet" + desc = "A thin piece of raw meat." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "rawcutlet" + bitesize = 1 + list_reagents = list("protein" = 1) + +/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/W, mob/user, params) + if(istype(W,/obj/item/kitchen/knife)) + user.visible_message( \ + "[user] cuts the raw cutlet with the knife!", \ + "You cut the raw cutlet with your knife!" \ + ) + new /obj/item/reagent_containers/food/snacks/raw_bacon(loc) + qdel(src) + +/obj/item/reagent_containers/food/snacks/bearmeat + name = "bear meat" + desc = "A very manly slab of meat." + icon_state = "bearmeat" + filling_color = "#DB0000" + bitesize = 3 + list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/xenomeat + name = "meat" + desc = "A slab of meat." + icon_state = "xenomeat" + filling_color = "#43DE18" + bitesize = 6 + list_reagents = list("protein" = 3, "vitamin" = 1) + +/obj/item/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, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/lizardmeat + name = "mutant lizard meat" + desc = "Seems to be a slab of meat from some mutant lizard thing?" + icon_state = "xenomeat" + filling_color = "#43DE18" + bitesize = 3 + list_reagents = list("protein" = 3, "toxin" = 3) + +/obj/item/reagent_containers/food/snacks/spiderleg + 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" + list_reagents = list("protein" = 2, "toxin" = 2) + +/obj/item/reagent_containers/food/snacks/raw_bacon + name = "raw bacon" + desc = "It's fleshy and pink!" + icon_state = "raw_bacon" + list_reagents = list("nutriment" = 1, "porktonium" = 10) + +/obj/item/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" + list_reagents = list("protein" = 2, "toxin" = 2) + +////////////////////// +// Cooked Meat // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meatsteak + name = "Meat steak" + desc = "A piece of hot spicy meat." + icon_state = "meatstake" + trash = /obj/item/trash/plate + filling_color = "#7A3D11" + bitesize = 3 + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/bacon + name = "bacon" + desc = "It looks juicy and tastes amazing!" + icon_state = "bacon2" + list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) + +/obj/item/reagent_containers/food/snacks/telebacon + name = "Tele Bacon" + desc = "It tastes a little odd but it is still delicious." + icon_state = "bacon" + var/obj/item/radio/beacon/bacon/baconbeacon + list_reagents = list("nutriment" = 4, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/telebacon/New() + ..() + baconbeacon = new /obj/item/radio/beacon/bacon(src) + +/obj/item/reagent_containers/food/snacks/telebacon/On_Consume(mob/M, mob/user) + if(!reagents.total_volume) + baconbeacon.loc = user + baconbeacon.digest_delay() + +/obj/item/reagent_containers/food/snacks/meatball + name = "Meatball" + desc = "A great meal all round." + icon_state = "meatball" + filling_color = "#DB0000" + list_reagents = list("protein" = 4, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/sausage + name = "Sausage" + desc = "A piece of mixed, long meat." + icon_state = "sausage" + filling_color = "#DB0000" + list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) + +/obj/item/reagent_containers/food/snacks/cutlet + name = "cutlet" + desc = "A tasty meat slice." + icon = 'icons/obj/food/food_ingredients.dmi' + icon_state = "cutlet" + list_reagents = list("protein" = 2) + +/obj/item/reagent_containers/food/snacks/spidereggsham + name = "green eggs and ham" + desc = "Would you eat them on a train? Would you eat them on a plane? Would you eat them on a state of the art corporate deathtrap floating through space?" + icon_state = "spidereggsham" + trash = /obj/item/trash/plate + bitesize = 4 + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/boiledspiderleg + name = "boiled spider leg" + desc = "A giant spider's leg that's still twitching after being cooked. Gross!" + icon_state = "spiderlegcooked" + trash = /obj/item/trash/plate + bitesize = 3 + list_reagents = list("nutriment" = 3, "capsaicin" = 2) + +/obj/item/reagent_containers/food/snacks/wingfangchu + name = "Wing Fang Chu" + desc = "A savory dish of alien wing wang in soy." + icon_state = "wingfangchu" + trash = /obj/item/trash/snack_bowl + filling_color = "#43DE18" + list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) + + +////////////////////// +// Cubes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/monkeycube + name = "monkey cube" + desc = "Just add water!" + icon_state = "monkeycube" + bitesize = 12 + filling_color = "#ADAC7F" + var/datum/species/monkey_type = /datum/species/monkey + list_reagents = list("nutriment" = 2) + +/obj/item/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature) + if(volume >= 5) + return Expand() + +/obj/item/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) + user.drop_item() + forceMove(get_turf(source)) + return 1 + +/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() + if(!QDELETED(src)) + visible_message("[src] expands!") + if(fingerprintslast) + log_game("Cube ([monkey_type]) inflated, last touched by: " + fingerprintslast) + else + log_game("Cube ([monkey_type]) inflated, last touched by: NO_DATA") + var/mob/living/carbon/human/creature = new /mob/living/carbon/human(get_turf(src)) + if(LAZYLEN(fingerprintshidden)) + creature.fingerprintshidden = fingerprintshidden.Copy() + creature.set_species(monkey_type) + qdel(src) + +/obj/item/reagent_containers/food/snacks/monkeycube/farwacube + name = "farwa cube" + monkey_type = /datum/species/monkey/tajaran + +/obj/item/reagent_containers/food/snacks/monkeycube/wolpincube + name = "wolpin cube" + monkey_type = /datum/species/monkey/vulpkanin + +/obj/item/reagent_containers/food/snacks/monkeycube/stokcube + name = "stok cube" + monkey_type = /datum/species/monkey/unathi + +/obj/item/reagent_containers/food/snacks/monkeycube/neaeracube + name = "neaera cube" + monkey_type = /datum/species/monkey/skrell + + +////////////////////// +// Eggs // +////////////////////// + +/obj/item/reagent_containers/food/snacks/egg + name = "egg" + desc = "An egg!" + icon_state = "egg" + filling_color = "#FDFFD1" + list_reagents = list("protein" = 1, "egg" = 5) + +/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) + ..() + var/turf/T = get_turf(hit_atom) + new/obj/effect/decal/cleanable/egg_smudge(T) + if(reagents) + reagents.reaction(hit_atom, TOUCH) + qdel(src) + +/obj/item/reagent_containers/food/snacks/egg/attackby(obj/item/W, mob/user, params) + if(istype( W, /obj/item/toy/crayon )) + var/obj/item/toy/crayon/C = W + var/clr = C.colourName + + if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) + to_chat(usr, "The egg refuses to take on this color!") + return + + to_chat(usr, "You color \the [src] [clr]") + icon_state = "egg-[clr]" + item_color = clr + else + ..() + +/obj/item/reagent_containers/food/snacks/egg/blue + icon_state = "egg-blue" + item_color = "blue" + +/obj/item/reagent_containers/food/snacks/egg/green + icon_state = "egg-green" + item_color = "green" + +/obj/item/reagent_containers/food/snacks/egg/mime + icon_state = "egg-mime" + item_color = "mime" + +/obj/item/reagent_containers/food/snacks/egg/orange + icon_state = "egg-orange" + item_color = "orange" + +/obj/item/reagent_containers/food/snacks/egg/purple + icon_state = "egg-purple" + item_color = "purple" + +/obj/item/reagent_containers/food/snacks/egg/rainbow + icon_state = "egg-rainbow" + item_color = "rainbow" + +/obj/item/reagent_containers/food/snacks/egg/red + icon_state = "egg-red" + item_color = "red" + +/obj/item/reagent_containers/food/snacks/egg/yellow + icon_state = "egg-yellow" + item_color = "yellow" + +/obj/item/reagent_containers/food/snacks/egg/gland + desc = "An egg! It looks weird..." + +/obj/item/reagent_containers/food/snacks/egg/gland/New() + ..() + reagents.add_reagent(get_random_reagent_id(), 15) + + var/reagent_color = mix_color_from_reagents(reagents.reagent_list) + color = reagent_color + +/obj/item/reagent_containers/food/snacks/friedegg + name = "Fried egg" + desc = "A fried egg, with a touch of salt and pepper." + icon_state = "friedegg" + filling_color = "#FFDF78" + bitesize = 1 + list_reagents = list("nutriment" = 3, "egg" = 5) + +/obj/item/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, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/chocolateegg + name = "Chocolate Egg" + desc = "Such sweet, fattening food." + icon_state = "chocolateegg" + filling_color = "#7D5F46" + list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) + +/obj/item/reagent_containers/food/snacks/omelette + name = "Omelette Du Fromage" + desc = "That's all you can say!" + icon_state = "omelette" + trash = /obj/item/trash/plate + filling_color = "#FFF9A8" + list_reagents = list("nutriment" = 8, "vitamin" = 1) + bitesize = 1 + +/obj/item/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" = 6, "egg" = 3, "vitamin" = 4) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hotdog + name = "hotdog" + desc = "Fresh footlong ready to go down on." + icon_state = "hotdog" + bitesize = 3 + list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) + +/obj/item/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, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/sliceable/turkey + name = "Turkey" + desc = "A traditional turkey served with stuffing." + icon_state = "turkey" + slice_path = /obj/item/reagent_containers/food/snacks/turkeyslice + slices_num = 6 + list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/turkeyslice + name = "turkey serving" + desc = "A serving of some tender and delicious turkey." + icon_state = "turkeyslice" + trash = /obj/item/trash/plate + filling_color = "#B97A57" + +/obj/item/reagent_containers/food/snacks/organ + name = "organ" + desc = "It's good for you." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + filling_color = "#E00D34" + bitesize = 3 + list_reagents = list("protein" = 4, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/appendix +//yes, this is the same as meat. I might do something different in future + name = "appendix" + desc = "An appendix which looks perfectly healthy." + icon = 'icons/obj/surgery.dmi' + icon_state = "appendix" + filling_color = "#E00D34" + bitesize = 3 + list_reagents = list("protein" = 3, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/appendix/inflamed + name = "inflamed appendix" + desc = "An appendix which appears to be inflamed." + icon_state = "appendixinflamed" + filling_color = "#E00D7A" diff --git a/code/modules/food_and_drinks/food/foods/misc.dm b/code/modules/food_and_drinks/food/foods/misc.dm new file mode 100644 index 00000000000..4c6c607eacb --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/misc.dm @@ -0,0 +1,171 @@ + +////////////////////// +// Meals // +////////////////////// + +/obj/item/reagent_containers/food/snacks/eggplantparm + name = "Eggplant Parmigiana" + desc = "The only good recipe for eggplant." + icon_state = "eggplantparm" + trash = /obj/item/trash/plate + filling_color = "#4D2F5E" + list_reagents = list("nutriment" = 6, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/soylentgreen + name = "Soylent Green" + desc = "Not made of people. Honest." //Totally people. + icon_state = "soylent_green" + trash = /obj/item/trash/waffles + filling_color = "#B8E6B5" + list_reagents = list("nutriment" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/soylentviridians + name = "Soylent Virdians" + desc = "Not made of people. Honest." //Actually honest for once. + icon_state = "soylent_yellow" + trash = /obj/item/trash/waffles + filling_color = "#E6FA61" + list_reagents = list("nutriment" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/monkeysdelight + name = "monkey's Delight" + desc = "Eeee Eee!" + icon_state = "monkeysdelight" + trash = /obj/item/trash/tray + filling_color = "#5C3C11" + bitesize = 6 + list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/dionaroast + name = "roast diona" + desc = "It's like an enormous, leathery carrot. With an eye." + icon_state = "dionaroast" + trash = /obj/item/trash/plate + filling_color = "#75754B" + list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/tofurkey + name = "Tofurkey" + desc = "A fake turkey made from tofu." + icon_state = "tofurkey" + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 12, "ether" = 3) + + +////////////////////// +// Salads // +////////////////////// + +/obj/item/reagent_containers/food/snacks/aesirsalad + name = "Aesir salad" + desc = "Probably too incredible for mortal men to fully enjoy." + icon_state = "aesirsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#468C00" + bitesize = 3 + list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/herbsalad + name = "herb salad" + desc = "A tasty salad with apples on top." + icon_state = "herbsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + bitesize = 3 + list_reagents = list("nutriment" = 8, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/validsalad + name = "valid salad" + desc = "It's just an herb salad with meatballs and fried potato slices. Nothing suspicious about it." + icon_state = "validsalad" + trash = /obj/item/trash/snack_bowl + filling_color = "#76B87F" + bitesize = 3 + list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) + + +////////////////////// +// Donk Pockets // +////////////////////// + +/obj/item/reagent_containers/food/snacks/donkpocket + name = "Donk-pocket" + desc = "The food of choice for the seasoned traitor." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket + name = "Warm Donk-pocket" + desc = "The food of choice for the seasoned traitor." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket/Post_Consume(mob/living/M) + M.reagents.add_reagent("omnizine", 15) + +/obj/item/reagent_containers/food/snacks/warmdonkpocket_weak + name = "Lightly Warm Donk-pocket" + desc = "The food of choice for the seasoned traitor. This one is lukewarm." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + list_reagents = list("nutriment" = 4, "weak_omnizine" = 3) + +/obj/item/reagent_containers/food/snacks/syndidonkpocket + name = "Donk-pocket" + desc = "This donk-pocket is emitting a small amount of heat." + icon_state = "donkpocket" + filling_color = "#DEDEAB" + bitesize = 100 //nom the whole thing at once. + list_reagents = list("nutriment" = 1) + +/obj/item/reagent_containers/food/snacks/syndidonkpocket/Post_Consume(mob/living/M) + M.reagents.add_reagent("omnizine", 15) + M.reagents.add_reagent("teporone", 15) + M.reagents.add_reagent("synaptizine", 15) + M.reagents.add_reagent("salglu_solution", 15) + M.reagents.add_reagent("salbutamol", 15) + M.reagents.add_reagent("methamphetamine", 15) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/boiledslimecore + name = "Boiled Slime Core" + desc = "A boiled red thing." + icon_state = "boiledrorocore" + bitesize = 3 + list_reagents = list("slimejelly" = 5) + +/obj/item/reagent_containers/food/snacks/popcorn + name = "Popcorn" + desc = "Now let's find some cinema." + icon_state = "popcorn" + trash = /obj/item/trash/popcorn + var/unpopped = 0 + filling_color = "#FFFAD4" + bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 + list_reagents = list("nutriment" = 2) + +/obj/item/reagent_containers/food/snacks/popcorn/New() + ..() + unpopped = rand(1,10) + +/obj/item/reagent_containers/food/snacks/popcorn/On_Consume(mob/M, mob/user) + if(prob(unpopped)) //lol ...what's the point? + to_chat(user, "You bite down on an un-popped kernel!") + unpopped = max(0, unpopped-1) + ..() + +/obj/item/reagent_containers/food/snacks/liquidfood + name = "\improper LiquidFood Ration" + desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" + icon_state = "liquidfood" + trash = /obj/item/trash/liquidfood + filling_color = "#A8A8A8" + bitesize = 4 + list_reagents = list("nutriment" = 20, "iron" = 3, "vitamin" = 2) diff --git a/code/modules/food_and_drinks/food/foods/pasta.dm b/code/modules/food_and_drinks/food/foods/pasta.dm new file mode 100644 index 00000000000..1b9c253ab53 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/pasta.dm @@ -0,0 +1,70 @@ + +////////////////////// +// Raw Pasta // +////////////////////// + +/obj/item/reagent_containers/food/snacks/spaghetti + name = "Spaghetti" + desc = "A bundle of raw spaghetti." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spaghetti" + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 1, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/macaroni + name = "Macaroni twists" + desc = "These are little twists of raw macaroni." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "macaroni" + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 1, "vitamin" = 1) + + +////////////////////// +// Pasta Dishes // +////////////////////// + +/obj/item/reagent_containers/food/snacks/boiledspaghetti + name = "Boiled Spaghetti" + desc = "A plain dish of noodles, this sucks." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spaghettiboiled" + trash = /obj/item/trash/plate + filling_color = "#FCEE81" + list_reagents = list("nutriment" = 2, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/pastatomato + name = "spaghetti" + desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" + icon = 'icons/obj/food/pasta.dmi' + icon_state = "pastatomato" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + bitesize = 4 + list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/meatballspaghetti + name = "spaghetti & Meatballs" + desc = "Now thats a nic'e meatball!" + icon = 'icons/obj/food/pasta.dmi' + icon_state = "meatballspaghetti" + trash = /obj/item/trash/plate + filling_color = "#DE4545" + list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/spesslaw + name = "Spesslaw" + desc = "A lawyer's favourite." + icon = 'icons/obj/food/pasta.dmi' + icon_state = "spesslaw" + filling_color = "#DE4545" + list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/macncheese + name = "Macaroni cheese" + desc = "One of the most comforting foods in the world. Apparently." + trash = /obj/item/trash/snack_bowl + icon = 'icons/obj/food/pasta.dmi' + icon_state = "macncheese" + filling_color = "#ffe45d" + list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4) diff --git a/code/modules/food_and_drinks/food/foods/pizza.dm b/code/modules/food_and_drinks/food/foods/pizza.dm new file mode 100644 index 00000000000..c34d8943da7 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/pizza.dm @@ -0,0 +1,254 @@ + +////////////////////// +// Pizzas // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sliceable/pizza + icon = 'icons/obj/food/pizza.dmi' + slices_num = 6 + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita + name = "Margherita" + desc = "The golden standard of pizzas." + icon_state = "pizzamargherita" + slice_path = /obj/item/reagent_containers/food/snacks/margheritaslice + list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/margheritaslice + name = "Margherita slice" + desc = "A slice of the classic pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "pizzamargheritaslice" + filling_color = "#BAA14C" + list_reagents = list("nutriment" = 5) + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza + name = "Meatpizza" + desc = "A pizza with meat topping." + icon_state = "meatpizza" + slice_path = /obj/item/reagent_containers/food/snacks/meatpizzaslice + list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) + +/obj/item/reagent_containers/food/snacks/meatpizzaslice + name = "Meatpizza slice" + desc = "A slice of a meaty pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "meatpizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza + name = "Mushroompizza" + desc = "Very special pizza." + icon_state = "mushroompizza" + slice_path = /obj/item/reagent_containers/food/snacks/mushroompizzaslice + list_reagents = list("plantmatter" = 30, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/mushroompizzaslice + name = "Mushroompizza slice" + desc = "Maybe it is the last slice of pizza in your life." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "mushroompizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza + name = "Vegetable pizza" + desc = "No one of Tomato Sapiens were harmed during making this pizza." + icon_state = "vegetablepizza" + slice_path = /obj/item/reagent_containers/food/snacks/vegetablepizzaslice + list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) + +/obj/item/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 = 'icons/obj/food/pizza.dmi' + icon_state = "vegetablepizzaslice" + filling_color = "#BAA14C" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza + name = "Hawaiian Pizza" + desc = "Love it or hate it, this pizza divides opinions. Complete with juicy pineapple." + icon_state = "hawaiianpizza" //NEEDED + slice_path = /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice + list_reagents = list("protein" = 15, "tomatojuice" = 6, "plantmatter" = 20, "pineapplejuice" = 6, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/hawaiianpizzaslice + name = "Hawaiian pizza slice" + desc = "A slice of polarising pizza." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "hawaiianpizzaslice" + filling_color = "#e5b437" + +/obj/item/reagent_containers/food/snacks/sliceable/pizza/macpizza + name = "Macaroni cheese pizza" + desc = "Gastronomists have yet to classify this dish as 'pizza'." + icon_state = "macpizza" + slice_path = /obj/item/reagent_containers/food/snacks/macpizzaslice + list_reagents = list("nutriment" = 40, "vitamin" = 5) //More nutriment because carbs, but it's not any more vitaminicious + filling_color = "#ffe45d" + +/obj/item/reagent_containers/food/snacks/macpizzaslice + name = "Macaroni cheese pizza slice" + desc = "A delicious slice of pizza topped with macaroni cheese... wait, what the hell? Who would do this?!" + icon = 'icons/obj/food/pizza.dmi' + icon_state = "macpizzaslice" + filling_color = "#ffe45d" + + +////////////////////// +// Boxes // +////////////////////// + +/obj/item/pizzabox + name = "pizza box" + desc = "A box suited for pizzas." + icon = 'icons/obj/food/pizza.dmi' + icon_state = "pizzabox1" + + var/open = 0 // Is the box open? + var/ismessy = 0 // Fancy mess on the lid + var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza + var/list/boxes = list() // If the boxes are stacked, they come here + var/boxtag = "" + +/obj/item/pizzabox/update_icon() + overlays = list() + + // Set appropriate description + if(open && pizza) + desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." + else if(boxes.len > 0) + desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." + var/obj/item/pizzabox/topbox = boxes[boxes.len] + var/toptag = topbox.boxtag + if(toptag != "") + desc = "[desc] The box on top has a tag, it reads: '[toptag]'." + else + desc = "A box suited for pizzas." + if(boxtag != "") + desc = "[desc] The box has a tag, it reads: '[boxtag]'." + + // Icon states and overlays + if(open) + if(ismessy) + icon_state = "pizzabox_messy" + else + icon_state = "pizzabox_open" + if(pizza) + var/image/pizzaimg = image("food/pizza.dmi", icon_state = pizza.icon_state) + pizzaimg.pixel_y = -3 + overlays += pizzaimg + + return + else + // Stupid code because byondcode sucks + var/doimgtag = 0 + if(boxes.len > 0) + var/obj/item/pizzabox/topbox = boxes[boxes.len] + if(topbox.boxtag != "") + doimgtag = 1 + else + if(boxtag != "") + doimgtag = 1 + if(doimgtag) + var/image/tagimg = image("food/pizza.dmi", icon_state = "pizzabox_tag") + tagimg.pixel_y = boxes.len * 3 + overlays += tagimg + icon_state = "pizzabox[boxes.len+1]" + +/obj/item/pizzabox/attack_hand(mob/user) + if(open && pizza) + user.put_in_hands(pizza) + to_chat(user, "You take the [pizza] out of the [src].") + pizza = null + update_icon() + return + + if(boxes.len > 0) + if(user.is_in_inactive_hand(src)) + ..() + return + var/obj/item/pizzabox/box = boxes[boxes.len] + boxes -= box + user.put_in_hands(box) + to_chat(user, "You remove the topmost [src] from your hand.") + box.update_icon() + update_icon() + return + ..() + +/obj/item/pizzabox/attack_self(mob/user) + if(boxes.len > 0) + return + open = !open + if(open && pizza) + ismessy = 1 + update_icon() + +/obj/item/pizzabox/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pizzabox/)) + var/obj/item/pizzabox/box = I + if(!box.open && !open) + // Make a list of all boxes to be added + var/list/boxestoadd = list() + boxestoadd += box + for(var/obj/item/pizzabox/i in box.boxes) + boxestoadd += i + if((boxes.len+1) + boxestoadd.len <= 5) + user.drop_item() + box.loc = src + box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit + boxes.Add(boxestoadd) + box.update_icon() + update_icon() + to_chat(user, "You put the [box] ontop of the [src]!") + else + to_chat(user, "The stack is too high!") + else + to_chat(user, "Close the [box] first!") + return + + if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name + if(open) + user.drop_item() + I.loc = src + pizza = I + + update_icon() + + to_chat(user, "You put the [I] in the [src]!") + else + to_chat(user, "You try to push the [I] through the lid but it doesn't work!") + return + + if(istype(I, /obj/item/pen/)) + if(open) + return + var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text + var/obj/item/pizzabox/boxtotagto = src + if(boxes.len > 0) + boxtotagto = boxes[boxes.len] + boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) + update_icon() + return + ..() + +/obj/item/pizzabox/margherita/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src) + boxtag = "Margherita Deluxe" + +/obj/item/pizzabox/vegetable/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) + boxtag = "Gourmet Vegatable" + +/obj/item/pizzabox/mushroom/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) + boxtag = "Mushroom Special" + +/obj/item/pizzabox/meat/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) + boxtag = "Meatlover's Supreme" + +/obj/item/pizzabox/hawaiian/New() + pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src) + boxtag = "Hawaiian Feast" \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/foods/sandwiches.dm b/code/modules/food_and_drinks/food/foods/sandwiches.dm new file mode 100644 index 00000000000..a55a92ae3d1 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/sandwiches.dm @@ -0,0 +1,196 @@ + +////////////////////// +// Burgers // +////////////////////// + +/obj/item/reagent_containers/food/snacks/brainburger + name = "brainburger" + desc = "A strange looking burger. It looks almost sentient." + icon_state = "brainburger" + filling_color = "#F2B6EA" + bitesize = 3 + list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/ghostburger + name = "Ghost Burger" + desc = "Spooky! It doesn't look very filling." + icon_state = "ghostburger" + filling_color = "#FFF2FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/human + var/hname = "" + var/job = null + filling_color = "#D63C3C" + +/obj/item/reagent_containers/food/snacks/human/burger + name = "-burger" + desc = "A bloody burger." + icon_state = "hburger" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/cheeseburger + name = "cheeseburger" + desc = "The cheese adds a good flavor." + icon_state = "cheeseburger" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/monkeyburger + name = "burger" + desc = "The cornerstone of every nutritious breakfast." + icon_state = "hburger" + filling_color = "#D63C3C" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/tofuburger + name = "Tofu Burger" + desc = "What.. is that meat?" + icon_state = "tofuburger" + filling_color = "#FFFEE0" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/roburger + name = "roburger" + desc = "The lettuce is the only organic component. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/roburgerbig + name = "roburger" + desc = "This massive patty looks like poison. Beep." + icon_state = "roburger" + filling_color = "#CCCCCC" + volume = 120 + bitesize = 3 + list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/xenoburger + name = "xenoburger" + desc = "Smells caustic. Tastes like heresy." + icon_state = "xburger" + filling_color = "#43DE18" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/clownburger + name = "Clown Burger" + desc = "This tastes funny..." + icon_state = "clownburger" + filling_color = "#FF00FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/mimeburger + name = "Mime Burger" + desc = "Its taste defies language." + icon_state = "mimeburger" + filling_color = "#FFFFFF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/baseballburger + name = "home run baseball burger" + desc = "It's still warm. The steam coming off of it looks like baseball." + icon_state = "baseball" + filling_color = "#CD853F" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/spellburger + name = "Spell Burger" + desc = "This is absolutely Ei Nath." + icon_state = "spellburger" + filling_color = "#D505FF" + bitesize = 3 + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/bigbiteburger + name = "Big Bite Burger" + desc = "Forget the Big Mac. THIS is the future!" + icon_state = "bigbiteburger" + filling_color = "#E3D681" + bitesize = 3 + list_reagents = list("nutriment" = 10, "vitamin" = 2) + +/obj/item/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 = 7 + list_reagents = list("nutriment" = 40, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/jellyburger + name = "Jelly Burger" + desc = "Culinary delight..?" + icon_state = "jellyburger" + filling_color = "#B572AB" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jellyburger/slime + list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/jellyburger/cherry + list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) + + +////////////////////// +// Sandwiches // +////////////////////// + +/obj/item/reagent_containers/food/snacks/sandwich + name = "Sandwich" + desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." + icon_state = "sandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 6, "vitamin" = 1) + +/obj/item/reagent_containers/food/snacks/toastedsandwich + name = "Toasted Sandwich" + desc = "Now if you only had a pepper bar." + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 6, "carbon" = 2) + +/obj/item/reagent_containers/food/snacks/grilledcheese + name = "Grilled Cheese Sandwich" + desc = "Goes great with Tomato soup!" + icon_state = "toastedsandwich" + trash = /obj/item/trash/plate + filling_color = "#D9BE29" + list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? + +/obj/item/reagent_containers/food/snacks/jellysandwich + name = "Jelly Sandwich" + desc = "You wish you had some peanut butter to go with this..." + icon_state = "jellysandwich" + trash = /obj/item/trash/plate + filling_color = "#9E3A78" + bitesize = 3 + +/obj/item/reagent_containers/food/snacks/jellysandwich/slime + list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/jellysandwich/cherry + list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) + +/obj/item/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" + list_reagents = list("nutriment" = 6, "vitamin" = 6) + +/obj/item/reagent_containers/food/snacks/wrap + name = "egg wrap" + desc = "The precursor to Pigs in a Blanket." + icon_state = "wrap" + list_reagents = list("nutriment" = 5) diff --git a/code/modules/food_and_drinks/food/seafood.dm b/code/modules/food_and_drinks/food/foods/seafood.dm similarity index 100% rename from code/modules/food_and_drinks/food/seafood.dm rename to code/modules/food_and_drinks/food/foods/seafood.dm diff --git a/code/modules/food_and_drinks/food/foods/side_dishes.dm b/code/modules/food_and_drinks/food/foods/side_dishes.dm new file mode 100644 index 00000000000..7b563519ca3 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/side_dishes.dm @@ -0,0 +1,105 @@ + +////////////////////// +// Raw // +////////////////////// + +/obj/item/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" + list_reagents = list("plantmatter" = 3) + + +////////////////////// +// Fried // +////////////////////// + +/obj/item/reagent_containers/food/snacks/fries + name = "Space fries" + desc = "AKA: French Fries, Freedom Fries, etc." + icon_state = "fries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 4) + +/obj/item/reagent_containers/food/snacks/cheesyfries + name = "cheesy fries" + desc = "Fries. Covered in cheese. Duh." + icon_state = "cheesyfries" + trash = /obj/item/trash/plate + filling_color = "#EDDD00" + list_reagents = list("nutriment" = 6) + +/obj/item/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" + +/obj/item/reagent_containers/food/snacks/onionrings + name = "onion rings" + desc = "Onion slices coated in batter." + icon_state = "onionrings" + list_reagents = list("nutriment" = 3) + filling_color = "#C0C9A0" + gender = PLURAL + +/obj/item/reagent_containers/food/snacks/carrotfries + name = "carrot fries" + desc = "Tasty fries from fresh carrots." + icon_state = "carrotfries" + trash = /obj/item/trash/plate + filling_color = "#FAA005" + list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) + + +////////////////////// +// Misc // +////////////////////// + +/obj/item/reagent_containers/food/snacks/beans + name = "tin of beans" + desc = "Musical fruit in a slightly less musical container." + icon_state = "beans" + list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) + +/obj/item/reagent_containers/food/snacks/mashed_potatoes //mashed taters + name = "mashed potatoes" + desc = "Some soft, creamy, and irresistible mashed potatoes." + icon_state = "mashedtaters" + trash = /obj/item/trash/plate + filling_color = "#D6D9C1" + list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/stuffing + name = "Stuffing" + desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" + icon_state = "stuffing" + filling_color = "#C9AC83" + list_reagents = list("nutriment" = 3) + +/obj/item/reagent_containers/food/snacks/loadedbakedpotato + name = "loaded baked potato" + desc = "Totally baked." + icon_state = "loadedbakedpotato" + filling_color = "#9C7A68" + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/boiledrice + name = "Boiled Rice" + desc = "A boring dish of boring rice." + icon_state = "boiledrice" + trash = /obj/item/trash/snack_bowl + filling_color = "#FFFBDB" + list_reagents = list("nutriment" = 5, "vitamin" = 1) + + +/obj/item/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" diff --git a/code/modules/food_and_drinks/food/foods/soups.dm b/code/modules/food_and_drinks/food/foods/soups.dm new file mode 100644 index 00000000000..76e4d752a41 --- /dev/null +++ b/code/modules/food_and_drinks/food/foods/soups.dm @@ -0,0 +1,166 @@ + +////////////////////// +// Soups // +////////////////////// + +/obj/item/reagent_containers/food/snacks/meatballsoup + name = "Meatball soup" + desc = "You've got balls kid, BALLS!" + icon_state = "meatballsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#785210" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/slimesoup + name = "slime soup" + desc = "If no water is available, you may substitute tears." + icon_state = "slimesoup" + filling_color = "#C4DBA0" + bitesize = 5 + list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/bloodsoup + name = "Tomato soup" + desc = "Smells like copper." + icon_state = "tomatosoup" + filling_color = "#FF0000" + bitesize = 5 + list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/clownstears + name = "Clown's Tears" + desc = "Not very funny." + icon_state = "clownstears" + filling_color = "#C4FBFF" + bitesize = 5 + list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) + +/obj/item/reagent_containers/food/snacks/vegetablesoup + name = "Vegetable soup" + desc = "A true vegan meal." //TODO + icon_state = "vegetablesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/nettlesoup + name = "Nettle soup" + desc = "To think, the botanist would've beat you to death with one of these." + icon_state = "nettlesoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#AFC4B5" + bitesize = 5 + list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/mysterysoup + name = "mystery soup" + desc = "The mystery is, why aren't you eating it?" + icon_state = "mysterysoup" + var/extra_reagent = null + bitesize = 5 + list_reagents = list("nutriment" = 6) + +/obj/item/reagent_containers/food/snacks/mysterysoup/New() + ..() + extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") + reagents.add_reagent("[extra_reagent]", 5) + +/obj/item/reagent_containers/food/snacks/wishsoup + name = "Wish Soup" + desc = "I wish this was soup." + icon_state = "wishsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D1F4FF" + bitesize = 5 + list_reagents = list("water" = 10) + +/obj/item/reagent_containers/food/snacks/wishsoup/New() + ..() + if(prob(25)) + desc = "A wish come true!" // hue + reagents.add_reagent("nutriment", 9) + reagents.add_reagent("vitamin", 1) + +/obj/item/reagent_containers/food/snacks/tomatosoup + name = "Tomato Soup" + desc = "Drinking this feels like being a vampire! A tomato vampire..." + icon_state = "tomatosoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#D92929" + bitesize = 5 + list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) + +/obj/item/reagent_containers/food/snacks/milosoup + name = "Milosoup" + desc = "The universe's best soup! Yum!!!" + icon_state = "milosoup" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/mushroomsoup + name = "chantrelle soup" + desc = "A delicious and hearty mushroom soup." + icon_state = "mushroomsoup" + trash = /obj/item/trash/snack_bowl + filling_color = "#E386BF" + bitesize = 5 + list_reagents = list("nutriment" = 8, "vitamin" = 4) + +/obj/item/reagent_containers/food/snacks/beetsoup + name = "beet soup" + desc = "Wait, how do you spell it again..?" + icon_state = "beetsoup" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + filling_color = "#FAC9FF" + list_reagents = list("nutriment" = 7, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/beetsoup/New() + ..() + name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") + + +////////////////////// +// Stews // +////////////////////// + +/obj/item/reagent_containers/food/snacks/stew + name = "Stew" + desc = "A nice and warm stew. Healthy and strong." + icon_state = "stew" + filling_color = "#9E673A" + bitesize = 7 + list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) + +/obj/item/reagent_containers/food/snacks/stewedsoymeat + name = "Stewed Soy Meat" + desc = "Even non-vegetarians will LOVE this!" + icon_state = "stewedsoymeat" + trash = /obj/item/trash/plate + list_reagents = list("nutriment" = 8) + + +////////////////////// +// Chili // +////////////////////// + +/obj/item/reagent_containers/food/snacks/hotchili + name = "Hot Chili" + desc = "A five alarm Texan Chili!" + icon_state = "hotchili" + trash = /obj/item/trash/snack_bowl + filling_color = "#FF3C00" + bitesize = 5 + list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) + +/obj/item/reagent_containers/food/snacks/coldchili + name = "Cold Chili" + desc = "This slush is barely a liquid!" + icon_state = "coldchili" + filling_color = "#2B00FF" + trash = /obj/item/trash/snack_bowl + bitesize = 5 + list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) diff --git a/code/modules/food_and_drinks/food/meat.dm b/code/modules/food_and_drinks/food/meat.dm deleted file mode 100644 index 7940050b35a..00000000000 --- a/code/modules/food_and_drinks/food/meat.dm +++ /dev/null @@ -1,55 +0,0 @@ -/obj/item/reagent_containers/food/snacks/meat - name = "meat" - desc = "A slab of meat" - icon_state = "meat" - health = 180 - filling_color = "#FF1C1C" - bitesize = 3 - list_reagents = list("protein" = 3) - -/obj/item/reagent_containers/food/snacks/meat/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/kitchen/knife) || istype(W, /obj/item/scalpel)) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - new /obj/item/reagent_containers/food/snacks/rawcutlet(src) - to_chat(user, "You cut the meat in thin strips.") - qdel(src) - else - ..() - -/obj/item/reagent_containers/food/snacks/meat/syntiflesh - name = "synthetic meat" - desc = "A synthetic slab of flesh." - -/obj/item/reagent_containers/food/snacks/meat/human - name = "-meat" - var/subjectname = "" - var/subjectjob = null - -/obj/item/reagent_containers/food/snacks/meat/slab/meatproduct - name = "meat product" - desc = "A slab of station reclaimed and chemically processed meat product." - -/obj/item/reagent_containers/food/snacks/meat/monkey - //same as plain meat - -/obj/item/reagent_containers/food/snacks/meat/corgi - name = "Corgi meat" - desc = "Tastes like... well you know..." - -/obj/item/reagent_containers/food/snacks/meat/pug - name = "Pug meat" - desc = "Tastes like... well you know..." - -/obj/item/reagent_containers/food/snacks/meat/ham - name = "Ham" - desc = "Taste like bacon." - list_reagents = list("protein" = 3, "porktonium" = 10) - -/obj/item/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/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index f690e5f4231..4803405520a 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -271,806 +271,6 @@ // bitesize = 3 //This is the amount each bite consumes. - - -/obj/item/reagent_containers/food/snacks/aesirsalad - name = "Aesir salad" - desc = "Probably too incredible for mortal men to fully enjoy." - icon_state = "aesirsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#468C00" - bitesize = 3 - list_reagents = list("nutriment" = 8, "omnizine" = 8, "vitamin" = 6) - -/obj/item/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" - junkiness = 20 - list_reagents = list("nutriment" = 1, "sodiumchloride" = 1, "sugar" = 3) - -/obj/item/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) - -/obj/item/reagent_containers/food/snacks/cookie - name = "cookie" - desc = "COOKIE!!!" - icon_state = "COOKIE!!!" - bitesize = 1 - filling_color = "#DBC94F" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/chocolatebar - name = "Chocolate Bar" - desc = "Such sweet, fattening food." - icon_state = "chocolatebar" - filling_color = "#7D5F46" - list_reagents = list("nutriment" = 2, "sugar" = 2, "cocoa" = 2) - -/obj/item/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" - list_reagents = list("chocolate" = 5) - -/obj/item/reagent_containers/food/snacks/chocolateegg - name = "Chocolate Egg" - desc = "Such sweet, fattening food." - icon_state = "chocolateegg" - filling_color = "#7D5F46" - list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2) - -/obj/item/reagent_containers/food/snacks/donut - name = "donut" - desc = "Goes great with Robust Coffee." - icon_state = "donut1" - bitesize = 5 - list_reagents = list("nutriment" = 3, "sugar" = 2) - var/extra_reagent = null - filling_color = "#D2691E" - var/randomized_sprinkles = 1 - -/obj/item/reagent_containers/food/snacks/donut/New() - ..() - if(randomized_sprinkles && prob(30)) - icon_state = "donut2" - name = "frosted donut" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/sprinkles - name = "frosted donut" - icon_state = "donut2" - list_reagents = list("nutriment" = 3, "sugar" = 2, "spinkles" = 2) - filling_color = "#FF69B4" - randomized_sprinkles = 0 - -/obj/item/reagent_containers/food/snacks/donut/chaos - name = "chaos donut" - desc = "Like life, it never quite tastes the same." - bitesize = 10 - -/obj/item/reagent_containers/food/snacks/donut/chaos/New() - ..() - 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" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/jelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "berryjuice" - -/obj/item/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" - reagents.add_reagent("sprinkles", 2) - filling_color = "#FF69B4" - -/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "slimejelly" - -/obj/item/reagent_containers/food/snacks/donut/jelly/cherryjelly - name = "jelly donut" - desc = "You jelly?" - icon_state = "jdonut1" - extra_reagent = "cherryjelly" - -/obj/item/reagent_containers/food/snacks/egg - name = "egg" - desc = "An egg!" - icon_state = "egg" - filling_color = "#FDFFD1" - list_reagents = list("protein" = 1, "egg" = 5) - -/obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) - ..() - var/turf/T = get_turf(hit_atom) - new/obj/effect/decal/cleanable/egg_smudge(T) - if(reagents) - reagents.reaction(hit_atom, TOUCH) - qdel(src) - -/obj/item/reagent_containers/food/snacks/egg/attackby(obj/item/W, mob/user, params) - if(istype( W, /obj/item/toy/crayon )) - var/obj/item/toy/crayon/C = W - var/clr = C.colourName - - if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - to_chat(usr, "The egg refuses to take on this color!") - return - - to_chat(usr, "You color \the [src] [clr]") - icon_state = "egg-[clr]" - item_color = clr - else - ..() - -/obj/item/reagent_containers/food/snacks/egg/blue - icon_state = "egg-blue" - item_color = "blue" - -/obj/item/reagent_containers/food/snacks/egg/green - icon_state = "egg-green" - item_color = "green" - -/obj/item/reagent_containers/food/snacks/egg/mime - icon_state = "egg-mime" - item_color = "mime" - -/obj/item/reagent_containers/food/snacks/egg/orange - icon_state = "egg-orange" - item_color = "orange" - -/obj/item/reagent_containers/food/snacks/egg/purple - icon_state = "egg-purple" - item_color = "purple" - -/obj/item/reagent_containers/food/snacks/egg/rainbow - icon_state = "egg-rainbow" - item_color = "rainbow" - -/obj/item/reagent_containers/food/snacks/egg/red - icon_state = "egg-red" - item_color = "red" - -/obj/item/reagent_containers/food/snacks/egg/yellow - icon_state = "egg-yellow" - item_color = "yellow" - -/obj/item/reagent_containers/food/snacks/friedegg - name = "Fried egg" - desc = "A fried egg, with a touch of salt and pepper." - icon_state = "friedegg" - filling_color = "#FFDF78" - bitesize = 1 - list_reagents = list("nutriment" = 3, "egg" = 5) - -/obj/item/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, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/organ - - name = "organ" - desc = "It's good for you." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - filling_color = "#E00D34" - bitesize = 3 - list_reagents = list("protein" = 4, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/appendix -//yes, this is the same as meat. I might do something different in future - name = "appendix" - desc = "An appendix which looks perfectly healthy." - icon = 'icons/obj/surgery.dmi' - icon_state = "appendix" - filling_color = "#E00D34" - bitesize = 3 - list_reagents = list("protein" = 3, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/appendix/inflamed - name = "inflamed appendix" - desc = "An appendix which appears to be inflamed." - icon_state = "appendixinflamed" - filling_color = "#E00D7A" - -/obj/item/reagent_containers/food/snacks/tofu - name = "Tofu" - icon_state = "tofu" - desc = "We all love tofu." - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("plantmatter" = 2) - -/obj/item/reagent_containers/food/snacks/fried_tofu - name = "Fried Tofu" - icon_state = "tofu" - desc = "Proof that even vegetarians crave unhealthy foods." - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("plantmatter" = 3) - -/obj/item/reagent_containers/food/snacks/tofurkey - name = "Tofurkey" - desc = "A fake turkey made from tofu." - icon_state = "tofurkey" - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 12, "ether" = 3) - -/obj/item/reagent_containers/food/snacks/stuffing - name = "Stuffing" - desc = "Moist, peppery breadcrumbs for filling the body cavities of dead birds. Dig in!" - icon_state = "stuffing" - filling_color = "#C9AC83" - list_reagents = list("nutriment" = 3) - -/obj/item/reagent_containers/food/snacks/hugemushroomslice - name = "huge mushroom slice" - desc = "A slice from a huge mushroom." - icon_state = "hugemushroomslice" - filling_color = "#E0D7C5" - bitesize = 6 - list_reagents = list("plantmatter" = 3, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/tomatomeat - name = "tomato slice" - desc = "A slice from a huge tomato." - icon_state = "tomatomeat" - filling_color = "#DB0000" - bitesize = 6 - list_reagents = list("protein" = 2) - -/obj/item/reagent_containers/food/snacks/bearmeat - name = "bear meat" - desc = "A very manly slab of meat." - icon_state = "bearmeat" - filling_color = "#DB0000" - bitesize = 3 - list_reagents = list("protein" = 12, "morphine" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/xenomeat - name = "meat" - desc = "A slab of meat." - icon_state = "xenomeat" - filling_color = "#43DE18" - bitesize = 6 - list_reagents = list("protein" = 3, "vitamin" = 1) - -/obj/item/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, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/lizardmeat - name = "mutant lizard meat" - desc = "Seems to be a slab of meat from some mutant lizard thing?" - icon_state = "xenomeat" - filling_color = "#43DE18" - bitesize = 3 - list_reagents = list("protein" = 3, "toxin" = 3) - -/obj/item/reagent_containers/food/snacks/spiderleg - 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" - list_reagents = list("protein" = 2, "toxin" = 2) - -/obj/item/reagent_containers/food/snacks/meatball - name = "Meatball" - desc = "A great meal all round." - icon_state = "meatball" - filling_color = "#DB0000" - list_reagents = list("protein" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/sausage - name = "Sausage" - desc = "A piece of mixed, long meat." - icon_state = "sausage" - filling_color = "#DB0000" - list_reagents = list("protein" = 6, "vitamin" = 1, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/donkpocket - name = "Donk-pocket" - desc = "The food of choice for the seasoned traitor." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket - name = "Warm Donk-pocket" - desc = "The food of choice for the seasoned traitor." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket/Post_Consume(mob/living/M) - M.reagents.add_reagent("omnizine", 15) - -/obj/item/reagent_containers/food/snacks/warmdonkpocket_weak - name = "Lightly Warm Donk-pocket" - desc = "The food of choice for the seasoned traitor. This one is lukewarm." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - list_reagents = list("nutriment" = 4, "weak_omnizine" = 3) - -/obj/item/reagent_containers/food/snacks/syndidonkpocket - name = "Donk-pocket" - desc = "This donk-pocket is emitting a small amount of heat." - icon_state = "donkpocket" - filling_color = "#DEDEAB" - bitesize = 100 //nom the whole thing at once. - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/syndidonkpocket/Post_Consume(mob/living/M) - M.reagents.add_reagent("omnizine", 15) - M.reagents.add_reagent("teporone", 15) - M.reagents.add_reagent("synaptizine", 15) - M.reagents.add_reagent("salglu_solution", 15) - M.reagents.add_reagent("salbutamol", 15) - M.reagents.add_reagent("methamphetamine", 15) - -/obj/item/reagent_containers/food/snacks/brainburger - name = "brainburger" - desc = "A strange looking burger. It looks almost sentient." - icon_state = "brainburger" - filling_color = "#F2B6EA" - bitesize = 3 - list_reagents = list("nutriment" = 6, "prions" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/ghostburger - name = "Ghost Burger" - desc = "Spooky! It doesn't look very filling." - icon_state = "ghostburger" - filling_color = "#FFF2FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/human - var/hname = "" - var/job = null - filling_color = "#D63C3C" - -/obj/item/reagent_containers/food/snacks/human/burger - name = "-burger" - desc = "A bloody burger." - icon_state = "hburger" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/cheeseburger - name = "cheeseburger" - desc = "The cheese adds a good flavor." - icon_state = "cheeseburger" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/monkeyburger - name = "burger" - desc = "The cornerstone of every nutritious breakfast." - icon_state = "hburger" - filling_color = "#D63C3C" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/tofuburger - name = "Tofu Burger" - desc = "What.. is that meat?" - icon_state = "tofuburger" - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/roburger - name = "roburger" - desc = "The lettuce is the only organic component. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - bitesize = 3 - list_reagents = list("nutriment" = 6, "nanomachines" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/roburgerbig - name = "roburger" - desc = "This massive patty looks like poison. Beep." - icon_state = "roburger" - filling_color = "#CCCCCC" - volume = 120 - bitesize = 3 - list_reagents = list("nutriment" = 6, "nanomachines" = 70, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/xenoburger - name = "xenoburger" - desc = "Smells caustic. Tastes like heresy." - icon_state = "xburger" - filling_color = "#43DE18" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/clownburger - name = "Clown Burger" - desc = "This tastes funny..." - icon_state = "clownburger" - filling_color = "#FF00FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/mimeburger - name = "Mime Burger" - desc = "Its taste defies language." - icon_state = "mimeburger" - filling_color = "#FFFFFF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/baseballburger - name = "home run baseball burger" - desc = "It's still warm. The steam coming off of it looks like baseball." - icon_state = "baseball" - filling_color = "#CD853F" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/omelette - name = "Omelette Du Fromage" - desc = "That's all you can say!" - icon_state = "omelette" - trash = /obj/item/trash/plate - filling_color = "#FFF9A8" - list_reagents = list("nutriment" = 8, "vitamin" = 1) - bitesize = 1 - -/obj/item/reagent_containers/food/snacks/muffin - name = "Muffin" - desc = "A delicious and spongy little cake." - icon_state = "muffin" - filling_color = "#E0CF9B" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/pie - name = "Banana Cream Pie" - desc = "Just like back home, on clown planet! HONK!" - icon_state = "pie" - trash = /obj/item/trash/plate - filling_color = "#FBFFB8" - bitesize = 3 - list_reagents = list("nutriment" = 6, "banana" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/pie/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/pie_smudge(loc) - visible_message("[src] splats.","You hear a splat.") - qdel(src) - -/obj/item/reagent_containers/food/snacks/berryclafoutis - name = "Berry Clafoutis" - desc = "No black birds, this is a good sign." - icon_state = "berryclafoutis" - trash = /obj/item/trash/plate - bitesize = 3 - list_reagents = list("nutriment" = 10, "berryjuice" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/waffles - name = "waffles" - desc = "Mmm, waffles." - icon_state = "waffles" - trash = /obj/item/trash/waffles - filling_color = "#E6DEB5" - list_reagents = list("nutriment" = 8, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/eggplantparm - name = "Eggplant Parmigiana" - desc = "The only good recipe for eggplant." - icon_state = "eggplantparm" - trash = /obj/item/trash/plate - filling_color = "#4D2F5E" - list_reagents = list("nutriment" = 6, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/soylentgreen - name = "Soylent Green" - desc = "Not made of people. Honest." //Totally people. - icon_state = "soylent_green" - trash = /obj/item/trash/waffles - filling_color = "#B8E6B5" - list_reagents = list("nutriment" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/soylentviridians - name = "Soylent Virdians" - desc = "Not made of people. Honest." //Actually honest for once. - icon_state = "soylent_yellow" - trash = /obj/item/trash/waffles - filling_color = "#E6FA61" - list_reagents = list("nutriment" = 10, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/meatpie - name = "Meat-pie" - icon_state = "meatpie" - desc = "An old barber recipe, very delicious!" - trash = /obj/item/trash/plate - filling_color = "#948051" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/tofupie - name = "Tofu-pie" - icon_state = "meatpie" - desc = "A delicious tofu pie." - trash = /obj/item/trash/plate - filling_color = "#FFFEE0" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/amanita_pie - name = "amanita pie" - desc = "Sweet and tasty poison pie." - icon_state = "amanita_pie" - filling_color = "#FFCCCC" - bitesize = 4 - list_reagents = list("nutriment" = 6, "amanitin" = 3, "psilocybin" = 1, "vitamin" = 4) - -/obj/item/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 = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/plump_pie/New() - ..() - if(prob(10)) - name = "exceptional plump pie" - desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" // What - reagents.add_reagent("omnizine", 5) - -/obj/item/reagent_containers/food/snacks/xemeatpie - name = "Xeno-pie" - icon_state = "xenomeatpie" - desc = "A delicious meatpie. Probably heretical." - trash = /obj/item/trash/plate - filling_color = "#43DE18" - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/wingfangchu - name = "Wing Fang Chu" - desc = "A savory dish of alien wing wang in soy." - icon_state = "wingfangchu" - trash = /obj/item/trash/snack_bowl - filling_color = "#43DE18" - list_reagents = list("nutriment" = 6, "soysauce" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/human/kabob - name = "-kabob" - icon_state = "kabob" - desc = "A human meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/monkeykabob - name = "Meat-kabob" - icon_state = "kabob" - desc = "Delicious meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#A85340" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/tofukabob - name = "Tofu-kabob" - icon_state = "kabob" - desc = "Vegan meat, on a stick." - trash = /obj/item/stack/rods - filling_color = "#FFFEE0" - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/popcorn - name = "Popcorn" - desc = "Now let's find some cinema." - icon_state = "popcorn" - trash = /obj/item/trash/popcorn - var/unpopped = 0 - filling_color = "#FFFAD4" - bitesize = 0.1 //this snack is supposed to be eating during looooong time. And this it not dinner food! --rastaf0 - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/popcorn/New() - ..() - unpopped = rand(1,10) - -/obj/item/reagent_containers/food/snacks/popcorn/On_Consume(mob/M, mob/user) - if(prob(unpopped)) //lol ...what's the point? - to_chat(user, "You bite down on an un-popped kernel!") - unpopped = max(0, unpopped-1) - ..() - -/obj/item/reagent_containers/food/snacks/sosjerky - name = "Scaredy's Private Reserve Beef Jerky" - icon_state = "sosjerky" - desc = "Beef jerky made from the finest space cows." - trash = /obj/item/trash/sosjerky - filling_color = "#631212" - junkiness = 25 - list_reagents = list("protein" = 1, "sugar" = 3) - -/obj/item/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/reagent_containers/food/snacks/pistachios - name = "Pistachios" - icon_state = "pistachios" - desc = "A snack of deliciously salted pistachios. A perfectly valid choice..." - trash = /obj/item/trash/pistachios - filling_color = "#BAD145" - junkiness = 20 - list_reagents = list("plantmatter" = 2, "sodiumchloride" = 1, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/no_raisin - name = "4no Raisins" - icon_state = "4no_raisins" - desc = "Best raisins in the universe. Not sure why." - trash = /obj/item/trash/raisins - filling_color = "#343834" - junkiness = 25 - list_reagents = list("plantmatter" = 2, "sugar" = 4) - -/obj/item/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/reagent_containers/food/snacks/spacetwinkie - name = "Space Twinkie" - icon_state = "space_twinkie" - desc = "Guaranteed to survive longer then you will." - filling_color = "#FFE591" - junkiness = 25 - list_reagents = list("sugar" = 4) - -/obj/item/reagent_containers/food/snacks/cheesiehonkers - name = "Cheesie Honkers" - icon_state = "cheesie_honkers" - desc = "Bite sized cheesie snacks that will honk all over your mouth." - trash = /obj/item/trash/cheesie - filling_color = "#FFA305" - junkiness = 25 - list_reagents = list("nutriment" = 1, "fake_cheese" = 2, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/chinese/chowmein - name = "chow mein" - desc = "What is in this anyways?" - icon_state = "chinese1" - junkiness = 25 - list_reagents = list("nutriment" = 1, "beans" = 3, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/chinese/sweetsourchickenball - name = "Sweet & Sour Chicken Balls" - desc = "Is this chicken cooked? The odds are better than wok paper scissors." - icon_state = "chickenball" - junkiness = 25 - list_reagents = list("nutriment" = 2, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/chinese/tao - name = "Admiral Yamamoto carp" - desc = "Tastes like chicken." - icon_state = "chinese2" - junkiness = 25 - list_reagents = list("nutriment" = 1, "protein" = 1, "msg" = 4, "sugar" = 4) - -/obj/item/reagent_containers/food/snacks/chinese/newdles - name = "chinese newdles" - desc = "Made fresh, weekly!" - icon_state = "chinese3" - junkiness = 25 - list_reagents = list("nutriment" = 1, "msg" = 4, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/chinese/rice - name = "fried rice" - desc = "A timeless classic." - icon_state = "chinese4" - junkiness = 20 - list_reagents = list("nutriment" = 1, "rice" = 3, "msg" = 4, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/syndicake - name = "Syndi-Cakes" - icon_state = "syndi_cakes" - desc = "An extremely moist snack cake that tastes just as good after being nuked." - filling_color = "#FF5D05" - trash = /obj/item/trash/syndi_cakes - bitesize = 3 - list_reagents = list("nutriment" = 4, "salglu_solution" = 5) - -/obj/item/reagent_containers/food/snacks/loadedbakedpotato - name = "Loaded Baked Potato" - desc = "Totally baked." - icon_state = "loadedbakedpotato" - filling_color = "#9C7A68" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/fries - name = "Space Fries" - desc = "AKA: French Fries, Freedom Fries, etc." - icon_state = "fries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 4) - -/obj/item/reagent_containers/food/snacks/soydope - name = "Soy Dope" - desc = "Dope from a soy." - icon_state = "soydope" - trash = /obj/item/trash/plate - filling_color = "#C4BF76" - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/spaghetti - name = "Spaghetti" - desc = "A bundle of raw spaghetti." - icon_state = "spaghetti" - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 1, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/macaroni - name = "Macaroni twists" - desc = "These are little twists of raw macaroni." - icon_state = "macaroni" - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 1, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/macncheese - name = "Macaroni cheese" - desc = "One of the most comforting foods in the world. Apparently." - trash = /obj/item/trash/snack_bowl - icon_state = "macncheese" - filling_color = "#ffe45d" - list_reagents = list("nutriment" = 5, "vitamin" = 2, "cheese" = 4) - -/obj/item/reagent_containers/food/snacks/cheesyfries - name = "Cheesy Fries" - desc = "Fries. Covered in cheese. Duh." - icon_state = "cheesyfries" - trash = /obj/item/trash/plate - filling_color = "#EDDD00" - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/fortunecookie - name = "Fortune cookie" - desc = "A true prophecy in each cookie!" - icon_state = "fortune_cookie" - filling_color = "#E8E79E" - list_reagents = list("nutriment" = 3) - /obj/item/reagent_containers/food/snacks/badrecipe name = "Burned mess" desc = "Someone should be demoted from chef for this." @@ -1084,1347 +284,7 @@ cooktype["grilled"] = 1 cooktype["deep fried"] = 1 -/obj/item/reagent_containers/food/snacks/meatsteak - name = "Meat steak" - desc = "A piece of hot spicy meat." - icon_state = "meatstake" - trash = /obj/item/trash/plate - filling_color = "#7A3D11" - bitesize = 3 - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/spacylibertyduff - name = "Spacy Liberty Duff" - desc = "Jello gelatin, from Alfred Hubbard's cookbook." - icon_state = "spacylibertyduff" - trash = /obj/item/trash/snack_bowl - filling_color = "#42B873" - bitesize = 3 - list_reagents = list("nutriment" = 6, "psilocybin" = 6) - -/obj/item/reagent_containers/food/snacks/amanitajelly - name = "Amanita Jelly" - desc = "Looks curiously toxic." - icon_state = "amanitajelly" - trash = /obj/item/trash/snack_bowl - filling_color = "#ED0758" - bitesize = 3 - list_reagents = list("nutriment" = 6, "amanitin" = 6, "psilocybin" = 3) - -/obj/item/reagent_containers/food/snacks/poppypretzel - name = "Poppy pretzel" - desc = "It's all twisted up!" - icon_state = "poppypretzel" - filling_color = "#916E36" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/meatballsoup - name = "Meatball soup" - desc = "You've got balls kid, BALLS!" - icon_state = "meatballsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#785210" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/slimesoup - name = "slime soup" - desc = "If no water is available, you may substitute tears." - icon_state = "slimesoup" - filling_color = "#C4DBA0" - bitesize = 5 - list_reagents = list("nutriment" = 5, "slimejelly" = 5, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/bloodsoup - name = "Tomato soup" - desc = "Smells like copper." - icon_state = "tomatosoup" - filling_color = "#FF0000" - bitesize = 5 - list_reagents = list("nutriment" = 2, "blood" = 10, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/clownstears - name = "Clown's Tears" - desc = "Not very funny." - icon_state = "clownstears" - filling_color = "#C4FBFF" - bitesize = 5 - list_reagents = list("nutriment" = 4, "banana" = 5, "water" = 5, "vitamin" = 8) - -/obj/item/reagent_containers/food/snacks/vegetablesoup - name = "Vegetable soup" - desc = "A true vegan meal." //TODO - icon_state = "vegetablesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/nettlesoup - name = "Nettle soup" - desc = "To think, the botanist would've beat you to death with one of these." - icon_state = "nettlesoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#AFC4B5" - bitesize = 5 - list_reagents = list("nutriment" = 8, "water" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/mysterysoup - name = "mystery soup" - desc = "The mystery is, why aren't you eating it?" - icon_state = "mysterysoup" - var/extra_reagent = null - bitesize = 5 - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/mysterysoup/New() - ..() - extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") - reagents.add_reagent("[extra_reagent]", 5) - -/obj/item/reagent_containers/food/snacks/wishsoup - name = "Wish Soup" - desc = "I wish this was soup." - icon_state = "wishsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D1F4FF" - bitesize = 5 - list_reagents = list("water" = 10) - -/obj/item/reagent_containers/food/snacks/wishsoup/New() - ..() - if(prob(25)) - desc = "A wish come true!" // hue - reagents.add_reagent("nutriment", 9) - reagents.add_reagent("vitamin", 1) - -/obj/item/reagent_containers/food/snacks/hotchili - name = "Hot Chili" - desc = "A five alarm Texan Chili!" - icon_state = "hotchili" - trash = /obj/item/trash/snack_bowl - filling_color = "#FF3C00" - bitesize = 5 - list_reagents = list("nutriment" = 5, "capsaicin" = 1, "tomatojuice" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/coldchili - name = "Cold Chili" - desc = "This slush is barely a liquid!" - icon_state = "coldchili" - filling_color = "#2B00FF" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - list_reagents = list("nutriment" = 5, "frostoil" = 1, "tomatojuice" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/raw_bacon - name = "raw bacon" - desc = "It's fleshy and pink!" - icon_state = "raw_bacon" - list_reagents = list("nutriment" = 1, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/bacon - name = "bacon" - desc = "It looks juicy and tastes amazing!" - icon_state = "bacon2" - list_reagents = list("nutriment" = 4, "porktonium" = 10, "msg" = 4) - -/obj/item/reagent_containers/food/snacks/telebacon - name = "Tele Bacon" - desc = "It tastes a little odd but it is still delicious." - icon_state = "bacon" - var/obj/item/radio/beacon/bacon/baconbeacon - list_reagents = list("nutriment" = 4, "porktonium" = 10) - -/obj/item/reagent_containers/food/snacks/telebacon/New() - ..() - baconbeacon = new /obj/item/radio/beacon/bacon(src) - -/obj/item/reagent_containers/food/snacks/telebacon/On_Consume(mob/M, mob/user) - if(!reagents.total_volume) - baconbeacon.loc = user - baconbeacon.digest_delay() - - -/obj/item/reagent_containers/food/snacks/monkeycube - name = "monkey cube" - desc = "Just add water!" - icon_state = "monkeycube" - bitesize = 12 - filling_color = "#ADAC7F" - var/monkey_type = "Monkey" - list_reagents = list("nutriment" = 2) - -/obj/item/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature) - if(volume >= 5) - return Expand() - -/obj/item/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source) - user.drop_item() - forceMove(get_turf(source)) - return 1 - -/obj/item/reagent_containers/food/snacks/monkeycube/proc/Expand() - if(!QDELETED(src)) - visible_message("[src] expands!") - if(fingerprintslast) - log_game("Cube ([monkey_type]) inflated, last touched by: " + fingerprintslast) - else - log_game("Cube ([monkey_type]) inflated, last touched by: NO_DATA") - var/mob/living/carbon/human/creature = new /mob/living/carbon/human(get_turf(src)) - if(LAZYLEN(fingerprintshidden)) - creature.fingerprintshidden = fingerprintshidden.Copy() - creature.set_species(monkey_type) - qdel(src) - -/obj/item/reagent_containers/food/snacks/monkeycube/farwacube - name = "farwa cube" - monkey_type = "Farwa" - -/obj/item/reagent_containers/food/snacks/monkeycube/wolpincube - name = "wolpin cube" - monkey_type = "Wolpin" - -/obj/item/reagent_containers/food/snacks/monkeycube/stokcube - name = "stok cube" - monkey_type = "Stok" - -/obj/item/reagent_containers/food/snacks/monkeycube/neaeracube - name = "neaera cube" - monkey_type = "Neara" - - -/obj/item/reagent_containers/food/snacks/spellburger - name = "Spell Burger" - desc = "This is absolutely Ei Nath." - icon_state = "spellburger" - filling_color = "#D505FF" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/bigbiteburger - name = "Big Bite Burger" - desc = "Forget the Big Mac. THIS is the future!" - icon_state = "bigbiteburger" - filling_color = "#E3D681" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/enchiladas - name = "Enchiladas" - desc = "Viva La Mexico!" - icon_state = "enchiladas" - trash = /obj/item/trash/tray - filling_color = "#A36A1F" - bitesize = 4 - list_reagents = list("nutriment" = 8, "capsaicin" = 6) - -/obj/item/reagent_containers/food/snacks/burrito - name = "Burrito" - desc = "Meat, beans, cheese, and rice wrapped up as an easy-to-hold meal." - icon_state = "burrito" - trash = /obj/item/trash/plate - filling_color = "#A36A1F" - list_reagents = list("nutriment" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/chimichanga - name = "Chimichanga" - desc = "Time to eat a chimi-f***ing-changa." - icon_state = "chimichanga" - trash = /obj/item/trash/plate - filling_color = "#A36A1F" - list_reagents = list("omnizine" = 4, "cheese" = 2) //Deadpool reference. Deal with it. - -/obj/item/reagent_containers/food/snacks/monkeysdelight - name = "monkey's Delight" - desc = "Eeee Eee!" - icon_state = "monkeysdelight" - trash = /obj/item/trash/tray - filling_color = "#5C3C11" - bitesize = 6 - list_reagents = list("nutriment" = 10, "banana" = 5, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/baguette - name = "Baguette" - desc = "Bon appetit!" - icon_state = "baguette" - filling_color = "#E3D796" - bitesize = 3 - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/sandwich - name = "Sandwich" - desc = "A grand creation of meat, cheese, bread, and several leaves of lettuce! Arthur Dent would be proud." - icon_state = "sandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/toastedsandwich - name = "Toasted Sandwich" - desc = "Now if you only had a pepper bar." - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 6, "carbon" = 2) - -/obj/item/reagent_containers/food/snacks/grilledcheese - name = "Grilled Cheese Sandwich" - desc = "Goes great with Tomato soup!" - icon_state = "toastedsandwich" - trash = /obj/item/trash/plate - filling_color = "#D9BE29" - list_reagents = list("nutriment" = 7, "vitamin" = 1) //why make a regualr sandwhich when you can make grilled cheese, with this nutriment value? - -/obj/item/reagent_containers/food/snacks/tomatosoup - name = "Tomato Soup" - desc = "Drinking this feels like being a vampire! A tomato vampire..." - icon_state = "tomatosoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#D92929" - bitesize = 5 - list_reagents = list("nutriment" = 5, "tomatojuice" = 10, "vitamin" = 3) - -/obj/item/reagent_containers/food/snacks/rofflewaffles - name = "Roffle Waffles" - desc = "Waffles from Roffle. Co." - icon_state = "rofflewaffles" - trash = /obj/item/trash/waffles - filling_color = "#FF00F7" - bitesize = 4 - list_reagents = list("nutriment" = 8, "psilocybin" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/stew - name = "Stew" - desc = "A nice and warm stew. Healthy and strong." - icon_state = "stew" - filling_color = "#9E673A" - bitesize = 7 - list_reagents = list("nutriment" = 10, "oculine" = 5, "tomatojuice" = 5, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/jelliedtoast - name = "Jellied Toast" - desc = "A slice of bread covered with delicious jam." - icon_state = "jellytoast" - trash = /obj/item/trash/plate - filling_color = "#B572AB" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jelliedtoast/cherry - list_reagents = list("nutriment" = 1, "cherryjelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jelliedtoast/slime - list_reagents = list("nutriment" = 1, "slimejelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellyburger - name = "Jelly Burger" - desc = "Culinary delight..?" - icon_state = "jellyburger" - filling_color = "#B572AB" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jellyburger/slime - list_reagents = list("nutriment" = 6, "slimejelly" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/jellyburger/cherry - list_reagents = list("nutriment" = 6, "cherryjelly" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/milosoup - name = "Milosoup" - desc = "The universe's best soup! Yum!!!" - icon_state = "milosoup" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/stewedsoymeat - name = "Stewed Soy Meat" - desc = "Even non-vegetarians will LOVE this!" - icon_state = "stewedsoymeat" - trash = /obj/item/trash/plate - list_reagents = list("nutriment" = 8) - -/obj/item/reagent_containers/food/snacks/boiledspaghetti - name = "Boiled Spaghetti" - desc = "A plain dish of noodles, this sucks." - icon_state = "spaghettiboiled" - trash = /obj/item/trash/plate - filling_color = "#FCEE81" - list_reagents = list("nutriment" = 2, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/boiledrice - name = "Boiled Rice" - desc = "A boring dish of boring rice." - icon_state = "boiledrice" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - list_reagents = list("nutriment" = 5, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/ricepudding - name = "Rice Pudding" - desc = "Where's the Jam!" - icon_state = "rpudding" - trash = /obj/item/trash/snack_bowl - filling_color = "#FFFBDB" - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/pastatomato - name = "spaghetti" - desc = "Spaghetti and crushed tomatoes. Just like your abusive father used to make!" - icon_state = "pastatomato" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - bitesize = 4 - list_reagents = list("nutriment" = 6, "tomatojuice" = 10, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/meatballspaghetti - name = "spaghetti & Meatballs" - desc = "Now thats a nic'e meatball!" - icon_state = "meatballspaghetti" - trash = /obj/item/trash/plate - filling_color = "#DE4545" - list_reagents = list("nutriment" = 8, "synaptizine" = 5, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/spesslaw - name = "Spesslaw" - desc = "A lawyer's favourite." - icon_state = "spesslaw" - filling_color = "#DE4545" - list_reagents = list("nutriment" = 8, "synaptizine" = 10, "vitamin" = 6) - -/obj/item/reagent_containers/food/snacks/poppypretzel - name = "Poppy Pretzel" - desc = "A large soft pretzel full of POP!" - icon_state = "poppypretzel" - filling_color = "#AB7D2E" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/carrotfries - name = "Carrot Fries" - desc = "Tasty fries from fresh carrots." - icon_state = "carrotfries" - trash = /obj/item/trash/plate - filling_color = "#FAA005" - list_reagents = list("plantmatter" = 3, "oculine" = 3, "vitamin" = 2) - -/obj/item/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 = 7 - list_reagents = list("nutriment" = 40, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/candiedapple - name = "Candied Apple" - desc = "An apple coated in sugary sweetness." - icon_state = "candiedapple" - filling_color = "#F21873" - bitesize = 3 - list_reagents = list("nutriment" = 3, "sugar" = 2) - -/obj/item/reagent_containers/food/snacks/applepie - name = "Apple Pie" - desc = "A pie containing sweet sweet love... or apple." - icon_state = "applepie" - filling_color = "#E0EDC5" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/cherrypie - name = "Cherry Pie" - desc = "Taste so good, make a grown man cry." - icon_state = "cherrypie" - filling_color = "#FF525A" - bitesize = 3 - list_reagents = list("nutriment" = 10, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/twobread - name = "Two Bread" - desc = "It is very bitter and winy." - icon_state = "twobread" - filling_color = "#DBCC9A" - bitesize = 3 - list_reagents = list("nutriment" = 2, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellysandwich - name = "Jelly Sandwich" - desc = "You wish you had some peanut butter to go with this..." - icon_state = "jellysandwich" - trash = /obj/item/trash/plate - filling_color = "#9E3A78" - bitesize = 3 - -/obj/item/reagent_containers/food/snacks/jellysandwich/slime - list_reagents = list("nutriment" = 2, "slimejelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/jellysandwich/cherry - list_reagents = list("nutriment" = 2, "cherryjelly" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/boiledslimecore - name = "Boiled Slime Core" - desc = "A boiled red thing." - icon_state = "boiledrorocore" - bitesize = 3 - list_reagents = list("slimejelly" = 5) - -/obj/item/reagent_containers/food/snacks/mint - name = "mint" - desc = "it is only wafer thin." - icon_state = "mint" - bitesize = 1 - filling_color = "#F2F2F2" - list_reagents = list("minttoxin" = 1) - -/obj/item/reagent_containers/food/snacks/mushroomsoup - name = "chantrelle soup" - desc = "A delicious and hearty mushroom soup." - icon_state = "mushroomsoup" - trash = /obj/item/trash/snack_bowl - filling_color = "#E386BF" - bitesize = 5 - list_reagents = list("nutriment" = 8, "vitamin" = 4) - -/obj/item/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" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/plumphelmetbiscuit/New() - ..() - 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("omnizine", 5) - -/obj/item/reagent_containers/food/snacks/chawanmushi - name = "chawanmushi" - desc = "A legendary egg custard that makes friends out of enemies. Probably too hot for a cat to eat." - icon_state = "chawanmushi" - trash = /obj/item/trash/snack_bowl - filling_color = "#F0F2E4" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/beetsoup - name = "beet soup" - desc = "Wait, how do you spell it again..?" - icon_state = "beetsoup" - trash = /obj/item/trash/snack_bowl - bitesize = 5 - filling_color = "#FAC9FF" - list_reagents = list("nutriment" = 7, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/beetsoup/New() - ..() - name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") - -/obj/item/reagent_containers/food/snacks/herbsalad - name = "herb salad" - desc = "A tasty salad with apples on top." - icon_state = "herbsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - bitesize = 3 - list_reagents = list("nutriment" = 8, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/validsalad - name = "valid salad" - desc = "It's just an herb salad with meatballs and fried potato slices. Nothing suspicious about it." - icon_state = "validsalad" - trash = /obj/item/trash/snack_bowl - filling_color = "#76B87F" - bitesize = 3 - list_reagents = list("nutriment" = 8, "salglu_solution" = 5, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/appletart - name = "golden apple streusel tart" - desc = "A tasty dessert that won't make it through a metal detector." - icon_state = "gappletart" - trash = /obj/item/trash/plate - filling_color = "#FFFF00" - bitesize = 3 - 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/reagent_containers/food/snacks/sliceable/meatbread - name = "meatbread loaf" - desc = "The culinary base of every self-respecting eloquen/tg/entleman." - icon_state = "meatbread" - slice_path = /obj/item/reagent_containers/food/snacks/meatbreadslice - slices_num = 5 - filling_color = "#FF7575" - list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/meatbreadslice - name = "meatbread slice" - desc = "A slice of delicious meatbread." - icon_state = "meatbreadslice" - trash = /obj/item/trash/plate - filling_color = "#FF7575" - -/obj/item/reagent_containers/food/snacks/sliceable/xenomeatbread - name = "xenomeatbread loaf" - desc = "The culinary base of every self-respecting eloquent gentleman. Extra Heretical." - icon_state = "xenomeatbread" - slice_path = /obj/item/reagent_containers/food/snacks/xenomeatbreadslice - slices_num = 5 - filling_color = "#8AFF75" - list_reagents = list("protein" = 20, "nutriment" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/xenomeatbreadslice - name = "xenomeatbread slice" - desc = "A slice of delicious meatbread. Extra Heretical." - icon_state = "xenobreadslice" - trash = /obj/item/trash/plate - filling_color = "#8AFF75" - -/obj/item/reagent_containers/food/snacks/sliceable/spidermeatbread - name = "spider meat loaf" - desc = "Reassuringly green meatloaf made from spider meat." - icon_state = "spidermeatbread" - slice_path = /obj/item/reagent_containers/food/snacks/spidermeatbreadslice - slices_num = 5 - list_reagents = list("protein" = 20, "nutriment" = 10, "toxin" = 15, "vitamin" = 5) - -/obj/item/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 - list_reagents = list("toxin" = 2) - -/obj/item/reagent_containers/food/snacks/sliceable/bananabread - name = "Banana-nut bread" - desc = "A heavenly and filling treat." - icon_state = "bananabread" - slice_path = /obj/item/reagent_containers/food/snacks/bananabreadslice - slices_num = 5 - filling_color = "#EDE5AD" - list_reagents = list("banana" = 20, "nutriment" = 20) - -/obj/item/reagent_containers/food/snacks/bananabreadslice - name = "Banana-nut bread slice" - desc = "A slice of delicious banana bread." - icon_state = "bananabreadslice" - trash = /obj/item/trash/plate - filling_color = "#EDE5AD" - -/obj/item/reagent_containers/food/snacks/sliceable/tofubread - name = "Tofubread" - icon_state = "Like meatbread but for vegetarians. Not guaranteed to give superpowers." - icon_state = "tofubread" - slice_path = /obj/item/reagent_containers/food/snacks/tofubreadslice - slices_num = 5 - filling_color = "#F7FFE0" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/tofubreadslice - name = "Tofubread slice" - desc = "A slice of delicious tofubread." - icon_state = "tofubreadslice" - trash = /obj/item/trash/plate - filling_color = "#F7FFE0" - -/obj/item/reagent_containers/food/snacks/sliceable/carrotcake - name = "Carrot Cake" - desc = "A favorite desert of a certain wascally wabbit. Not a lie." - icon_state = "carrotcake" - slice_path = /obj/item/reagent_containers/food/snacks/carrotcakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FFD675" - list_reagents = list("nutriment" = 20, "oculine" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/carrotcakeslice - name = "Carrot Cake slice" - desc = "Carrotty slice of Carrot Cake, carrots are good for your eyes! Also not a lie." - icon_state = "carrotcake_slice" - trash = /obj/item/trash/plate - filling_color = "#FFD675" - -/obj/item/reagent_containers/food/snacks/sliceable/braincake - name = "Brain Cake" - desc = "A squishy cake-thing." - icon_state = "braincake" - slice_path = /obj/item/reagent_containers/food/snacks/braincakeslice - slices_num = 5 - filling_color = "#E6AEDB" - bitesize = 3 - list_reagents = list("protein" = 10, "nutriment" = 10, "mannitol" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/braincakeslice - name = "Brain Cake slice" - desc = "Lemme tell you something about prions. THEY'RE DELICIOUS." - icon_state = "braincakeslice" - trash = /obj/item/trash/plate - filling_color = "#E6AEDB" - -/obj/item/reagent_containers/food/snacks/sliceable/cheesecake - name = "Cheese Cake" - desc = "DANGEROUSLY cheesy." - icon_state = "cheesecake" - slice_path = /obj/item/reagent_containers/food/snacks/cheesecakeslice - slices_num = 5 - filling_color = "#FAF7AF" - bitesize = 3 - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/cheesecakeslice - name = "Cheese Cake slice" - desc = "Slice of pure cheestisfaction." - icon_state = "cheesecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAF7AF" - -/obj/item/reagent_containers/food/snacks/sliceable/plaincake - name = "Vanilla Cake" - desc = "A plain cake, not a lie." - icon_state = "plaincake" - slice_path = /obj/item/reagent_containers/food/snacks/plaincakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#F7EDD5" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/plaincakeslice - name = "Vanilla Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "plaincake_slice" - trash = /obj/item/trash/plate - filling_color = "#F7EDD5" - -/obj/item/reagent_containers/food/snacks/sliceable/orangecake - name = "Orange Cake" - desc = "A cake with added orange." - icon_state = "orangecake" - slice_path = /obj/item/reagent_containers/food/snacks/orangecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FADA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/orangecakeslice - name = "Orange Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "orangecake_slice" - trash = /obj/item/trash/plate - filling_color = "#FADA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/limecake - name = "Lime Cake" - desc = "A cake with added lime." - icon_state = "limecake" - bitesize = 3 - slice_path = /obj/item/reagent_containers/food/snacks/limecakeslice - slices_num = 5 - filling_color = "#CBFA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/limecakeslice - name = "Lime Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "limecake_slice" - trash = /obj/item/trash/plate - filling_color = "#CBFA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/lemoncake - name = "Lemon Cake" - desc = "A cake with added lemon." - icon_state = "lemoncake" - slice_path = /obj/item/reagent_containers/food/snacks/lemoncakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#FAFA8E" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/lemoncakeslice - name = "Lemon Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "lemoncake_slice" - trash = /obj/item/trash/plate - filling_color = "#FAFA8E" - -/obj/item/reagent_containers/food/snacks/sliceable/chocolatecake - name = "Chocolate Cake" - desc = "A cake with added chocolate." - icon_state = "chocolatecake" - slice_path = /obj/item/reagent_containers/food/snacks/chocolatecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#805930" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/chocolatecakeslice - name = "Chocolate Cake slice" - desc = "Just a slice of cake, it is enough for everyone." - icon_state = "chocolatecake_slice" - trash = /obj/item/trash/plate - filling_color = "#805930" - -/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel - name = "Cheese wheel" - desc = "A big wheel of delicious Cheddar." - icon_state = "cheesewheel" - slice_path = /obj/item/reagent_containers/food/snacks/cheesewedge - slices_num = 5 - filling_color = "#FFF700" - list_reagents = list("nutriment" = 15, "vitamin" = 5, "cheese" = 20) - -/obj/item/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" - -/obj/item/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" - list_reagents = list("mercury" = 5, "lsd" = 5, "ethanol" = 5, "weird_cheese" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/birthdaycake - name = "Birthday Cake" - desc = "Happy Birthday..." - icon_state = "birthdaycake" - slice_path = /obj/item/reagent_containers/food/snacks/birthdaycakeslice - slices_num = 5 - filling_color = "#FFD6D6" - bitesize = 3 - list_reagents = list("nutriment" = 20, "sprinkles" = 10, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/birthdaycakeslice - name = "Birthday Cake slice" - desc = "A slice of your birthday" - icon_state = "birthdaycakeslice" - trash = /obj/item/trash/plate - filling_color = "#FFD6D6" - -/obj/item/reagent_containers/food/snacks/sliceable/bread - name = "Bread" - icon_state = "Some plain old Earthen bread." - icon_state = "bread" - slice_path = /obj/item/reagent_containers/food/snacks/breadslice - slices_num = 6 - filling_color = "#FFE396" - list_reagents = list("nutriment" = 10) - -/obj/item/reagent_containers/food/snacks/breadslice - name = "Bread slice" - desc = "A slice of home." - icon_state = "breadslice" - trash = /obj/item/trash/plate - filling_color = "#D27332" - list_reagents = list("nutriment" = 2, "bread" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/creamcheesebread - name = "Cream Cheese Bread" - desc = "Yum yum yum!" - icon_state = "creamcheesebread" - slice_path = /obj/item/reagent_containers/food/snacks/creamcheesebreadslice - slices_num = 5 - filling_color = "#FFF896" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/creamcheesebreadslice - name = "Cream Cheese Bread slice" - desc = "A slice of yum!" - icon_state = "creamcheesebreadslice" - trash = /obj/item/trash/plate - filling_color = "#FFF896" - list_reagents = list("nutriment" = 4, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/watermelonslice - name = "Watermelon Slice" - desc = "A slice of watery goodness." - icon_state = "watermelonslice" - filling_color = "#FF3867" - -/obj/item/reagent_containers/food/snacks/pineappleslice - name = "Pineapple Slices" - desc = "Rings of pineapple." - icon_state = "pineappleslice" - filling_color = "#e5b437" - -/obj/item/reagent_containers/food/snacks/sliceable/applecake - name = "Apple Cake" - desc = "A cake centered with Apple." - icon_state = "applecake" - slice_path = /obj/item/reagent_containers/food/snacks/applecakeslice - slices_num = 5 - bitesize = 3 - filling_color = "#EBF5B8" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/applecakeslice - name = "Apple Cake slice" - desc = "A slice of heavenly cake." - icon_state = "applecakeslice" - trash = /obj/item/trash/plate - filling_color = "#EBF5B8" - -/obj/item/reagent_containers/food/snacks/sliceable/pumpkinpie - name = "Pumpkin Pie" - desc = "A delicious treat for the autumn months." - icon_state = "pumpkinpie" - slice_path = /obj/item/reagent_containers/food/snacks/pumpkinpieslice - slices_num = 5 - bitesize = 3 - filling_color = "#F5B951" - list_reagents = list("nutriment" = 20, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/pumpkinpieslice - name = "Pumpkin Pie slice" - desc = "A slice of pumpkin pie, with whipped cream on top. Perfection." - icon_state = "pumpkinpieslice" - trash = /obj/item/trash/plate - filling_color = "#F5B951" - -/obj/item/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) - -/obj/item/reagent_containers/food/snacks/rawcutlet - name = "raw cutlet" - desc = "A thin piece of raw meat." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "rawcutlet" - bitesize = 1 - list_reagents = list("protein" = 1) - -/obj/item/reagent_containers/food/snacks/rawcutlet/attackby(obj/item/W, mob/user, params) - if(istype(W,/obj/item/kitchen/knife)) - user.visible_message( \ - "[user] cuts the raw cutlet with the knife!", \ - "You cut the raw cutlet with your knife!" \ - ) - new /obj/item/reagent_containers/food/snacks/raw_bacon(loc) - qdel(src) - - -/////////////////////////////////////////////////PIZZA//////////////////////////////////////// - -/obj/item/reagent_containers/food/snacks/sliceable/pizza - slices_num = 6 - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita - name = "Margherita" - desc = "The golden standard of pizzas." - icon_state = "pizzamargherita" - slice_path = /obj/item/reagent_containers/food/snacks/margheritaslice - slices_num = 6 - list_reagents = list("nutriment" = 30, "tomatojuice" = 6, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/margheritaslice - name = "Margherita slice" - desc = "A slice of the classic pizza." - icon_state = "pizzamargheritaslice" - filling_color = "#BAA14C" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza - name = "Meatpizza" - desc = "A pizza with meat topping." - icon_state = "meatpizza" - slice_path = /obj/item/reagent_containers/food/snacks/meatpizzaslice - slices_num = 6 - list_reagents = list("protein" = 30, "tomatojuice" = 6, "vitamin" = 8) - -/obj/item/reagent_containers/food/snacks/meatpizzaslice - name = "Meatpizza slice" - desc = "A slice of a meaty pizza." - icon_state = "meatpizzaslice" - filling_color = "#BAA14C" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza - name = "Mushroompizza" - desc = "Very special pizza." - icon_state = "mushroompizza" - slice_path = /obj/item/reagent_containers/food/snacks/mushroompizzaslice - slices_num = 6 - list_reagents = list("plantmatter" = 30, "vitamin" = 5) - -/obj/item/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" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza - name = "Vegetable pizza" - desc = "No one of Tomato Sapiens were harmed during making this pizza." - icon_state = "vegetablepizza" - slice_path = /obj/item/reagent_containers/food/snacks/vegetablepizzaslice - slices_num = 6 - list_reagents = list("plantmatter" = 25, "tomatojuice" = 6, "oculine" = 12, "vitamin" = 5) - -/obj/item/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" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza - name = "Hawaiian Pizza" - desc = "Love it or hate it, this pizza divides opinions. Complete with juicy pineapple." - icon_state = "hawaiianpizza" //NEEDED - slice_path = /obj/item/reagent_containers/food/snacks/hawaiianpizzaslice - slices_num = 6 - list_reagents = list("protein" = 15, "tomatojuice" = 6, "plantmatter" = 20, "pineapplejuice" = 6, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/hawaiianpizzaslice - name = "Hawaiian pizza slice" - desc = "A slice of polarising pizza." - icon_state = "hawaiianpizzaslice" - filling_color = "#e5b437" - -/obj/item/reagent_containers/food/snacks/sliceable/pizza/macpizza - name = "Macaroni cheese pizza" - desc = "Gastronomists have yet to classify this dish as 'pizza'." - icon_state = "macpizza" - slice_path = /obj/item/reagent_containers/food/snacks/macpizzaslice - list_reagents = list("nutriment" = 40, "vitamin" = 5) //More nutriment because carbs, but it's not any more vitaminicious - filling_color = "#ffe45d" - -/obj/item/reagent_containers/food/snacks/macpizzaslice - name = "Macaroni cheese pizza slice" - desc = "A delicious slice of pizza topped with macaroni cheese... wait, what the hell? Who would do this?!" - icon_state = "macpizzaslice" - filling_color = "#ffe45d" - -/obj/item/pizzabox - name = "pizza box" - desc = "A box suited for pizzas." - icon = 'icons/obj/food/food.dmi' - icon_state = "pizzabox1" - - var/open = 0 // Is the box open? - var/ismessy = 0 // Fancy mess on the lid - var/obj/item/reagent_containers/food/snacks/sliceable/pizza/pizza // Content pizza - var/list/boxes = list() // If the boxes are stacked, they come here - var/boxtag = "" - -/obj/item/pizzabox/update_icon() - - overlays = list() - - // Set appropriate description - if( open && pizza ) - desc = "A box suited for pizzas. It appears to have a [pizza.name] inside." - else if( boxes.len > 0 ) - desc = "A pile of boxes suited for pizzas. There appears to be [boxes.len + 1] boxes in the pile." - - var/obj/item/pizzabox/topbox = boxes[boxes.len] - var/toptag = topbox.boxtag - if( toptag != "" ) - desc = "[desc] The box on top has a tag, it reads: '[toptag]'." - else - desc = "A box suited for pizzas." - - if( boxtag != "" ) - desc = "[desc] The box has a tag, it reads: '[boxtag]'." - - // Icon states and overlays - if( open ) - if( ismessy ) - icon_state = "pizzabox_messy" - else - icon_state = "pizzabox_open" - - if( pizza ) - var/image/pizzaimg = image("food/food.dmi", icon_state = pizza.icon_state) - pizzaimg.pixel_y = -3 - overlays += pizzaimg - - return - else - // Stupid code because byondcode sucks - var/doimgtag = 0 - if( boxes.len > 0 ) - var/obj/item/pizzabox/topbox = boxes[boxes.len] - if( topbox.boxtag != "" ) - doimgtag = 1 - else - if( boxtag != "" ) - doimgtag = 1 - - if( doimgtag ) - var/image/tagimg = image("food/food.dmi", icon_state = "pizzabox_tag") - tagimg.pixel_y = boxes.len * 3 - overlays += tagimg - - icon_state = "pizzabox[boxes.len+1]" - -/obj/item/pizzabox/attack_hand(mob/user) - if(open && pizza) - user.put_in_hands(pizza) - to_chat(user, "You take the [pizza] out of the [src].") - pizza = null - update_icon() - return - - if(boxes.len > 0) - if(user.is_in_inactive_hand(src)) - ..() - return - - var/obj/item/pizzabox/box = boxes[boxes.len] - boxes -= box - - user.put_in_hands( box ) - to_chat(user, "You remove the topmost [src] from your hand.") - box.update_icon() - update_icon() - return - ..() - -/obj/item/pizzabox/attack_self(mob/user) - if(boxes.len > 0) - return - - open = !open - - if( open && pizza ) - ismessy = 1 - - update_icon() - -/obj/item/pizzabox/attackby( obj/item/I, mob/user, params) - if(istype(I, /obj/item/pizzabox/)) - var/obj/item/pizzabox/box = I - - if(!box.open && !open) - // Make a list of all boxes to be added - var/list/boxestoadd = list() - boxestoadd += box - for(var/obj/item/pizzabox/i in box.boxes) - boxestoadd += i - - if( (boxes.len+1) + boxestoadd.len <= 5 ) - user.drop_item() - - box.loc = src - box.boxes = list() // Clear the box boxes so we don't have boxes inside boxes. - Xzibit - boxes.Add( boxestoadd ) - - box.update_icon() - update_icon() - - to_chat(user, "You put the [box] ontop of the [src]!") - else - to_chat(user, "The stack is too high!") - else - to_chat(user, "Close the [box] first!") - - return - - if(istype(I, /obj/item/reagent_containers/food/snacks/sliceable/pizza/)) // Long ass fucking object name - - if(open) - user.drop_item() - I.loc = src - pizza = I - - update_icon() - - to_chat(user, "You put the [I] in the [src]!") - else - to_chat(user, "You try to push the [I] through the lid but it doesn't work!") - return - - if(istype(I, /obj/item/pen/)) - - if(open) - return - - var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text - - var/obj/item/pizzabox/boxtotagto = src - if( boxes.len > 0 ) - boxtotagto = boxes[boxes.len] - - boxtotagto.boxtag = copytext("[boxtotagto.boxtag][t]", 1, 30) - - update_icon() - return - ..() - -/obj/item/pizzabox/margherita/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/margherita(src) - boxtag = "Margherita Deluxe" - -/obj/item/pizzabox/vegetable/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza(src) - boxtag = "Gourmet Vegatable" - -/obj/item/pizzabox/mushroom/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/mushroompizza(src) - boxtag = "Mushroom Special" - -/obj/item/pizzabox/meat/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/meatpizza(src) - boxtag = "Meatlover's Supreme" - -/obj/item/pizzabox/hawaiian/New() - pizza = new /obj/item/reagent_containers/food/snacks/sliceable/pizza/hawaiianpizza(src) - boxtag = "Hawaiian Feast" - -////////////////////////////////FOOD ADDITIONS//////////////////////////////////////////// - -/obj/item/reagent_containers/food/snacks/wrap - name = "egg wrap" - desc = "The precursor to Pigs in a Blanket." - icon_state = "wrap" - list_reagents = list("nutriment" = 5) - -/obj/item/reagent_containers/food/snacks/beans - name = "tin of beans" - desc = "Musical fruit in a slightly less musical container." - icon_state = "beans" - list_reagents = list("nutriment" = 10, "beans" = 10, "vitamin" = 3) - -/obj/item/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" = 6, "egg" = 3, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/hotdog - name = "hotdog" - desc = "Fresh footlong ready to go down on." - icon_state = "hotdog" - bitesize = 3 - list_reagents = list("nutriment" = 6, "ketchup" = 3, "vitamin" = 3) - -/obj/item/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, "vitamin" = 2) - -/obj/item/reagent_containers/food/snacks/icecreamsandwich - name = "icecream sandwich" - desc = "Portable Ice-cream in it's own packaging." - icon_state = "icecreamsandwich" - list_reagents = list("nutriment" = 2, "ice" = 2) - -/obj/item/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" - list_reagents = list("nutriment" = 6, "vitamin" = 6) - -/obj/item/reagent_containers/food/snacks/sugarcookie - name = "sugar cookie" - desc = "Just like your little sister used to make." - icon_state = "sugarcookie" - list_reagents = list("nutriment" = 3, "sugar" = 3) - -/obj/item/reagent_containers/food/snacks/friedbanana - name = "Fried Banana" - desc = "Goreng Pisang, also known as fried bananas." - icon_state = "friedbanana" - list_reagents = list("sugar" = 5, "nutriment" = 8, "cornoil" = 4) - -/obj/item/reagent_containers/food/snacks/dionaroast - name = "roast diona" - desc = "It's like an enormous, leathery carrot. With an eye." - icon_state = "dionaroast" - trash = /obj/item/trash/plate - filling_color = "#75754B" - list_reagents = list("plantmatter" = 4, "nutriment" = 2, "radium" = 2, "vitamin" = 4) - -/obj/item/reagent_containers/food/snacks/boiledspiderleg - name = "boiled spider leg" - desc = "A giant spider's leg that's still twitching after being cooked. Gross!" - icon_state = "spiderlegcooked" - trash = /obj/item/trash/plate - bitesize = 3 - list_reagents = list("nutriment" = 3, "capsaicin" = 2) - -/obj/item/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" - list_reagents = list("protein" = 2, "toxin" = 2) - -/obj/item/reagent_containers/food/snacks/spidereggsham - name = "green eggs and ham" - desc = "Would you eat them on a train? Would you eat them on a plane? Would you eat them on a state of the art corporate deathtrap floating through space?" - icon_state = "spidereggsham" - trash = /obj/item/trash/plate - bitesize = 4 - list_reagents = list("nutriment" = 6) - -/obj/item/reagent_containers/food/snacks/sliceable/turkey - name = "Turkey" - desc = "A traditional turkey served with stuffing." - icon_state = "turkey" - slice_path = /obj/item/reagent_containers/food/snacks/turkeyslice - slices_num = 6 - list_reagents = list("protein" = 24, "nutriment" = 18, "vitamin" = 5) - -/obj/item/reagent_containers/food/snacks/turkeyslice - name = "turkey serving" - desc = "A serving of some tender and delicious turkey." - icon_state = "turkeyslice" - trash = /obj/item/trash/plate - filling_color = "#B97A57" - -/obj/item/reagent_containers/food/snacks/mashed_potatoes //mashed taters - name = "mashed potatoes" - desc = "Some sot creamy, and irresistible mashed potatoes." - icon_state = "mashedtaters" - trash = /obj/item/trash/plate - filling_color = "#D6D9C1" - list_reagents = list("nutriment" = 5, "gravy" = 5, "mashedpotatoes" = 10, "vitamin" = 2) - -////////////////////////////////ICE CREAM/////////////////////////////////// -/obj/item/reagent_containers/food/snacks/icecream - name = "ice cream" - desc = "Delicious ice cream." - icon = 'icons/obj/kitchen.dmi' - icon_state = "icecream_cone" - bitesize = 3 - list_reagents = list("nutriment" = 1, "sugar" = 1) - -/obj/item/reagent_containers/food/snacks/icecream/New() - ..() - update_icon() - -/obj/item/reagent_containers/food/snacks/icecream/update_icon() - overlays.Cut() - var/image/filling = image('icons/obj/kitchen.dmi', src, "icecream_color") - filling.icon += mix_color_from_reagents(reagents.reagent_list) - overlays += filling - -/obj/item/reagent_containers/food/snacks/icecream/icecreamcone - name = "ice cream cone" - desc = "Delicious ice cream." - icon_state = "icecream_cone" - volume = 50 - bitesize = 3 - list_reagents = list("nutriment" = 3, "sugar" = 7, "ice" = 2) - -/obj/item/reagent_containers/food/snacks/icecream/icecreamcup - name = "chocolate ice cream cone" - desc = "Delicious ice cream." - icon_state = "icecream_cup" - volume = 50 - bitesize = 6 - list_reagents = list("nutriment" = 5, "chocolate" = 8, "ice" = 2) +// MISC /obj/item/reagent_containers/food/snacks/cereal name = "box of cereal" @@ -2440,131 +300,5 @@ icon_state = "deepfried_holder_icon" list_reagents = list("nutriment" = 3) -/obj/item/reagent_containers/food/snacks/dough - name = "dough" - desc = "A piece of dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "dough" - list_reagents = list("nutriment" = 6) -// Dough + rolling pin = flat dough -/obj/item/reagent_containers/food/snacks/dough/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/kitchen/rollingpin)) - if(isturf(loc)) - new /obj/item/reagent_containers/food/snacks/sliceable/flatdough(loc) - to_chat(user, "You flatten [src].") - qdel(src) - else - to_chat(user, "You need to put [src] on a surface to roll it out!") - else - ..() - -// slicable into 3xdoughslices -/obj/item/reagent_containers/food/snacks/sliceable/flatdough - name = "flat dough" - desc = "Some flattened dough." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flat dough" - slice_path = /obj/item/reagent_containers/food/snacks/doughslice - slices_num = 3 - list_reagents = list("nutriment" = 6) - -/obj/item/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" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/bun - name = "bun" - desc = "The base for any self-respecting burger." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "bun" - list_reagents = list("nutriment" = 1) - -/obj/item/reagent_containers/food/snacks/taco - name = "taco" - desc = "Take a bite!" - icon_state = "taco" - bitesize = 3 - list_reagents = list("nutriment" = 7, "vitamin" = 1) - -/obj/item/reagent_containers/food/snacks/cutlet - name = "cutlet" - desc = "A tasty meat slice." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "cutlet" - list_reagents = list("protein" = 2) - -/obj/item/reagent_containers/food/snacks/flatbread - name = "flatbread" - desc = "Bland but filling." - icon = 'icons/obj/food/food_ingredients.dmi' - icon_state = "flatbread" - list_reagents = list("nutriment" = 6, "vitamin" = 1) - -/obj/item/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" - list_reagents = list("plantmatter" = 3) - -/obj/item/reagent_containers/food/snacks/ectoplasm - name = "ectoplasm" - desc = "A luminescent blob of what scientists refer to as 'ghost goo'." - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - list_reagents = list("ectoplasm" = 10) - -/obj/item/reagent_containers/food/snacks/liquidfood - name = "\improper LiquidFood Ration" - desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" - icon_state = "liquidfood" - trash = /obj/item/trash/liquidfood - filling_color = "#A8A8A8" - bitesize = 4 - list_reagents = list("nutriment" = 20, "iron" = 3, "vitamin" = 2) - - -/obj/item/reagent_containers/food/snacks/tastybread - name = "bread tube" - desc = "Bread in a tube. Chewy...and surprisingly tasty." - icon_state = "tastybread" - trash = /obj/item/trash/tastybread - filling_color = "#A66829" - junkiness = 20 - list_reagents = list("nutriment" = 2, "sugar" = 4) - -/obj/item/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/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/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" - -/obj/item/reagent_containers/food/snacks/onionrings - name = "onion rings" - desc = "Onion slices coated in batter." - icon_state = "onionrings" - list_reagents = list("nutriment" = 3) - filling_color = "#C0C9A0" - gender = PLURAL #undef MAX_WEIGHT_CLASS \ No newline at end of file diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index a67b88f97d4..1e3c5602a22 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -122,7 +122,7 @@ to_chat(user, "The [src] is locked and running, wait for it to finish.") return - if(!ishuman(victim) || issmall(victim)) + if(!ishuman(victim)) to_chat(user, "This is not suitable for the [src]!") return @@ -255,8 +255,11 @@ if(occupant.reagents) occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - if(occupant.get_species() == "Human") - new /obj/item/stack/sheet/animalhide/human(src) + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + var/skinned = H.dna.species.skinned_type + if(skinned) + new skinned(src) new /obj/effect/decal/cleanable/blood/gibs(src) if(!UserOverride) diff --git a/code/modules/food_and_drinks/recipes/recipes_oven.dm b/code/modules/food_and_drinks/recipes/recipes_oven.dm index 025670aa817..7dcfe199ded 100644 --- a/code/modules/food_and_drinks/recipes/recipes_oven.dm +++ b/code/modules/food_and_drinks/recipes/recipes_oven.dm @@ -180,21 +180,16 @@ result = /obj/item/reagent_containers/food/snacks/fortunecookie /datum/recipe/oven/fortunecookie/make_food(obj/container) - var/obj/item/paper/paper = locate() in container - paper.loc = null //prevent deletion + var/obj/item/paper/P = locate() in container + P.loc = null //So we don't delete the paper while cooking the cookie var/obj/item/reagent_containers/food/snacks/fortunecookie/being_cooked = ..() - paper.loc = being_cooked - being_cooked.trash = paper //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn + if(P.info) //If there's anything written on the paper, just move it into the fortune cookie + P.forceMove(being_cooked) //Prevents the oven deleting our paper + being_cooked.trash = P //so the paper is left behind as trash without special-snowflake(TM Nodrak) code ~carn + else + qdel(P) return being_cooked -/datum/recipe/oven/fortunecookie/check_items(obj/container) - . = ..() - if(.) - var/obj/item/paper/paper = locate() in container - if(!paper || !paper.info) - return -1 - return . - /datum/recipe/oven/pizzamargherita items = list( /obj/item/reagent_containers/food/snacks/sliceable/flatdough, diff --git a/code/modules/games/52card.dm b/code/modules/games/52card.dm new file mode 100644 index 00000000000..036df3dd0c3 --- /dev/null +++ b/code/modules/games/52card.dm @@ -0,0 +1,50 @@ +/obj/item/deck/holder + name = "card box" + desc = "A small leather case to show how classy you are compared to everyone else." + icon_state = "card_holder" + +/obj/item/deck/cards + name = "deck of cards" + desc = "A simple deck of playing cards." + icon_state = "deck" + +/obj/item/deck/cards/New() + ..() + for(var/suit in list("spades","clubs","diamonds","hearts")) + var/colour + if(suit == "spades" || suit == "clubs") + colour = "black_" + else + colour = "red_" + + for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten")) + cards += new /datum/playingcard("[number] of [suit]", "[colour]num") + + for(var/number in list("jack","queen","king")) + cards += new /datum/playingcard("[number] of [suit]", "[colour]col") + + for(var/i = 0, i<2, i++) + cards += new /datum/playingcard("joker", "joker") + +/obj/item/deck/doublecards + name = "double deck of cards" + desc = "A simple deck of playing cards. Multiplied by two. Does not necessarily come with twice the fun." + icon_state = "doubledeck" + +/obj/item/deck/doublecards/New() + ..() + for(var/f = 0, f<2, f++) + for(var/suit in list("spades","clubs","diamonds","hearts")) + + var/colour + if(suit == "spades" || suit == "clubs") + colour = "black_" + else + colour = "red_" + for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten",)) + cards += new /datum/playingcard("[number] of [suit]", "[colour]num") + for(var/number in list("jack","queen","king")) + cards += new /datum/playingcard("[number] of [suit]", "[colour]col") + + for(var/i = 0, i<2, i++) + cards += new /datum/playingcard("joker", "joker") diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm new file mode 100644 index 00000000000..e14aaa09ba7 --- /dev/null +++ b/code/modules/games/cards.dm @@ -0,0 +1,481 @@ +/datum/playingcard + var/name = "playing card" + var/card_icon = "card_back" + var/back_icon = "card_back" + +/datum/playingcard/New(newname, newcard_icon, newback_icon) + ..() + if(newname) + name = newname + if(newcard_icon) + card_icon = newcard_icon + if(newback_icon) + back_icon = newback_icon + +/obj/item/deck + w_class = WEIGHT_CLASS_SMALL + icon = 'icons/obj/playing_cards.dmi' + actions_types = list(/datum/action/item_action/draw_card, /datum/action/item_action/deal_card, /datum/action/item_action/deal_card_multi, /datum/action/item_action/shuffle) + var/list/cards = list() + var/cooldown = 0 // to prevent spam shuffle + throw_speed = 3 + throw_range = 10 + throwforce = 0 + force = 0 + +/obj/item/deck/attackby(obj/O as obj, mob/user as mob) + if(istype(O,/obj/item/cardhand)) + var/obj/item/cardhand/H = O + if(H.parentdeck == src) + for(var/datum/playingcard/P in H.cards) + cards += P + qdel(H) + to_chat(user,"You place your cards on the bottom of [src].") + return + else + to_chat(user,"You can't mix cards from different decks!") + return + + ..() + +/obj/item/deck/examine(mob/user) + ..() + to_chat(user,"It contains [cards.len ? cards.len : "no"] cards") + +/obj/item/deck/attack_hand(mob/user as mob) + draw_card(user) + +// Datum actions +/datum/action/item_action/draw_card + name = "Draw - Draw one card" + button_icon_state = "draw" + use_itemicon = FALSE + +/datum/action/item_action/draw_card/Trigger() + if(istype(target, /obj/item/deck)) + var/obj/item/deck/D = target + return D.draw_card(owner) + return ..() + +/datum/action/item_action/deal_card + name = "Deal - deal one card to a person next to you" + button_icon_state = "deal_card" + use_itemicon = FALSE + +/datum/action/item_action/deal_card/Trigger() + if(istype(target, /obj/item/deck)) + var/obj/item/deck/D = target + return D.deal_card() + return ..() + +/datum/action/item_action/deal_card_multi + name = "Deal multiple card - Deal multiple card to a person next to you" + button_icon_state = "deal_card_multi" + use_itemicon = FALSE + +/datum/action/item_action/deal_card_multi/Trigger() + if(istype(target, /obj/item/deck)) + var/obj/item/deck/D = target + return D.deal_card_multi() + return ..() + +/datum/action/item_action/shuffle + name = "Shuffle - shuffle the deck" + button_icon_state = "shuffle" + use_itemicon = FALSE + +/datum/action/item_action/shuffle/Trigger() + if(istype(target, /obj/item/deck)) + var/obj/item/deck/D = target + return D.deckshuffle() + return ..() + +// Datum actions + +/obj/item/deck/verb/draw_card(mob/user) + + set category = "Object" + set name = "Draw" + set desc = "Draw a card from a deck." + set src in view(1) + + var/mob/living/carbon/human/M = user + + if(user.incapacitated() || !Adjacent(user)) + return + + if(!cards.len) + to_chat(user,"There are no cards in the deck.") + return + + var/obj/item/cardhand/H = M.is_in_hands(/obj/item/cardhand) + if(H && !(H.parentdeck == src)) + to_chat(user,"You can't mix cards from different decks!") + return + if(H && ((1 + H.cards.len) > H.maxcardlen)) + to_chat(user,"You can't hold that many cards in one hand!") + return + + if(!H) + H = new(get_turf(src)) + user.put_in_hands(H) + + var/datum/playingcard/P = cards[1] + H.cards += P + cards -= P + H.parentdeck = src + H.update_icon() + user.visible_message("[user] draws a card.","You draws a card.") + to_chat(user,"It's [P].") + +/obj/item/deck/verb/deal_card() + + set category = "Object" + set name = "Deal" + set desc = "Deal a card from a deck." + set src in view(1) + + if(usr.incapacitated() || !Adjacent(usr)) + return + + if(!cards.len) + to_chat(usr,"There are no cards in the deck.") + return + + var/list/players = list() + for(var/mob/living/player in viewers(3)) + if(!player.incapacitated()) + players += player + //players -= usr + + var/mob/living/M = input("Who do you wish to deal a card to?") as null|anything in players + if(!usr || !src || !M) return + + deal_at(usr, M, 1) + +/obj/item/deck/verb/deal_card_multi() + + set category = "Object" + set name = "Deal Multiple Cards" + set desc = "Deal multiple cards from a deck." + set src in view(1) + + if(usr.incapacitated() || !Adjacent(usr)) + return + + if(!cards.len) + to_chat(usr,"There are no cards in the deck.") + return + + var/list/players = list() + for(var/mob/living/player in viewers(3)) + if(!player.incapacitated()) + players += player + var/maxcards = max(min(cards.len,10),1) + var/dcard = input("How many card(s) do you wish to deal? You may deal up to [maxcards] cards.") as num + if(dcard > maxcards) + return + var/mob/living/M = input("Who do you wish to deal [dcard] card(s)?") as null|anything in players + if(!usr || !src || !M || !Adjacent(usr)) + return + + deal_at(usr, M, dcard) + +/obj/item/deck/proc/deal_at(mob/user, mob/target, dcard) // Take in the no. of card to be dealt + var/obj/item/cardhand/H = new(get_step(user, user.dir)) + for(var/i in 1 to dcard) + H.cards += cards[1] + cards -= cards[1] + H.parentdeck = src + H.concealed = TRUE + H.update_icon() + if(user == target) + user.visible_message("[user] deals [dcard] card(s) to \himself.") + else + user.visible_message("[user] deals [dcard] card(s) to [target].") + H.throw_at(get_step(target,target.dir),3,1,H) + + +/obj/item/deck/attack_self() + deckshuffle() + +/obj/item/deck/verb/verb_shuffle() + set category = "Object" + set name = "Shuffle" + set desc = "Shuffle the cards in the deck." + set src in view(1) + deckshuffle() + +/obj/item/deck/proc/deckshuffle() + var/mob/living/user = usr + if(cooldown < world.time - 5 SECONDS) + cards = shuffle(cards) + user.visible_message("[user] shuffles [src].") + playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) + cooldown = world.time + + +/obj/item/deck/MouseDrop(atom/over_object) // Code from Paper bin, so you can still pick up the deck + var/mob/M = usr + if(M.incapacitated() || !Adjacent(M)) + return + + if(over_object == M) + M.put_in_hands(src) + + else if(istype(over_object, /obj/screen)) + switch(over_object.name) + if("r_hand") + if(!remove_item_from_storage(M)) + M.unEquip(src) + M.put_in_r_hand(src) + if("l_hand") + if(!remove_item_from_storage(M)) + M.unEquip(src) + M.put_in_l_hand(src) + + add_fingerprint(M) + usr.visible_message("[usr] picks up the deck.") + +/obj/item/pack + name = "Card Pack" + desc = "For those with disposable income." + + icon_state = "card_pack" + icon = 'icons/obj/playing_cards.dmi' + w_class = WEIGHT_CLASS_TINY + var/list/cards = list() + var/parentdeck = null // For future card pack that need to be compatible with eachother i.e. cardemon + + +/obj/item/pack/attack_self(mob/user as mob) + user.visible_message("[name] rips open the [src]!", "You rips open the [src]!") + var/obj/item/cardhand/H = new() + + H.cards += cards + cards.Cut() + user.unEquip(src, force = 1) + qdel(src) + + H.update_icon() + user.put_in_active_hand(H) + +/obj/item/cardhand + name = "hand of cards" + desc = "Some playing cards." + icon = 'icons/obj/playing_cards.dmi' + icon_state = "empty" + w_class = WEIGHT_CLASS_TINY + throw_speed = 4 + throw_range = 20 + throwforce = 0 + force = 0 + var/maxcardlen = 20 + actions_types = list(/datum/action/item_action/remove_card, /datum/action/item_action/discard) + + var/concealed = FALSE + var/list/cards = list() + var/parentdeck = null + +/obj/item/cardhand/attackby(obj/O as obj, mob/user as mob) + if(cards.len == 1 && istype(O, /obj/item/pen)) + var/datum/playingcard/P = cards[1] + if(P.name != "Blank Card") + to_chat(user,"You cannot write on that card.") + return + var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_PAPER_MESSAGE_LEN) + if(!cardtext) + return + P.name = cardtext + // SNOWFLAKE FOR CAG, REMOVE IF OTHER CARDS ARE ADDED THAT USE THIS. + P.card_icon = "cag_white_card" + update_icon() + else if(istype(O,/obj/item/cardhand)) + var/obj/item/cardhand/H = O + if((H.cards.len + cards.len) > maxcardlen) + to_chat(user,"You can't hold that many cards in one hand!") + return + if(H.parentdeck == src.parentdeck) + for(var/datum/playingcard/P in cards) + H.cards += P + H.concealed = src.concealed + qdel(src) + H.update_icon() + return + else + to_chat(user,"You cannot mix cards from other deck!") + return + ..() + +/obj/item/cardhand/attack_self(var/mob/user as mob) + concealed = !concealed + update_icon() + user.visible_message("[user] [concealed ? "conceals" : "reveals"] their hand.") + +/obj/item/cardhand/examine(mob/user) + ..(user) + if((!concealed) && cards.len) + to_chat(user,"It contains:") + for(var/datum/playingcard/P in cards) + to_chat(user,"the [P.name].") + +// Datum action here + +/datum/action/item_action/remove_card + name = "Remove a card - Remove a single card from the hand." + button_icon_state = "remove_card" + use_itemicon = FALSE + +/datum/action/item_action/remove_card/Trigger() + if(istype(target, /obj/item/cardhand)) + var/obj/item/cardhand/C = target + return C.Removecard() + return ..() + +/datum/action/item_action/discard + name = "Discard - Place (a) card(s) from your hand in front of you." + button_icon_state = "discard" + use_itemicon = FALSE + +/datum/action/item_action/discard/Trigger() + if(istype(target, /obj/item/cardhand)) + var/obj/item/cardhand/C = target + return C.discard() + return ..() + +// No more datum action here + +/obj/item/cardhand/verb/Removecard() + + set category = "Object" + set name = "Remove card" + set desc = "Remove a card from the hand." + set src in view(1) + + var/mob/living/carbon/user = usr + + if(user.incapacitated() || !Adjacent(user)) + return + + var/pickablecards = list() + for(var/datum/playingcard/P in cards) + pickablecards[P.name] = P + var/pickedcard = input("Which card do you want to remove from the hand?") as null|anything in pickablecards + + if(QDELETED(src)) + return + + var/datum/playingcard/card = pickablecards[pickedcard] + + var/obj/item/cardhand/H = new(get_turf(src)) + user.put_in_active_hand(H) + H.cards += card + cards -= card + H.parentdeck = parentdeck + H.concealed = concealed + H.update_icon() + update_icon() + + if(!cards.len) + qdel(src) + +/obj/item/cardhand/verb/discard(var/mob/user as mob) + + set category = "Object" + set name = "Discard" + set desc = "Place (a) card(s) from your hand in front of you." + + var/maxcards = min(cards.len,5) + var/discards = input("How many cards do you want to discard? You may discard up to [maxcards] card(s)") as num + if(discards > maxcards) + return + for(var/i in 1 to discards) + var/list/to_discard = list() + for(var/datum/playingcard/P in cards) + to_discard[P.name] = P + var/discarding = input("Which card do you wish to put down?") as null|anything in to_discard + + if(QDELETED(src)) + return + + var/datum/playingcard/card = to_discard[discarding] + to_discard.Cut() + + var/obj/item/cardhand/H = new(get_turf(src)) + H.cards += card + cards -= card + H.concealed = FALSE + H.parentdeck = parentdeck + H.update_icon() + if(cards.len) + update_icon() + if(H.cards.len) + usr.visible_message("The [user] plays the [discarding].", "You play the [discarding].") + H.loc = get_step(usr,usr.dir) + + if(!cards.len) + qdel(src) + +/obj/item/cardhand/update_icon(var/direction = 0) + + if(!cards.len) + qdel(src) + return + else if(cards.len > 1) + name = "hand of cards" + desc = "Some playing cards." + else + name = "a playing card" + desc = "A playing card." + + overlays.Cut() + + if(cards.len == 1) + var/datum/playingcard/P = cards[1] + var/image/I = new(icon, (concealed ? "[P.back_icon]" : "[P.card_icon]") ) + I.pixel_x += (-5+rand(10)) + I.pixel_y += (-5+rand(10)) + overlays += I + return + + var/offset = Floor(20/cards.len + 1) + + var/matrix/M = matrix() + if(direction) + switch(direction) + if(NORTH) + M.Translate( 0, 0) + if(SOUTH) + M.Translate( 0, 4) + if(WEST) + M.Turn(90) + M.Translate( 3, 0) + if(EAST) + M.Turn(90) + M.Translate(-2, 0) + var/i = 0 + for(var/datum/playingcard/P in cards) + var/image/I = new(icon, (concealed ? "[P.back_icon]" : "[P.card_icon]") ) + //I.pixel_x = origin+(offset*i) + switch(direction) + if(SOUTH) + I.pixel_x = 8-(offset*i) + if(WEST) + I.pixel_y = -6+(offset*i) + if(EAST) + I.pixel_y = 8-(offset*i) + else + I.pixel_x = -7+(offset*i) + I.transform = M + overlays += I + i++ + +/obj/item/cardhand/dropped(mob/user as mob) + ..() + if(locate(/obj/structure/table, loc)) + update_icon(user.dir) + else + update_icon() + +/obj/item/cardhand/pickup(mob/user as mob) + update_icon() diff --git a/code/modules/games/tarot.dm b/code/modules/games/tarot.dm new file mode 100644 index 00000000000..bd26c34d437 --- /dev/null +++ b/code/modules/games/tarot.dm @@ -0,0 +1,32 @@ +/* this is a playing card deck based off of the Rider-Waite Tarot Deck. +*/ + +/obj/item/deck/tarot + name = "deck of tarot cards" + desc = "For all your occult needs!" + icon_state = "deck_tarot" + +/obj/item/deck/tarot/New() + ..() + + for(var/tarotname in list("Fool","Magician","High Priestess","Empress","Emperor","Hierophant","Lovers","Chariot","Strength","Hermit","Wheel of Fortune","Justice","Hanged Man","Death","Temperance","Devil","Tower","Star","Moon","Sun","Judgement","World")) + cards += new /datum/playingcard("[tarotname]", "tarot_major", "card_back_tarot") + for(var/suit in list("wands","pentacles","cups","swords")) + for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten","page","knight","queen","king")) + cards += new /datum/playingcard("[number] of [suit]", "tarot_[suit]", "card_back_tarot") + +/obj/item/deck/tarot/deckshuffle() + var/mob/living/user = usr + if(cooldown < world.time - 5 SECONDS) + var/list/newcards = list() + while(cards.len) + var/datum/playingcard/P = pick(cards) + P.name = replacetext(P.name," reversed","") + if(prob(50)) + P.name += " reversed" + newcards += P + cards -= P + cards = newcards + playsound(user, 'sound/items/cardshuffle.ogg', 50, 1) + user.visible_message("[user] shuffles [src].", "You shuffle the [src].") + cooldown = world.time diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 950b873af55..7acd3efc961 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -23,7 +23,7 @@ return 1 /mob/living/carbon/human/bee_friendly() - if(get_species() == "Diona") //bees pollinate plants, duh. + if(isdiona(src)) //bees pollinate plants, duh. return 1 if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL))) return 1 diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index e9265c15b4a..1f18edfae22 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -371,29 +371,30 @@ You've gained [totalkarma] total karma in your time here.
    "} return /client/proc/karmarefund(var/type,var/name,var/cost) - if(name == "Tajaran Ambassador") - cost = 30 - else if(name == "Unathi Ambassador") - cost = 30 - else if(name == "Skrell Ambassador") - cost = 30 - else if(name == "Diona Ambassador") - cost = 30 - else if(name == "Kidan Ambassador") - cost = 30 - else if(name == "Slime People Ambassador") - cost = 30 - else if(name == "Grey Ambassador") - cost = 30 - else if(name == "Vox Ambassador") - cost = 30 - else if(name == "Customs Officer") - cost = 30 - else if(name == "Nanotrasen Recruiter") - cost = 10 - else - to_chat(usr, "That job is not refundable.") - return + switch(name) + if("Tajaran Ambassador") + cost = 30 + if("Unathi Ambassador") + cost = 30 + if("Skrell Ambassador") + cost = 30 + if("Diona Ambassador") + cost = 30 + if("Kidan Ambassador") + cost = 30 + if("Slime People Ambassador") + cost = 30 + if("Grey Ambassador") + cost = 30 + if("Vox Ambassador") + cost = 30 + if("Customs Officer") + cost = 30 + if("Nanotrasen Recruiter") + cost = 10 + else + to_chat(usr, "That job is not refundable.") + return var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("whitelist")] WHERE ckey='[usr.ckey]'") query.Execute() @@ -408,12 +409,13 @@ You've gained [totalkarma] total karma in your time here.
    "} if(dbckey) var/list/typelist = list() - if(type == "job") - typelist = splittext(dbjob,",") - else if(type == "species") - typelist = splittext(dbspecies,",") - else - to_chat(usr, "Type [type] is not a valid column.") + switch(type) + if("job") + typelist = splittext(dbjob,",") + if("species") + typelist = splittext(dbspecies,",") + else + to_chat(usr, "Type [type] is not a valid column.") if(name in typelist) typelist -= name diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 8df5d593b9b..a856e3f822f 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -228,7 +228,7 @@ src.name = newtitle src.title = newtitle if("Contents") - var/content = strip_html(input(usr, "Write your book's contents (HTML NOT allowed):"), MAX_BOOK_MESSAGE_LEN) as message|null + var/content = strip_html(input(usr, "Write your book's contents (HTML NOT allowed):") as message|null, MAX_BOOK_MESSAGE_LEN) if(!content) to_chat(usr, "The content is invalid.") return 1 diff --git a/code/modules/martial_arts/brawling.dm b/code/modules/martial_arts/brawling.dm index a40a52b86be..b326e9f8b33 100644 --- a/code/modules/martial_arts/brawling.dm +++ b/code/modules/martial_arts/brawling.dm @@ -15,7 +15,7 @@ var/atk_verb = pick("left hook","right hook","straight punch") - var/damage = rand(5, 8) + A.species.punchdamagelow + var/damage = rand(5, 8) + A.dna.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index f42b7963104..bff0cf0d2e4 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -33,8 +33,8 @@ /datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) - var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) - var/datum/unarmed_attack/attack = A.species.unarmed + var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) + var/datum/unarmed_attack/attack = A.dna.species.unarmed var/atk_verb = "[pick(attack.attack_verb)]" if(D.lying) @@ -62,7 +62,7 @@ add_attack_logs(A, D, "Melee attacked with martial-art [src]", (damage > 0) ? null : ATKLOG_ALL) - if((D.stat != DEAD) && damage >= A.species.punchstunthreshold) + if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold) D.visible_message("[A] has weakened [D]!!", \ "[A] has weakened [D]!") D.apply_effect(4, WEAKEN, armor_block) diff --git a/code/modules/martial_arts/mimejutsu.dm b/code/modules/martial_arts/mimejutsu.dm index 38605c3538d..e8aa7a53d03 100644 --- a/code/modules/martial_arts/mimejutsu.dm +++ b/code/modules/martial_arts/mimejutsu.dm @@ -23,7 +23,7 @@ /datum/martial_art/mimejutsu/proc/mimeChuck(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(!D.stat && !D.stunned && !D.weakened) - var/damage = rand(5, 8) + A.species.punchdamagelow + var/damage = rand(5, 8) + A.dna.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] swings invisible nunchcuks at [D]..and misses?") diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index 4d94793a5e9..96fc0aa2e7f 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -95,8 +95,9 @@ sideslist = list("valid", "salad") credits = 20 -/obj/item/coin/antagtoken/New() - return +/obj/item/coin/antagtoken/syndicate + name = "syndicate coin" + credits = 160 /obj/item/coin/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/stack/cable_coil)) diff --git a/code/modules/mining/lavaland/loot/ashdragon_loot.dm b/code/modules/mining/lavaland/loot/ashdragon_loot.dm index ff0db975895..d88ec709dce 100644 --- a/code/modules/mining/lavaland/loot/ashdragon_loot.dm +++ b/code/modules/mining/lavaland/loot/ashdragon_loot.dm @@ -116,7 +116,7 @@ switch(random) if(1) to_chat(user, "Your flesh begins to melt! Miraculously, you seem fine otherwise.") - H.set_species("Skeleton") + H.set_species(/datum/species/skeleton) if(2) to_chat(user, "Power courses through you! You can now shift your form at will.") if(user.mind) diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm index ddf1255cca0..59d3a715f32 100644 --- a/code/modules/mining/lavaland/loot/colossus_loot.dm +++ b/code/modules/mining/lavaland/loot/colossus_loot.dm @@ -289,7 +289,7 @@ if(ishuman(i)) var/mob/living/carbon/human/H = i if(H.stat == DEAD) - H.set_species("Shadow") + H.set_species(/datum/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) diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index e1c6c7f28a9..a80c2ae6c18 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -105,13 +105,13 @@ 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(!ishumanbasic(H) || 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") + H.set_species(/datum/species/angel) playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1, -1) H.adjustBruteLoss(20) H.emote("scream") diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 0a151babe67..c4487d61948 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -523,7 +523,7 @@ icon_state = "fan_tiny" buildstackamount = 2 -/obj/structure/fans/New(loc) +/obj/structure/fans/Initialize(loc) ..() air_update_turf(1) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 93bdfe30c27..1a6f29a6dd0 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -226,7 +226,14 @@ "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") /datum/language/vox/get_random_name() - return ..(FEMALE,1,6) + var/sounds = rand(2, 8) + var/i = 0 + var/newname = "" + + while(i <= sounds) + i++ + newname += pick(vox_name_syllables) + return capitalize(newname) /datum/language/diona name = "Rootspeak" @@ -240,8 +247,8 @@ syllables = list("hs","zt","kr","st","sh") /datum/language/diona/get_random_name() - var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" - new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + var/new_name = "[pick(list("To Sleep Beneath", "Wind Over", "Embrace of", "Dreams of", "Witnessing", "To Walk Beneath", "Approaching the", "Glimmer of", "The Ripple of", "Colors of", "The Still of", "Silence of", "Gentle Breeze of", "Glistening Waters under", "Child of", "Blessed Plant-ling of", "Grass-Walker of", "Element of", "Spawn of"))]" + new_name += " [pick(list("the Void", "the Sky", "Encroaching Night", "Planetsong", "Starsong", "the Wandering Star", "the Empty Day", "Daybreak", "Nightfall", "the Rain", "the Stars", "the Waves", "Dusk", "Night", "the Wind", "the Summer Wind", "the Blazing Sun", "the Scorching Sun", "Eternal Fields", "the Soothing Plains", "the Undying Fiona", "Mother Nature's Bousum"))]" return new_name /datum/language/trinary @@ -507,8 +514,10 @@ ..(speaker,message,speaker.real_name) /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) + if(isabductor(other) && isabductor(speaker)) + var/datum/species/abductor/A = speaker.dna.species + var/datum/species/abductor/A2 = other.dna.species + if(A.team == A2.team) return TRUE return FALSE @@ -553,7 +562,7 @@ if(!message) return - + log_say("(ROBOT) [message]", speaker) var/message_start = "[name], [speaker.name]" var/message_body = "[speaker.say_quote(message)],\"[message]\"
    " diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm index da19b6a35b2..df1bde34306 100644 --- a/code/modules/mob/living/autohiss.dm +++ b/code/modules/mob/living/autohiss.dm @@ -4,7 +4,7 @@ /mob/living/carbon/human/handle_autohiss(message, datum/language/L) if(!client || client.prefs.autohiss_mode == AUTOHISS_OFF) // no need to process if there's no client or they have autohiss off return message - return species.handle_autohiss(message, L, client.prefs.autohiss_mode) + return dna.species.handle_autohiss(message, L, client.prefs.autohiss_mode) /client/verb/toggle_autohiss() set name = "Toggle Auto-Accent" diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 7b0e58ba5eb..9d50d8bf2ea 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -121,10 +121,10 @@ brainmob.dna = H.dna.Clone() brainmob.container = src - if(!istype(H.species) || isnull(H.species.return_organ("brain"))) // Diona/buggy people + if(!istype(H.dna.species) || isnull(H.dna.species.return_organ("brain"))) // Diona/buggy people held_brain = new(src) else // We have a species, and it has a brain - var/brain_path = H.species.return_organ("brain") + var/brain_path = H.dna.species.return_organ("brain") if(!ispath(brain_path, /obj/item/organ/internal/brain)) brain_path = /obj/item/organ/internal/brain held_brain = new brain_path(src) // Slime people will keep their slimy brains this way @@ -265,8 +265,6 @@ forceMove(holder) holder.stored_mmi = src holder.update_from_mmi() - if(istype(src, /obj/item/mmi/posibrain)) - holder.robotize() if(brainmob && brainmob.mind) brainmob.mind.transfer_to(H) holder.insert(H) diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 82e062246b6..c64318d804b 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -84,12 +84,12 @@ I'm using this for Stat to give it a more nifty interface to work with if(container) var/obj/item/mmi/M = container if(istype(M) && M.held_brain) - return M.held_brain.dna.get_species_name() + return M.held_brain.dna.species.name else return "Artificial Life" if(istype(loc, /obj/item/organ/internal/brain)) var/obj/item/organ/internal/brain/B = loc - return B.dna.get_species_name() + return B.dna.species.name /mob/living/carbon/brain/Stat() ..() diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm deleted file mode 100644 index ab9c72373a1..00000000000 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ /dev/null @@ -1,206 +0,0 @@ -/obj/item/mmi/posibrain - name = "positronic brain" - desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." - icon = 'icons/obj/assemblies.dmi' - icon_state = "posibrain" - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=3;programming=3;plasmatech=2" - - var/searching = 0 - var/askDelay = 10 * 60 * 1 - //var/mob/living/carbon/brain/brainmob = null - var/list/ghost_volunteers[0] - req_access = list(access_robotics) - mecha = null//This does not appear to be used outside of reference in mecha.dm. - var/silenced = 0 //if set to 1, they can't talk. - var/next_ping_at = 0 - -/obj/item/mmi/posibrain/attack_self(mob/user) - if(brainmob && !brainmob.key && searching == 0) - //Start the process of searching for a new user. - to_chat(user, "You carefully locate the manual activation switch and start the positronic brain's boot process.") - icon_state = "posibrain-searching" - ghost_volunteers.Cut() - searching = 1 - request_player() - spawn(600) - if(ghost_volunteers.len) - var/mob/dead/observer/O - while(!istype(O) && ghost_volunteers.len) - O = pick_n_take(ghost_volunteers) - if(istype(O) && check_observer(O)) - transfer_personality(O) - reset_search() - else - silenced = !silenced - to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].") - if(brainmob && brainmob.key) - to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].") - -/obj/item/mmi/posibrain/proc/request_player() - for(var/mob/dead/observer/O in player_list) - if(check_observer(O)) - to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)") - -/obj/item/mmi/posibrain/proc/check_observer(var/mob/dead/observer/O) - if(cannotPossess(O)) - return 0 - if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) - return 0 - if(!O.can_reenter_corpse) - return 0 - if(O.client) - return 1 - return 0 - -/obj/item/mmi/posibrain/proc/question(var/client/C) - spawn(0) - if(!C) return - var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") - if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. - if(response == "Yes") - transfer_personality(C.mob) - else if(response == "Never for this round") - C.prefs.be_special -= ROLE_POSIBRAIN - -// This should not ever happen, but let's be safe -/obj/item/mmi/posibrain/dropbrain(var/turf/dropspot) - log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src) - return - -/obj/item/mmi/posibrain/transfer_identity(var/mob/living/carbon/H) - name = "positronic brain ([H])" - if(isnull(brainmob.dna)) - brainmob.dna = H.dna.Clone() - brainmob.name = brainmob.dna.real_name - brainmob.real_name = brainmob.name - brainmob.timeofhostdeath = H.timeofdeath - brainmob.stat = CONSCIOUS - if(brainmob.mind) - brainmob.mind.assigned_role = "Positronic Brain" - if(H.mind) - H.mind.transfer_to(brainmob) - to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a metal cube.") - become_occupied("posibrain-occupied") - if(radio) - radio_action.ApplyIcon() - return - -/obj/item/mmi/posibrain/proc/transfer_personality(var/mob/candidate) - src.searching = 0 - src.brainmob.key = candidate.key - src.name = "positronic brain ([src.brainmob.name])" - - to_chat(src.brainmob, "You are a positronic brain, brought into existence on [station_name()].") - to_chat(src.brainmob, "As a synthetic intelligence, you answer to all crewmembers, as well as the AI.") - to_chat(src.brainmob, "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.") - src.brainmob.mind.assigned_role = "Positronic Brain" - - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain chimes quietly.") - become_occupied("posibrain-occupied") - - -/obj/item/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. - if(src.brainmob && src.brainmob.key) return - - src.searching = 0 - icon_state = "posibrain" - - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") - -/obj/item/mmi/posibrain/Topic(href,href_list) - if("signup" in href_list) - var/mob/dead/observer/O = locate(href_list["signup"]) - if(!O) return - volunteer(O) - -/obj/item/mmi/posibrain/proc/volunteer(var/mob/dead/observer/O) - if(!searching) - to_chat(O, "Not looking for a ghost, yet.") - return - if(!istype(O)) - to_chat(O, "Error.") - return - if(O in ghost_volunteers) - to_chat(O, "Removed from registration list.") - ghost_volunteers.Remove(O) - return - if(!check_observer(O)) - to_chat(O, "You cannot be \a [src].") - return - if(cannotPossess(O)) - to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.") - return - if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) - to_chat(O, "You are job banned from this role.") - return - to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") - ghost_volunteers.Add(O) - - -/obj/item/mmi/posibrain/examine(mob/user) - to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].") - to_chat(user, "*---------*") - . = ..() - if(!.) - to_chat(user, "*---------*") - return - - var/list/msg = list("") - - if(brainmob && brainmob.key) - switch(brainmob.stat) - if(CONSCIOUS) - if(!brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk - if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" - if(DEAD) msg += "It appears to be completely inactive.\n" - else - msg += "It appears to be completely inactive.\n" - msg += "*---------*" - to_chat(user, msg.Join("")) - -/obj/item/mmi/posibrain/emp_act(severity) - if(!src.brainmob) - return - else - switch(severity) - if(1) - src.brainmob.emp_damage += rand(20,30) - if(2) - src.brainmob.emp_damage += rand(10,20) - if(3) - src.brainmob.emp_damage += rand(0,10) - ..() - -/obj/item/mmi/posibrain/New() - src.brainmob = new(src) - src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" - src.brainmob.real_name = src.brainmob.name - src.brainmob.loc = src - src.brainmob.container = src - src.brainmob.stat = 0 - src.brainmob.SetSilence(0) - dead_mob_list -= src.brainmob - - ..() - -/obj/item/mmi/posibrain/attack_ghost(var/mob/dead/observer/O) - if(searching) - volunteer(O) - return - if(brainmob && brainmob.key) - return // No point pinging a posibrain with a player already inside - if(check_observer(O) && (world.time >= next_ping_at)) - next_ping_at = world.time + (20 SECONDS) - playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0) - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/M in viewers(T)) - M.show_message("The positronic brain pings softly.") - -/obj/item/mmi/posibrain/ipc - desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." - silenced = 1 diff --git a/code/modules/mob/living/carbon/brain/robotic_brain.dm b/code/modules/mob/living/carbon/brain/robotic_brain.dm new file mode 100644 index 00000000000..ea83ab90206 --- /dev/null +++ b/code/modules/mob/living/carbon/brain/robotic_brain.dm @@ -0,0 +1,231 @@ +/obj/item/mmi/robotic_brain + name = "robotic brain" + desc = "An advanced circuit, capable of housing a non-sentient synthetic intelligence." + icon = 'icons/obj/module.dmi' + icon_state = "boris_blank" + var/blank_icon = "boris_blank" + var/searching_icon = "boris_recharging" + var/occupied_icon = "boris" + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "biotech=3;programming=3;plasmatech=2" + + var/searching = FALSE + var/askDelay = 10 * 60 * 1 + //var/mob/living/carbon/brain/brainmob = null + var/list/ghost_volunteers[0] + req_access = list(access_robotics) + mecha = null//This does not appear to be used outside of reference in mecha.dm. + var/silenced = FALSE //if TRUE, they can't talk. + var/next_ping_at = 0 + var/requires_master = TRUE + var/mob/living/carbon/human/imprinted_master = null + var/ejected_flavor_text = "circuit" + +/obj/item/mmi/robotic_brain/Destroy() + imprinted_master = null + return ..() + +/obj/item/mmi/robotic_brain/attack_self(mob/user) + if(requires_master && !imprinted_master) + to_chat(user, "You press your thumb on [src] and imprint your user information.") + imprinted_master = user + return + if(brainmob && !brainmob.key && !searching) + //Start the process of searching for a new user. + to_chat(user, "You carefully locate the manual activation switch and start [src]'s boot process.") + icon_state = searching_icon + ghost_volunteers.Cut() + searching = TRUE + request_player() + spawn(600) + if(ghost_volunteers.len) + var/mob/dead/observer/O + while(!istype(O) && ghost_volunteers.len) + O = pick_n_take(ghost_volunteers) + if(istype(O) && check_observer(O)) + transfer_personality(O) + reset_search() + else + silenced = !silenced + to_chat(user, "You toggle the speaker [silenced ? "off" : "on"].") + if(brainmob && brainmob.key) + to_chat(brainmob, "Your internal speaker has been toggled [silenced ? "off" : "on"].") + +/obj/item/mmi/robotic_brain/proc/request_player() + for(var/mob/dead/observer/O in player_list) + if(check_observer(O)) + to_chat(O, "\A [src] has been activated. (Teleport | Sign Up)") + +/obj/item/mmi/robotic_brain/proc/check_observer(mob/dead/observer/O) + if(cannotPossess(O)) + return FALSE + if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) + return FALSE + if(!O.can_reenter_corpse) + return FALSE + if(O.client) + return TRUE + return FALSE + +/obj/item/mmi/robotic_brain/proc/question(client/C) + spawn(0) + if(!C) + return + var/response = alert(C, "Someone is requesting a personality for a [src]. Would you like to play as one?", "[src] request", "Yes", "No", "Never for this round") + if(!C || brainmob.key || !searching) + return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(response == "Yes") + transfer_personality(C.mob) + else if(response == "Never for this round") + C.prefs.be_special -= ROLE_POSIBRAIN + +// This should not ever happen, but let's be safe +/obj/item/mmi/robotic_brain/dropbrain(turf/dropspot) + log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src) + +/obj/item/mmi/robotic_brain/transfer_identity(mob/living/carbon/H) + name = "[src] ([H])" + if(isnull(brainmob.dna)) + brainmob.dna = H.dna.Clone() + brainmob.name = brainmob.dna.real_name + brainmob.real_name = brainmob.name + brainmob.timeofhostdeath = H.timeofdeath + brainmob.stat = CONSCIOUS + if(brainmob.mind) + brainmob.mind.assigned_role = "Positronic Brain" + if(H.mind) + H.mind.transfer_to(brainmob) + to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [ejected_flavor_text].") + become_occupied(occupied_icon) + if(radio) + radio_action.ApplyIcon() + +/obj/item/mmi/robotic_brain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/H) + if(..()) + if(imprinted_master) + to_chat(H, "You are permanently imprinted to [imprinted_master], obey [imprinted_master]'s every order and assist [imprinted_master.p_them()] in completing [imprinted_master.p_their()] goals at any cost.") + + +/obj/item/mmi/robotic_brain/proc/transfer_personality(mob/candidate) + searching = FALSE + brainmob.key = candidate.key + name = "[src] ([brainmob.name])" + + to_chat(brainmob, "You are a [src], brought into existence on [station_name()].") + to_chat(brainmob, "As a non-sentient synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure or mech.") + to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.") + brainmob.mind.assigned_role = "Positronic Brain" + + visible_message("[src] chimes quietly.") + become_occupied(occupied_icon) + + +/obj/item/mmi/robotic_brain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. + if(brainmob && brainmob.key) + return + + searching = FALSE + icon_state = blank_icon + + visible_message("[src] buzzes quietly as the light fades out. Perhaps you could try again?") + +/obj/item/mmi/robotic_brain/Topic(href, href_list) + if("signup" in href_list) + var/mob/dead/observer/O = locate(href_list["signup"]) + if(!O) + return + volunteer(O) + +/obj/item/mmi/robotic_brain/proc/volunteer(mob/dead/observer/O) + if(!searching) + to_chat(O, "Not looking for a ghost, yet.") + return + if(!istype(O)) + to_chat(O, "Error.") + return + if(O in ghost_volunteers) + to_chat(O, "Removed from registration list.") + ghost_volunteers.Remove(O) + return + if(!check_observer(O)) + to_chat(O, "You cannot be \a [src].") + return + if(cannotPossess(O)) + to_chat(O, "Upon using the antagHUD you forfeited the ability to join the round.") + return + if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept")) + to_chat(O, "You are job banned from this role.") + return + to_chat(O., "You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.") + ghost_volunteers.Add(O) + + +/obj/item/mmi/robotic_brain/examine(mob/user) + to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].") + to_chat(user, "*---------*") + . = ..() + if(!.) + to_chat(user, "*---------*") + return + + var/list/msg = list("") + + if(brainmob && brainmob.key) + switch(brainmob.stat) + if(CONSCIOUS) + if(!brainmob.client) + msg += "It appears to be in stand-by mode.\n" //afk + if(UNCONSCIOUS) + msg += "It doesn't seem to be responsive.\n" + if(DEAD) + msg += "It appears to be completely inactive.\n" + else + msg += "It appears to be completely inactive.\n" + msg += "*---------*" + to_chat(user, msg.Join("")) + +/obj/item/mmi/robotic_brain/emp_act(severity) + if(!brainmob) + return + switch(severity) + if(1) + brainmob.emp_damage += rand(20, 30) + if(2) + brainmob.emp_damage += rand(10, 20) + if(3) + brainmob.emp_damage += rand(0, 10) + ..() + +/obj/item/mmi/robotic_brain/New() + brainmob = new(src) + brainmob.name = "[pick(list("PBU", "HIU", "SINA", "ARMA", "OSI"))]-[rand(100, 999)]" + brainmob.real_name = brainmob.name + brainmob.forceMove(src) + brainmob.container = src + brainmob.stat = CONSCIOUS + brainmob.SetSilence(0) + dead_mob_list -= brainmob + ..() + +/obj/item/mmi/robotic_brain/attack_ghost(mob/dead/observer/O) + if(searching) + volunteer(O) + return + if(brainmob && brainmob.key) + return // No point pinging a posibrain with a player already inside + if(check_observer(O) && (world.time >= next_ping_at)) + next_ping_at = world.time + (20 SECONDS) + playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0) + visible_message("[src] pings softly.") + +/obj/item/mmi/robotic_brain/positronic + name = "positronic brain" + icon = 'icons/obj/assemblies.dmi' + icon_state = "posibrain" + blank_icon = "posibrain" + searching_icon = "posibrain-searching" + occupied_icon = "posibrain-occupied" + desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." + silenced = TRUE + requires_master = FALSE + ejected_flavor_text = "metal cube" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index 4a34d2d1b05..907a2e4862d 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -22,9 +22,9 @@ if(!istype(container, /obj/item/mmi)) . = FALSE - else if(istype(container, /obj/item/mmi/posibrain)) - var/obj/item/mmi/posibrain/P = container - if(P && P.silenced) + else if(istype(container, /obj/item/mmi/robotic_brain)) + var/obj/item/mmi/robotic_brain/R = container + if(R && R.silenced) if(warning) to_chat(usr, "You cannot speak, as your internal speaker is turned off.") . = FALSE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 604dfc36f32..4b00bf832c8 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -382,7 +382,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, if(!ventcrawler) if(ishuman(src)) var/mob/living/carbon/human/H = src - ventcrawlerlocal = H.species.ventcrawler + ventcrawlerlocal = H.dna.species.ventcrawler if(!ventcrawlerlocal) return diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 152262b69ea..d19051692ca 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -3,20 +3,9 @@ AC.flags = flags AC.ui_interact(user, state = state) -/mob/living/carbon/human/proc/change_species(var/new_species) - if(!new_species || species == new_species || !(new_species in all_species)) - return - - set_species(new_species, null, 1) - reset_hair() - if(species.bodyflags & HAS_MARKINGS) - reset_markings() - - return 1 - /mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1) var/obj/item/organ/external/head/H = bodyparts_by_name["head"] - if(gender == new_gender || (gender == PLURAL && species.has_gender)) + if(gender == new_gender || (gender == PLURAL && dna.species.has_gender)) return gender = new_gender @@ -129,7 +118,7 @@ /mob/living/carbon/human/proc/change_alt_head(var/alternate_head) var/obj/item/organ/external/head/H = get_organ("head") - if(!H || H.alt_head == alternate_head || H.is_robotic() || (!(species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list)) + if(!H || H.alt_head == alternate_head || H.is_robotic() || (!(dna.species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list)) return H.alt_head = alternate_head @@ -296,7 +285,7 @@ /mob/living/carbon/human/proc/change_skin_color(var/colour = "#000000") - if(colour == skin_colour || !(species.bodyflags & HAS_SKIN_COLOR)) + if(colour == skin_colour || !(dna.species.bodyflags & HAS_SKIN_COLOR)) return skin_colour = colour @@ -306,7 +295,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) - if(s_tone == tone || !((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) + if(s_tone == tone || !((dna.species.bodyflags & HAS_SKIN_TONE) || (dna.species.bodyflags & HAS_ICON_SKIN_TONE))) return s_tone = tone @@ -321,8 +310,8 @@ /mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) var/list/valid_species = new() - for(var/current_species_name in all_species) - var/datum/species/current_species = all_species[current_species_name] + for(var/current_species_name in GLOB.all_species) + var/datum/species/current_species = GLOB.all_species[current_species_name] if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it! if(whitelist.len && !(current_species_name in whitelist)) @@ -350,16 +339,16 @@ continue if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE)) continue - if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] - if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_hairstyles += hairstyle //Give them their hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */ valid_hairstyles += hairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. + if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. valid_hairstyles += hairstyle return valid_hairstyles @@ -378,17 +367,17 @@ continue if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE)) continue - if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] - if(H.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... - if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if(H.dna.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... + if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */ valid_facial_hairstyles += facialhairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. + if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. valid_facial_hairstyles += facialhairstyle return valid_facial_hairstyles @@ -402,7 +391,7 @@ for(var/head_accessory in head_accessory_styles_list) var/datum/sprite_accessory/S = head_accessory_styles_list[head_accessory] - if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + if(!(H.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. continue valid_head_accessories += head_accessory @@ -421,7 +410,7 @@ continue if(S.marking_location != location) //If the marking isn't for the location we desire, skip. continue - if(!(species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. + if(!(dna.species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. continue if(location == "tail") if(!body_accessory) @@ -432,7 +421,7 @@ continue if(location == "head") var/datum/sprite_accessory/body_markings/head/M = marking_styles_list[S.name] - if(H.species.bodyflags & ALL_RPARTS)//If the user is a species that can have a robotic head... + if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species that can have a robotic head... var/datum/robolimb/robohead = all_robolimbs[H.model] if(!(S.models_allowed && (robohead.company in S.models_allowed))) //Make sure they don't get markings incompatible with their head. continue @@ -456,7 +445,7 @@ if(!istype(A)) valid_body_accessories["None"] = "None" //The only null entry should be the "None" option. continue - if(species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. + if(dna.species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. valid_body_accessories += B return valid_body_accessories @@ -469,7 +458,7 @@ valid_alt_heads["None"] = alt_heads_list["None"] //The only null entry should be the "None" option, and there should always be a "None" option. for(var/alternate_head in alt_heads_list) var/datum/sprite_accessory/alt_heads/head = alt_heads_list[alternate_head] - if(!(H.species.name in head.species_allowed)) + if(!(H.dna.species.name in head.species_allowed)) continue valid_alt_heads += alternate_head diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 37749c0dd76..bdca496d256 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -62,7 +62,7 @@ animation.master = src flick("dust-h", animation) - new species.remains_type(get_turf(src)) + new dna.species.remains_type(get_turf(src)) spawn(15) if(animation) qdel(animation) @@ -103,8 +103,8 @@ set_heartattack(FALSE) //Handle species-specific deaths. - if(species) - species.handle_death(src) + if(dna.species) + dna.species.handle_death(src) callHook("death", list(src, gibbed)) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index be46cc9fa7d..c1eb8641820 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -29,34 +29,42 @@ switch(act) //Cooldown-inducing emotes if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2") - if(species.name == "Machine") //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise. + var/found_machine_head = FALSE + if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - else //Everyone else fails, skip the emote attempt - return + found_machine_head = TRUE + else + var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises + if(H && H.is_robotic()) + on_CD = handle_emote_CD() + found_machine_head = TRUE + + if(!found_machine_head) //Everyone else fails, skip the emote attempt + return //Everyone else fails, skip the emote attempt if("drone","drones","hum","hums","rumble","rumbles") - if(get_species() == "Drask") //Only Drask can make whale noises + if(isdrask(src)) //Only Drask can make whale noises on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm else return if("howl", "howls") - if(get_species() == "Vulpkanin") //Only Vulpkanin can howl + if(isvulpkanin(src)) //Only Vulpkanin can howl on_CD = handle_emote_CD(100) else return if("growl", "growls") - if(get_species() == "Vulpkanin") //Only Vulpkanin can growl + if(isvulpkanin(src)) //Only Vulpkanin can growl on_CD = handle_emote_CD() else return if("squish", "squishes") var/found_slime_bodypart = 0 - if(get_species() == "Slime People") //Only Slime People can squish + if(isslimeperson(src)) //Only Slime People can squish on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' found_slime_bodypart = 1 else for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too! - if(L.dna.species in list("Slime People")) + if(istype(L.dna.species, /datum/species/slime)) on_CD = handle_emote_CD() found_slime_bodypart = 1 break @@ -65,31 +73,31 @@ return if("clack", "clacks") - if(get_species() == "Kidan") //Only Kidan can clack and rightfully so. + if(iskidan(src)) //Only Kidan can clack and rightfully so. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("click", "clicks") - if(get_species() == "Kidan") //Only Kidan can click and rightfully so. + if(iskidan(src)) //Only Kidan can click and rightfully so. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("creaks", "creak") - if(get_species() == "Diona") //Only Dionas can Creaks. + if(isdiona(src)) //Only Dionas can Creaks. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("hiss", "hisses") - if(get_species() == "Unathi") //Only Unathi can hiss. + if(isunathi(src)) //Only Unathi can hiss. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return if("quill", "quills") - if(get_species() == "Vox") //Only Vox can rustle their quills. + if(isvox(src)) //Only Vox can rustle their quills. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm' else //Everyone else fails, skip the emote attempt return @@ -225,7 +233,7 @@ message = "[src] starts wagging [p_their()] tail." start_tail_wagging(1) - else if(species.bodyflags & TAIL_WAGGING) + else if(dna.species.bodyflags & TAIL_WAGGING) if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) message = "[src] starts wagging [p_their()] tail." start_tail_wagging(1) @@ -236,7 +244,7 @@ m_type = 1 if("swag", "swags") - if(species.bodyflags & TAIL_WAGGING || body_accessory) + if(dna.species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging [p_their()] tail." stop_tail_wagging(1) else @@ -431,11 +439,11 @@ message = "[src] coughs!" m_type = 2 if(gender == FEMALE) - if(species.female_cough_sounds) - playsound(src, pick(species.female_cough_sounds), 120) + if(dna.species.female_cough_sounds) + playsound(src, pick(dna.species.female_cough_sounds), 120) else - if(species.male_cough_sounds) - playsound(src, pick(species.male_cough_sounds), 120) + if(dna.species.male_cough_sounds) + playsound(src, pick(dna.species.male_cough_sounds), 120) else message = "[src] makes a strong noise." m_type = 2 @@ -479,7 +487,7 @@ m_type = 2 if("deathgasp", "deathgasps") - message = "[src] [replacetext(species.death_message, "their", p_their())]" + message = "[src] [replacetext(dna.species.death_message, "their", p_their())]" m_type = 1 if("giggle", "giggles") @@ -676,9 +684,9 @@ if(!muzzled) message = "[src] sneezes." if(gender == FEMALE) - playsound(src, species.female_sneeze_sound, 70) + playsound(src, dna.species.female_sneeze_sound, 70) else - playsound(src, species.male_sneeze_sound, 70) + playsound(src, dna.species.male_sneeze_sound, 70) m_type = 2 else message = "[src] makes a strange noise." @@ -784,12 +792,12 @@ m_type = 1 else if(!muzzled) - message = "[src] [species.scream_verb][M ? " at [M]" : ""]!" + message = "[src] [dna.species.scream_verb][M ? " at [M]" : ""]!" m_type = 2 if(gender == FEMALE) - playsound(loc, "[species.female_scream_sound]", 80, 1, frequency = get_age_pitch()) + playsound(loc, "[dna.species.female_scream_sound]", 80, 1, frequency = get_age_pitch()) else - playsound(loc, "[species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present. + playsound(loc, "[dna.species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present. else message = "[src] makes a very loud noise[M ? " at [M]" : ""]." @@ -890,9 +898,7 @@ + " 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), quill(s)" - switch(species.name) - if("Machine") - emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + switch(dna.species.name) if("Drask") emotelist += "\nDrask specific emotes :- drone(s)-(none)/mob, hum(s)-(none)/mob, rumble(s)-(none)/mob" if("Kidan") @@ -906,11 +912,18 @@ if("Diona") emotelist += "\nDiona specific emotes :- creak(s)" - if (species.name == "Slime People") + if(ismachine(src)) + emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + else + var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises + if(H && H.is_robotic()) + emotelist += "\nRobotic head specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob" + + if(isslimeperson(src)) emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" else for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too! - if(L.dna.species in list("Slime People")) + if(istype(L.dna.species, /datum/species/slime)) emotelist += "\nSlime people body part specific emotes :- squish(es)-(none)/mob" break diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index e382796cd09..a39d2843501 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -29,14 +29,12 @@ msg += "[bicon(icon(icon, dir=SOUTH))] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated msg += "[name]" - var/list/nospecies = list("Abductor", "Shadowling", "Neara", "Monkey", "Stok", "Farwa", "Wolpin") //species that won't show their race no matter what - - var/displayed_species = get_species() + var/displayed_species = dna.species.name for(var/obj/item/clothing/C in src) //Disguise checks if(C == src.head || C == src.wear_suit || C == src.wear_mask || C == src.w_uniform || C == src.belt || C == src.back) if(C.species_disguise) displayed_species = C.species_disguise - if(skipjumpsuit && skipface || (displayed_species in nospecies)) //either obscured or on the nospecies list + if(skipjumpsuit && skipface || (NO_EXAMINE in dna.species.species_traits)) //either obscured or on the nospecies list msg += "!\n" //omit the species when examining else if(displayed_species == "Slime People") //snowflakey because Slime People are defined as a plural msg += ", a slime person!\n" @@ -199,9 +197,9 @@ var/list/wound_flavor_text = list() var/list/is_destroyed = list() - for(var/organ_tag in species.has_limbs) + for(var/organ_tag in dna.species.has_limbs) - var/list/organ_data = species.has_limbs[organ_tag] + var/list/organ_data = dna.species.has_limbs[organ_tag] var/organ_descriptor = organ_data["descriptor"] is_destroyed["[organ_data["descriptor"]]"] = 1 @@ -324,7 +322,7 @@ var/dodebug = auto.doing2string(auto.doing) var/interestdebug = auto.interest2string(auto.interest) msg += "[p_they(TRUE)] [p_are()] appears to be [interestdebug] and [dodebug].\n" - else if(species.show_ssd) + else if(dna.species.show_ssd) if(!key) msg += "[p_they(TRUE)] [p_are()] totally catatonic. The stresses of life in deep-space must have been too much for [p_them()]. Any recovery is unlikely.\n" else if(!client) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ad249d8307f..3f36b8b6d55 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -4,10 +4,6 @@ voice_name = "unknown" icon = 'icons/mob/human.dmi' icon_state = "body_m_s" - - //why are these here and not in human_defines.dm - //var/list/hud_list[10] - var/datum/species/species //Contains icon generation and language information, set during New(). var/obj/item/rig/wearing_rig // This is very not good, but it's much much better than calling get_rig() every update_canmove() call. /mob/living/carbon/human/New(loc) @@ -15,21 +11,17 @@ log_runtime(EXCEPTION("human/New called with more than 1 argument (REPORT THIS ENTIRE RUNTIME TO A CODER)")) . = ..() -/mob/living/carbon/human/Initialize(mapload, new_species = null) +/mob/living/carbon/human/Initialize(mapload, datum/species/new_species = /datum/species/human) if(!dna) dna = new /datum/dna(null) // Species name is handled by set_species() - if(!species) - if(new_species) - set_species(new_species, 1, delay_icon_update = 1) - else - set_species(delay_icon_update = 1) + set_species(new_species, 1, delay_icon_update = 1, skip_same_check = TRUE) ..() - if(species) - real_name = species.get_random_name(gender) + if(dna.species) + real_name = dna.species.get_random_name(gender) name = real_name if(mind) mind.name = real_name @@ -74,79 +66,92 @@ status_flags = GODMODE|CANPUSH /mob/living/carbon/human/skrell/Initialize(mapload) - ..(mapload, "Skrell") + ..(mapload, /datum/species/skrell) /mob/living/carbon/human/tajaran/Initialize(mapload) - ..(mapload, "Tajaran") + ..(mapload, /datum/species/tajaran) /mob/living/carbon/human/vulpkanin/Initialize(mapload) - ..(mapload, "Vulpkanin") + ..(mapload, /datum/species/vulpkanin) /mob/living/carbon/human/unathi/Initialize(mapload) - ..(mapload, "Unathi") + ..(mapload, /datum/species/unathi) /mob/living/carbon/human/vox/Initialize(mapload) - ..(mapload, "Vox") + ..(mapload, /datum/species/vox) /mob/living/carbon/human/voxarmalis/Initialize(mapload) - ..(mapload, "Vox Armalis") + ..(mapload, /datum/species/vox/armalis) /mob/living/carbon/human/skeleton/Initialize(mapload) - ..(mapload, "Skeleton") + ..(mapload, /datum/species/skeleton) /mob/living/carbon/human/kidan/Initialize(mapload) - ..(mapload, "Kidan") + ..(mapload, /datum/species/kidan) /mob/living/carbon/human/plasma/Initialize(mapload) - ..(mapload, "Plasmaman") + ..(mapload, /datum/species/plasmaman) /mob/living/carbon/human/slime/Initialize(mapload) - ..(mapload, "Slime People") + ..(mapload, /datum/species/slime) /mob/living/carbon/human/grey/Initialize(mapload) - ..(mapload, "Grey") + ..(mapload, /datum/species/grey) /mob/living/carbon/human/abductor/Initialize(mapload) - ..(mapload, "Abductor") - -/mob/living/carbon/human/human/Initialize(mapload) - ..(mapload, "Human") + ..(mapload, /datum/species/abductor) /mob/living/carbon/human/diona/Initialize(mapload) - ..(mapload, "Diona") + ..(mapload, /datum/species/diona) /mob/living/carbon/human/machine/Initialize(mapload) - ..(mapload, "Machine") + ..(mapload, /datum/species/machine) + +/mob/living/carbon/human/machine/created + name = "Integrated Robotic Chassis" + +/mob/living/carbon/human/machine/created/Initialize(mapload) + ..() + rename_character(null, "Integrated Robotic Chassis ([rand(1, 9999)])") + update_dna() + for(var/obj/item/organ/external/E in bodyparts) + if(istype(E, /obj/item/organ/external/chest) || istype(E, /obj/item/organ/external/groin)) + continue + qdel(E) + for(var/obj/item/organ/O in internal_organs) + qdel(O) + regenerate_icons() + death() /mob/living/carbon/human/shadow/Initialize(mapload) - ..(mapload, "Shadow") + ..(mapload, /datum/species/shadow) /mob/living/carbon/human/golem/Initialize(mapload) - ..(mapload, "Golem") + ..(mapload, /datum/species/golem) /mob/living/carbon/human/wryn/Initialize(mapload) - ..(mapload, "Wryn") + ..(mapload, /datum/species/wryn) /mob/living/carbon/human/nucleation/Initialize(mapload) - ..(mapload, "Nucleation") + ..(mapload, /datum/species/nucleation) /mob/living/carbon/human/drask/Initialize(mapload) - ..(mapload, "Drask") + ..(mapload, /datum/species/drask) /mob/living/carbon/human/monkey/Initialize(mapload) - ..(mapload, "Monkey") + ..(mapload, /datum/species/monkey) /mob/living/carbon/human/farwa/Initialize(mapload) - ..(mapload, "Farwa") + ..(mapload, /datum/species/monkey/tajaran) /mob/living/carbon/human/wolpin/Initialize(mapload) - ..(mapload, "Wolpin") + ..(mapload, /datum/species/monkey/vulpkanin) /mob/living/carbon/human/neara/Initialize(mapload) - ..(mapload, "Neara") + ..(mapload, /datum/species/monkey/skrell) /mob/living/carbon/human/stok/Initialize(mapload) - ..(mapload, "Stok") + ..(mapload, /datum/species/monkey/unathi) /mob/living/carbon/human/Stat() ..() @@ -550,7 +555,7 @@ grant_death_vision() return - species.update_sight(src) + dna.species.update_sight(src) //Removed the horrible safety parameter. It was only being used by ninja code anyways. //Now checks siemens_coefficient of the affected area by default @@ -580,8 +585,8 @@ if(gloves) var/obj/item/clothing/gloves/G = gloves gloves_siemens_coeff = G.siemens_coefficient - if(species) - species_siemens_coeff = species.siemens_coeff + if(dna.species) + species_siemens_coeff = dna.species.siemens_coeff siemens_coeff = gloves_siemens_coeff * species_siemens_coeff if(undergoing_cardiac_arrest()) if(shock_damage * siemens_coeff >= 1 && prob(25)) @@ -1032,14 +1037,6 @@ /mob/living/carbon/human/proc/check_dna() dna.check_integrity(src) - return - -/mob/living/carbon/human/get_species() - - if(!species) - set_species() - - return species.name /mob/living/carbon/human/proc/play_xylophone() if(!src.xylophone) @@ -1140,9 +1137,9 @@ //Replacing lost limbs with the species default. var/mob/living/carbon/human/temp_holder - for(var/limb_type in H.species.has_limbs) + for(var/limb_type in H.dna.species.has_limbs) if(!(limb_type in H.bodyparts_by_name)) - var/list/organ_data = H.species.has_limbs[limb_type] + var/list/organ_data = H.dna.species.has_limbs[limb_type] var/limb_path = organ_data["path"] var/obj/item/organ/external/O = new limb_path(temp_holder) if(H.get_limb_by_name(O.name)) //Check to see if the user already has an limb with the same name as the 'missing limb'. If they do, skip regrowth. @@ -1155,8 +1152,8 @@ //Replacing lost organs with the species default. temp_holder = new /mob/living/carbon/human() - for(var/index in H.species.has_organ) - var/organ = H.species.has_organ[index] + for(var/index in H.dna.species.has_organ) + var/organ = H.dna.species.has_organ[index] if(!(organ in types_of_int_organs)) //If the mob is missing this particular organ... var/obj/item/organ/internal/I = new organ(temp_holder) //Create the organ inside our holder so we can check it before implantation. if(H.get_organ_slot(I.slot)) //Check to see if the user already has an organ in the slot the 'missing organ' belongs to. If they do, skip implantation. @@ -1173,7 +1170,7 @@ surgeries.Cut() //End all surgeries. update_revive() - if(species.name != "Skeleton" && (SKELETON in mutations)) + if(!isskeleton(src) && (SKELETON in mutations)) mutations.Remove(SKELETON) if(NOCLONE in mutations) mutations.Remove(NOCLONE) @@ -1236,7 +1233,7 @@ ..() /mob/living/carbon/human/generate_name() - name = species.makeName(gender,src) + name = dna.species.get_random_name(gender) real_name = name if(dna) dna.real_name = name @@ -1275,88 +1272,90 @@ else to_chat(usr, "[self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)].") -/mob/living/carbon/human/proc/set_species(var/new_species, var/default_colour, var/delay_icon_update = 0) - var/datum/species/oldspecies = species - var/datum/species/NS = all_species[new_species] - if(!dna) - if(!new_species) - new_species = "Human" - else - if(!new_species) - new_species = dna.species - else - dna.species = new_species - - if(species) - if(species.name && species.name == new_species) +/mob/living/carbon/human/proc/set_species(datum/species/new_species, default_colour, delay_icon_update = FALSE, skip_same_check = FALSE) + if(!skip_same_check) + if(dna.species.name == initial(new_species.name)) return - - if(species.language) - remove_language(species.language) - - if(species.default_language) - remove_language(species.default_language) - - if(gender == PLURAL && NS.has_gender) - change_gender(pick(MALE,FEMALE)) - species.handle_pre_change(src) - - species = all_species[new_species] + var/datum/species/oldspecies = dna.species if(oldspecies) + if(oldspecies.language) + remove_language(oldspecies.language) + + if(oldspecies.default_language) + remove_language(oldspecies.default_language) + + if(gender == PLURAL && oldspecies.has_gender) + change_gender(pick(MALE, FEMALE)) + if(oldspecies.default_genes.len) - oldspecies.handle_dna(src,1) // Remove any genes that belong to the old species + oldspecies.handle_dna(src, TRUE) // Remove any genes that belong to the old species - tail = species.tail + oldspecies.on_species_loss(src) - maxHealth = species.total_health + dna.species = new new_species() - if(species.language) - add_language(species.language) + tail = dna.species.tail - if(species.default_language) - add_language(species.default_language) + maxHealth = dna.species.total_health - hunger_drain = species.hunger_drain - digestion_ratio = species.digestion_ratio + if(dna.species.language) + add_language(dna.species.language) - if(species.base_color && default_colour) + if(dna.species.default_language) + add_language(dna.species.default_language) + + hunger_drain = dna.species.hunger_drain + digestion_ratio = dna.species.digestion_ratio + + if(dna.species.base_color && default_colour) //Apply colour. - skin_colour = species.base_color + skin_colour = dna.species.base_color else skin_colour = "#000000" - if(!(species.bodyflags & HAS_SKIN_TONE)) + if(!(dna.species.bodyflags & HAS_SKIN_TONE)) s_tone = 0 - species.create_organs(src) + var/list/thing_to_check = list(slot_wear_mask, slot_head, slot_shoes, slot_gloves, slot_l_ear, slot_r_ear, slot_glasses, slot_l_hand, slot_r_hand) + var/list/kept_items[0] + + for(var/thing in thing_to_check) + var/obj/item/I = get_item_by_slot(thing) + if(I) + kept_items[I] = thing + + dna.species.create_organs(src) + + for(var/thing in kept_items) + equip_to_slot_or_del(thing, kept_items[thing]) //Handle default hair/head accessories for created mobs. var/obj/item/organ/external/head/H = get_organ("head") - if(species.default_hair) - H.h_style = species.default_hair + if(dna.species.default_hair) + H.h_style = dna.species.default_hair else H.h_style = "Bald" - if(species.default_fhair) - H.f_style = species.default_fhair + if(dna.species.default_fhair) + H.f_style = dna.species.default_fhair else H.f_style = "Shaved" - if(species.default_headacc) - H.ha_style = species.default_headacc + if(dna.species.default_headacc) + H.ha_style = dna.species.default_headacc else H.ha_style = "None" - if(species.default_hair_colour) + if(dna.species.default_hair_colour) //Apply colour. - H.hair_colour = species.default_hair_colour + H.hair_colour = dna.species.default_hair_colour else H.hair_colour = "#000000" - if(species.default_fhair_colour) - H.facial_colour = species.default_fhair_colour + if(dna.species.default_fhair_colour) + H.facial_colour = dna.species.default_fhair_colour else H.facial_colour = "#000000" - if(species.default_headacc_colour) - H.headacc_colour = species.default_headacc_colour + if(dna.species.default_headacc_colour) + H.headacc_colour = dna.species.default_headacc_colour else H.headacc_colour = "#000000" @@ -1364,43 +1363,39 @@ m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. body_accessory = null - if(!dna) - dna = new /datum/dna(null) - dna.species = species.name - dna.real_name = real_name + dna.real_name = real_name - species.handle_post_spawn(src) + dna.species.on_species_gain(src) - see_in_dark = species.get_resultant_darksight(src) + see_in_dark = dna.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. + dna.species.handle_dna(src) //Give them whatever special dna business they got. update_client_colour(0) - spawn(0) - overlays.Cut() - update_mutantrace(1) - regenerate_icons() - if(!delay_icon_update) UpdateAppearance() - if(species) - return 1 + overlays.Cut() + update_mutantrace(1) + regenerate_icons() + + if(dna.species) + return TRUE else - return 0 + return FALSE /mob/living/carbon/human/get_default_language() if(default_language) return default_language - if(!species) + if(!dna.species) return null - return species.default_language ? all_languages[species.default_language] : null + return dna.species.default_language ? all_languages[dna.species.default_language] : null /mob/living/carbon/human/proc/bloody_doodle() set category = "IC" @@ -1452,127 +1447,11 @@ W.message = message W.add_fingerprint(src) -// Allows IPC's to change their monitor display -/mob/living/carbon/human/proc/change_monitor() - set category = "IC" - set name = "Change Monitor/Optical Display" - set desc = "Change the display on your monitor or the colour of your optics." - - if(incapacitated()) - to_chat(src, "You cannot change your monitor or optical display in your current state.") - return - - var/obj/item/organ/external/head/head_organ = get_organ("head") - if(!head_organ) //If the rock'em-sock'em robot's head came off during a fight, they shouldn't be able to change their screen/optics. - to_chat(src, "Where's your head at? Can't change your monitor/display without one.") - return - - if(species.bodyflags & ALL_RPARTS) //If they can have a fully cybernetic body... - var/datum/robolimb/robohead = all_robolimbs[head_organ.model] - if(!head_organ) - return - if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics! - var/optic_colour = input(src, "Select optic colour", m_colours["head"]) as color|null - if(incapacitated()) - to_chat(src, "You were interrupted while changing the colour of your optics.") - return - if(optic_colour) - change_markings(optic_colour, "head") - - else if(robohead.is_monitor) //Means that the character's head is a monitor (has a screen). Time to customize. - var/list/hair = list() - for(var/i in hair_styles_public_list) - var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] - if((head_organ.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. - hair += i - - var/new_style = input(src, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair - if(incapacitated()) - to_chat(src, "You were interrupted while changing your monitor display.") - return - if(new_style) - change_hair(new_style) - -//Putting a couple of procs here that I don't know where else to dump. -//Mostly going to be used for Vox and Vox Armalis, but other human mobs might like them (for adminbuse). -/mob/living/carbon/human/proc/leap() - set category = "Abilities" - set name = "Leap" - set desc = "Leap at a target and grab them aggressively." - - if(last_special > world.time) - return - - if(stat || paralysis || stunned || weakened || lying || restrained() || buckled) - to_chat(src, "You cannot leap in your current state.") - return - - var/list/choices = list() - for(var/mob/living/M in view(6,src)) - if(!istype(M,/mob/living/silicon)) - choices += M - choices -= src - - var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices - - if(!T || !src || src.stat) return - - if(get_dist(get_turf(T), get_turf(src)) > 6) return - - if(last_special > world.time) - return - - if(!canmove) - to_chat(src, "You cannot leap in your current state.") - return - - last_special = world.time + 75 - status_flags |= LEAPING - - src.visible_message("\The [src] leaps at [T]!") - src.throw_at(get_step(get_turf(T),get_turf(src)), 5, 1, src) - playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) - - sleep(5) - - if(status_flags & LEAPING) status_flags &= ~LEAPING - - if(!src.Adjacent(T)) - to_chat(src, "You miss!") - return - - T.Weaken(5) - - //Only official raider vox get the grab and no self-prone." - if(src.mind && src.mind.special_role != "Vox Raider") - src.Weaken(5) - return - - var/use_hand = "left" - if(l_hand) - if(r_hand) - to_chat(src, "You need to have one hand free to grab someone.") - return - else - use_hand = "right" - - src.visible_message("\The [src] seizes [T] aggressively!") - - var/obj/item/grab/G = new(src,T) - if(use_hand == "left") - l_hand = G - else - r_hand = G - - G.state = GRAB_AGGRESSIVE - G.icon_state = "grabbed1" - G.synch() - /mob/living/carbon/human/proc/get_eyecon() var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) var/obj/item/organ/internal/cyberimp/eyes/eye_implant = get_int_organ(/obj/item/organ/internal/cyberimp/eyes) - if(istype(species) && species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) + if(istype(dna.species) && dna.species.eyes) + var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', dna.species.eyes) if(eye_implant) //Eye implants override native DNA eye colo(u)r eyes_icon = eye_implant.generate_icon() else if(eyes) @@ -1603,43 +1482,6 @@ Eyes need to have significantly high darksight to shine unless the mob has the X return TRUE -/mob/living/carbon/human/proc/gut() - set category = "Abilities" - set name = "Gut" - set desc = "While grabbing someone aggressively, rip their guts out or tear them apart." - - if(last_special > world.time) - return - - if(!canmove) - to_chat(src, "You cannot do that in your current state.") - return - - var/obj/item/grab/G = locate() in src - if(!G || !istype(G)) - to_chat(src, "You are not grabbing anyone.") - return - - if(G.state < GRAB_AGGRESSIVE) - to_chat(src, "You must have an aggressive grab to gut your prey!") - return - - last_special = world.time + 50 - - visible_message("\The [src] rips viciously at \the [G.affecting]'s body with its claws!") - - if(istype(G.affecting,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = G.affecting - H.apply_damage(50,BRUTE) - if(H.stat == 2) - H.gib() - else - var/mob/living/M = G.affecting - if(!istype(M)) return //wut - M.apply_damage(50,BRUTE) - if(M.stat == 2) - M.gib() - /mob/living/carbon/human/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor) if(judgebot.emagged == 2) return 10 //Everyone is a criminal! @@ -1778,7 +1620,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X /mob/living/carbon/human/IsAdvancedToolUser() - if(species.has_fine_manipulation) + if(dna.species.has_fine_manipulation) return 1 return 0 @@ -1813,7 +1655,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X return 1 /mob/living/carbon/human/can_eat(flags = 255) - return species && (species.dietflags & flags) + return dna.species && (dna.species.dietflags & flags) /mob/living/carbon/human/selfFeed(var/obj/item/reagent_containers/food/toEat, fullness) if(!check_has_mouth()) @@ -1823,14 +1665,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X /mob/living/carbon/human/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness) if(!check_has_mouth()) - if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (get_species() == "Machine")))) + if(!((istype(toEat, /obj/item/reagent_containers/food/drinks) && (ismachine(src))))) to_chat(user, "Where do you intend to put \the [toEat]? \The [src] doesn't have a mouth!") return 0 return ..() /mob/living/carbon/human/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink) if(!check_has_mouth()) - if(!get_species() == "Machine") + if(!ismachine(src)) to_chat(src, "Where do you intend to put \the [src]? You don't have a mouth!") return 0 else @@ -1874,7 +1716,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X . |= A.GetAccess() /mob/living/carbon/human/is_mechanical() - return ..() || (species.bodyflags & ALL_RPARTS) != 0 + return ..() || (dna.species.bodyflags & ALL_RPARTS) != 0 /mob/living/carbon/human/can_use_guns(var/obj/item/gun/G) . = ..() @@ -1883,7 +1725,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(HULK in mutations) to_chat(src, "Your meaty finger is much too large for the trigger guard!") return 0 - if(NOGUNS in species.species_traits) + if(NOGUNS in dna.species.species_traits) to_chat(src, "Your fingers don't fit in the trigger guard!") return 0 @@ -1950,7 +1792,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X dna.deserialize(data["dna"]) real_name = dna.real_name name = real_name - set_species(dna.species) + set_species(dna.species.type, skip_same_check = TRUE) age = data["age"] undershirt = data["ushirt"] underwear = data["uwear"] @@ -2012,8 +1854,8 @@ Eyes need to have significantly high darksight to shine unless the mob has the X . += "---" /mob/living/carbon/human/get_taste_sensitivity() - if(species) - return species.taste_sensitivity + if(dna.species) + return dna.species.taste_sensitivity else return 1 diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index c2c16382995..80c128ee07f 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -17,7 +17,7 @@ //TODO: fix husking if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD) ChangeToHusk() - if(species.can_revive_by_healing) + if(dna.species.can_revive_by_healing) var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain) if(B) if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && stat == DEAD && getBrainLoss()<120) @@ -32,11 +32,11 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.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 + if(dna.species) + amount = amount * dna.species.brain_mod sponge.receive_damage(amount, 1) brainloss = sponge.damage else @@ -48,11 +48,11 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.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 + if(dna.species) + amount = amount * dna.species.brain_mod sponge.damage = min(max(amount, 0), (maxHealth*2)) brainloss = sponge.damage else @@ -64,7 +64,7 @@ if(status_flags & GODMODE) return 0 //godmode - if(species && species.has_organ["brain"]) + if(dna.species && dna.species.has_organ["brain"]) var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) brainloss = min(sponge.damage,maxHealth*2) @@ -89,24 +89,24 @@ /mob/living/carbon/human/adjustBruteLoss(amount, damage_source) - if(species) - amount = amount * species.brute_mod + if(dna.species) + amount = amount * dna.species.brute_mod if(amount > 0) take_overall_damage(amount, 0, used_weapon = damage_source) else heal_overall_damage(-amount, 0) /mob/living/carbon/human/adjustFireLoss(amount, damage_source) - if(species) - amount = amount * species.burn_mod + if(dna.species) + amount = amount * dna.species.burn_mod if(amount > 0) take_overall_damage(0, amount, used_weapon = damage_source) else heal_overall_damage(0, -amount) /mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null) - if(species) - amount = amount * species.brute_mod + if(dna.species) + amount = amount * dna.species.brute_mod if(organ_name in bodyparts_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -119,8 +119,8 @@ /mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null) - if(species) - amount = amount * species.burn_mod + if(dna.species) + amount = amount * dna.species.burn_mod if(organ_name in bodyparts_by_name) var/obj/item/organ/external/O = get_organ(organ_name) @@ -139,8 +139,8 @@ ..() /mob/living/carbon/human/adjustCloneLoss(amount) - if(species) - amount = amount * species.clone_mod + if(dna.species) + amount = amount * dna.species.clone_mod ..() var/heal_prob = max(0, 80 - getCloneLoss()) @@ -179,23 +179,23 @@ // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/adjustOxyLoss(amount) - if(species) - amount = amount * species.oxy_mod + if(dna.species) + amount = amount * dna.species.oxy_mod ..() /mob/living/carbon/human/setOxyLoss(amount) - if(species) - amount = amount * species.oxy_mod + if(dna.species) + amount = amount * dna.species.oxy_mod ..() /mob/living/carbon/human/adjustToxLoss(amount) - if(species) - amount = amount * species.tox_mod + if(dna.species) + amount = amount * dna.species.tox_mod ..() /mob/living/carbon/human/setToxLoss(amount) - if(species) - amount = amount * species.tox_mod + if(dna.species) + amount = amount * dna.species.tox_mod ..() //////////////////////////////////////////// @@ -352,8 +352,8 @@ This function restores all organs. switch(damagetype) if(BRUTE) damageoverlaytemp = 20 - if(species) - damage = damage * species.brute_mod + if(dna.species) + damage = damage * dna.species.brute_mod if(organ.receive_damage(damage, 0, sharp, used_weapon)) UpdateDamageIcon() @@ -376,8 +376,8 @@ This function restores all organs. if(BURN) damageoverlaytemp = 20 - if(species) - damage = damage * species.burn_mod + if(dna.species) + damage = damage * dna.species.burn_mod if(organ.receive_damage(0, damage, sharp, used_weapon)) UpdateDamageIcon() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 2991e0a7111..6c2bb844155 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -354,7 +354,7 @@ emp_act if(check_shields(user, 15, "the [hulk_verb]ing")) return ..(user, TRUE) - playsound(loc, user.species.unarmed.attack_sound, 25, 1, -1) + playsound(loc, user.dna.species.unarmed.attack_sound, 25, 1, -1) var/message = "[user] has [hulk_verb]ed [src]!" visible_message("[message]", "[message]") adjustBruteLoss(15) @@ -365,7 +365,7 @@ emp_act return if(ishuman(user)) var/mob/living/carbon/human/H = user - species.spec_attack_hand(H, src) + dna.species.spec_attack_hand(H, src) /mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) if(..()) //successful larva bite. @@ -494,7 +494,7 @@ emp_act /mob/living/carbon/human/water_act(volume, temperature, source) ..() - species.water_act(src,volume,temperature,source) + dna.species.water_act(src,volume,temperature,source) /mob/living/carbon/human/is_eyes_covered(check_glasses = TRUE, check_head = TRUE, check_mask = TRUE) if(check_glasses && glasses && (glasses.flags_cover & GLASSESCOVERSEYES)) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index a7fcc6874a2..96693a0d086 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,7 @@ var/global/default_martial_art = new/datum/martial_art /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD,GLAND_HUD) //Marking colour and style var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000. diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index a835133f4d0..71a5f0396a1 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -2,7 +2,7 @@ . = 0 . += ..() . += config.human_delay - . += species.movement_delay(src) + . += dna.species.movement_delay(src) /mob/living/carbon/human/Process_Spacemove(movement_dir = 0) @@ -39,12 +39,12 @@ if(!lying && !buckled && !throwing) for(var/obj/item/organ/external/splinted in splinted_limbs) splinted.update_splints() - + if(!has_gravity(loc)) return - + var/obj/item/clothing/shoes/S = shoes - + //Bloody footprints var/turf/T = get_turf(src) var/obj/item/organ/external/l_foot = get_organ("l_foot") @@ -119,7 +119,7 @@ if(step_count % 3) //this basically says, every three moves make a noise return 0 //1st - none, 1%3==1, 2nd - none, 2%3==2, 3rd - noise, 3%3==0 - if(species.silent_steps) + if(dna.species.silent_steps) return 0 //species is silent playsound(T, S, volume, 1, range) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 3f478e65d40..5dcae16b87a 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -62,7 +62,7 @@ // standing is poor if(stance_damage >= 8) if(!(lying || resting)) - if(!(NO_PAIN in species.species_traits)) + if(!(NO_PAIN in dna.species.species_traits)) emote("scream") custom_emote(1, "collapses!") Weaken(5) //can't emote while weakened, apparently. @@ -90,7 +90,7 @@ continue var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ") - custom_emote(1, "[(NO_PAIN in species.species_traits) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!") + custom_emote(1, "[(NO_PAIN in dna.species.species_traits) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!") else if(E.is_malfunctioning()) diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index a93fd9e8635..763a5ef15be 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -128,7 +128,7 @@ //this is here because this has no client/prefs/brain whatever. age = rand(AGE_MIN, AGE_MAX) change_gender(pick("male", "female")) - rename_character(real_name, species.get_random_name(gender)) + rename_character(real_name, dna.species.get_random_name(gender)) //job handling myjob = new default_job() job = myjob.title @@ -208,9 +208,9 @@ var/datum/dna/toDoppel = chosen.dna T.real_name = toDoppel.real_name - T.set_species(chosen.species.name) - T.body_accessory = chosen.body_accessory + T.set_species(chosen.dna.species.type) T.dna = toDoppel.Clone() + T.body_accessory = chosen.body_accessory T.UpdateAppearance() domutcheck(T) @@ -245,7 +245,7 @@ MYID.age = age MYID.registered_name = real_name MYID.photo = get_id_photo(src) - MYID.access = Path_ID.access // Automatons have strange powers... strange indeed + MYID.access = Path_ID.access.Copy() // Automatons have strange powers... strange indeed RPID = new(src) RPID.name = "[real_name]'s ID Card ([alt_title])" @@ -257,7 +257,10 @@ RPID.photo = get_id_photo(src) RPID.access = myjob.get_access() - equip_to_slot_or_del(MYID, slot_wear_id) + if(wear_id) + qdel(wear_id) + if(!equip_to_slot_or_del(MYID, slot_wear_id)) + create_attack_log("Deleted ID due to slot contention") if(wear_pda) MYPDA = wear_pda else @@ -403,8 +406,12 @@ if(!hud_used) hud_used = new /datum/hud/human(src) -/mob/living/carbon/human/interactive/New(var/new_loc, var/new_species = null) +/mob/living/carbon/human/interactive/Initialize() ..() + return INITIALIZE_HINT_LATELOAD + +/mob/living/carbon/human/interactive/LateInitialize() + . = ..() snpc_list += src create_mob_hud() @@ -427,6 +434,7 @@ /mob/living/carbon/human/interactive/Destroy() hear_radio_list -= src snpc_list -= src + npc_master.removeBot(src) return ..() /mob/living/carbon/human/interactive/proc/retalTarget(mob/living/target) diff --git a/code/modules/mob/living/carbon/human/interactive/prefabs.dm b/code/modules/mob/living/carbon/human/interactive/prefabs.dm index 6553bb26b70..cee716b66ec 100644 --- a/code/modules/mob/living/carbon/human/interactive/prefabs.dm +++ b/code/modules/mob/living/carbon/human/interactive/prefabs.dm @@ -1,18 +1,18 @@ -/mob/living/carbon/human/interactive/angry/New() +/mob/living/carbon/human/interactive/angry/Initialize(mapload) TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_MEAN faction += "bot_angry" - ..() + return ..() -/mob/living/carbon/human/interactive/friendly/New() +/mob/living/carbon/human/interactive/friendly/Initialize(mapload) TRAITS |= TRAIT_FRIENDLY TRAITS |= TRAIT_UNROBUST faction += "bot_friendly" faction += "neutral" functions -= "combat" - ..() + return ..() -/mob/living/carbon/human/interactive/greytide/New() +/mob/living/carbon/human/interactive/greytide/Initialize(mapload) TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_MEAN TRAITS |= TRAIT_THIEVING @@ -21,4 +21,4 @@ targetInterestShift = 2 // likewise faction += "bot_grey" graytide = 1 - ..() \ No newline at end of file + return ..() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 882501c49f2..50848851646 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -419,7 +419,7 @@ ..(what, who, where, silent = is_silent) /mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0) - switch(species.handle_can_equip(I, slot, disable_warning, src)) + switch(dna.species.handle_can_equip(I, slot, disable_warning, src)) if(1) return 1 if(2) return 0 //if it returns 2, it wants no normal handling diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 2e9e9b88656..d577a02e2c4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -15,10 +15,10 @@ handle_heartbeat() handle_heartattack() handle_drunk() - species.handle_life(src) + dna.species.handle_life(src) if(!client) - species.handle_npc(src) + dna.species.handle_npc(src) if(stat != DEAD) //Stuff jammed in your limbs hurts @@ -178,7 +178,7 @@ if(gene_stability < GENETIC_DAMAGE_STAGE_3) gib() - if(!(RADIMMUNE in species.species_traits)) + if(!(RADIMMUNE in dna.species.species_traits)) if(radiation) radiation = Clamp(radiation, 0, 200) @@ -238,7 +238,7 @@ chest.add_autopsy_data("Radiation Poisoning", autopsy_damage) /mob/living/carbon/human/breathe() - if(!species.breathe(src)) + if(!dna.species.breathe(src)) ..() /mob/living/carbon/human/check_breath(datum/gas_mixture/breath) @@ -253,8 +253,8 @@ failed_last_breath = TRUE - if(species) - var/datum/species/S = species + if(dna.species) + var/datum/species/S = dna.species if(S.breathid == "o2") throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) @@ -332,39 +332,39 @@ bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. - if(bodytemperature > species.heat_level_1) + if(bodytemperature > dna.species.heat_level_1) //Body temperature is too hot. if(status_flags & GODMODE) return 1 //godmode - var/mult = species.heatmod + var/mult = dna.species.heatmod - if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2) + if(bodytemperature >= dna.species.heat_level_1 && bodytemperature <= dna.species.heat_level_2) throw_alert("temp", /obj/screen/alert/hot, 1) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") - if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3) + if(bodytemperature > dna.species.heat_level_2 && bodytemperature <= dna.species.heat_level_3) throw_alert("temp", /obj/screen/alert/hot, 2) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") - if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY) + if(bodytemperature > dna.species.heat_level_3 && bodytemperature < INFINITY) throw_alert("temp", /obj/screen/alert/hot, 3) if(on_fire) take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire") else take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature") - else if(bodytemperature < species.cold_level_1) + else if(bodytemperature < dna.species.cold_level_1) if(status_flags & GODMODE) return 1 if(stat == DEAD) return 1 if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) - var/mult = species.coldmod - if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1) + var/mult = dna.species.coldmod + if(bodytemperature >= dna.species.cold_level_2 && bodytemperature <= dna.species.cold_level_1) throw_alert("temp", /obj/screen/alert/cold, 1) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature") - if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2) + if(bodytemperature >= dna.species.cold_level_3 && bodytemperature < dna.species.cold_level_2) throw_alert("temp", /obj/screen/alert/cold, 2) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature") - if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3) + if(bodytemperature > -INFINITY && bodytemperature < dna.species.cold_level_3) throw_alert("temp", /obj/screen/alert/cold, 3) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature") else @@ -379,18 +379,18 @@ var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. if(status_flags & GODMODE) return 1 //godmode - if(adjusted_pressure >= species.hazard_high_pressure) + if(adjusted_pressure >= dna.species.hazard_high_pressure) if(!(HEATRES in mutations)) - var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) + var/pressure_damage = min( ( (adjusted_pressure / dna.species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure") throw_alert("pressure", /obj/screen/alert/highpressure, 2) else clear_alert("pressure") - else if(adjusted_pressure >= species.warning_high_pressure) + else if(adjusted_pressure >= dna.species.warning_high_pressure) throw_alert("pressure", /obj/screen/alert/highpressure, 1) - else if(adjusted_pressure >= species.warning_low_pressure) + else if(adjusted_pressure >= dna.species.warning_low_pressure) clear_alert("pressure") - else if(adjusted_pressure >= species.hazard_low_pressure) + else if(adjusted_pressure >= dna.species.hazard_low_pressure) throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else if(COLDRES in mutations) @@ -430,13 +430,13 @@ //END FIRE CODE /mob/living/carbon/human/proc/stabilize_temperature_from_calories() - var/body_temperature_difference = species.body_temperature - bodytemperature + var/body_temperature_difference = dna.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(bodytemperature <= dna.species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) - if(bodytemperature >= species.cold_level_1 && bodytemperature <= species.heat_level_1) + if(bodytemperature >= dna.species.cold_level_1 && bodytemperature <= dna.species.heat_level_1) 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. + if(bodytemperature >= dna.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...~ bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers @@ -588,7 +588,7 @@ return 0 //godmode //The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered. - if(CAN_BE_FAT in species.species_traits) + if(CAN_BE_FAT in dna.species.species_traits) if(FAT in mutations) if(overeatduration < 100) becomeSlim() @@ -652,7 +652,7 @@ AdjustDizzy(-3) AdjustJitter(-3) - if(NO_INTORGANS in species.species_traits) + if(NO_INTORGANS in dna.species.species_traits) return handle_trace_chems() @@ -766,10 +766,10 @@ //Vision //god knows why this is here var/obj/item/organ/vision - if(species.vision_organ) - vision = get_int_organ(species.vision_organ) + if(dna.species.vision_organ) + vision = get_int_organ(dna.species.vision_organ) - if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. + if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means. SetEyeBlind(0) blinded = 0 SetEyeBlurry(0) @@ -860,10 +860,10 @@ remoteview_target = null reset_perspective(null) - species.handle_vision(src) + dna.species.handle_vision(src) /mob/living/carbon/human/handle_hud_icons() - species.handle_hud_icons(src) + dna.species.handle_hud_icons(src) /mob/living/carbon/human/handle_random_events() // Puke if toxloss is too high @@ -907,7 +907,7 @@ if(times_fired % 5 == 1) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load) - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) return PULSE_NONE //No blood, no pulse. if(stat == DEAD) @@ -977,7 +977,7 @@ var/obj/item/clothing/mask/M = H.wear_mask if(M && (M.flags_cover & MASKCOVERSMOUTH)) return - if(NO_BREATHE in H.species.species_traits) + if(NO_BREATHE in H.dna.species.species_traits) return //no puking if you can't smell! // Humans can lack a mind datum, y'know if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner")) @@ -1054,9 +1054,9 @@ /mob/living/carbon/human/proc/can_heartattack() - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) return FALSE - if(NO_INTORGANS in species.species_traits) + if(NO_INTORGANS in dna.species.species_traits) return FALSE return TRUE diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm index d4b160509ea..e16c67a56d0 100644 --- a/code/modules/mob/living/carbon/human/login.dm +++ b/code/modules/mob/living/carbon/human/login.dm @@ -1,7 +1,7 @@ /mob/living/carbon/human/Login() ..() - if(species && species.ventcrawler) + if(dna.species && dna.species.ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") update_pipe_vision() return diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 7657a3be3be..7d408ce9199 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -42,7 +42,7 @@ if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak. return 1 - if(species.can_understand(other)) + if(dna.species.can_understand(other)) return 1 //These only pertain to common. Languages are handled by mob/say_understands() @@ -87,7 +87,7 @@ /mob/living/carbon/human/IsVocal() // how do species that don't breathe talk? magic, that's what. - var/breathes = (!(NO_BREATHE in species.species_traits)) + var/breathes = (!(NO_BREATHE in dna.species.species_traits)) var/obj/item/organ/internal/L = get_organ_slot("lungs") if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD)) return FALSE @@ -219,8 +219,8 @@ /mob/living/carbon/human/handle_speech_sound() var/list/returns[2] - if(species.speech_sounds && prob(species.speech_chance)) - returns[1] = sound(pick(species.speech_sounds)) + if(dna.species.speech_sounds && prob(dna.species.speech_chance)) + returns[1] = sound(pick(dna.species.speech_sounds)) returns[2] = 50 return returns diff --git a/code/modules/mob/living/carbon/human/shock.dm b/code/modules/mob/living/carbon/human/shock.dm index d8dc9356de7..e2d5dd79cec 100644 --- a/code/modules/mob/living/carbon/human/shock.dm +++ b/code/modules/mob/living/carbon/human/shock.dm @@ -23,7 +23,7 @@ /mob/living/carbon/human/proc/handle_shock() if(status_flags & GODMODE) //godmode return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return updateshock() diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/_species.dm similarity index 91% rename from code/modules/mob/living/carbon/human/species/species.dm rename to code/modules/mob/living/carbon/human/species/_species.dm index 139f2f7c9bb..c11d84451f9 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -1,11 +1,6 @@ -/* - Datum-based species. Should make for much cleaner and easier to maintain mutantrace code. -*/ - /datum/species var/name // Species name. var/name_plural // Pluralized name (since "[name]s" is not always valid) - var/path // Species path var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. @@ -18,8 +13,8 @@ var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. var/butt_sprite = "human" - var/primitive_form // Lesser form, if any (ie. monkey for humans) - var/greater_form // Greater form, if any, ie. human for monkeys. + var/datum/species/primitive_form = null // Lesser form, if any (ie. monkey for humans) + var/datum/species/greater_form = null // Greater form, if any, ie. human for monkeys. var/tail // Name of tail image in species effects icon file. var/datum/unarmed_attack/unarmed //For empty hand harm-intent attack var/unarmed_type = /datum/unarmed_attack @@ -80,11 +75,10 @@ var/clothing_flags = 0 // Underwear and socks. var/exotic_blood + var/skinned_type var/bodyflags = 0 var/dietflags = 0 // Make sure you set this, otherwise it won't be able to digest a lot of foods - var/list/abilities = list() // For species-derived or admin-given powers - var/blood_color = "#A10808" //Red. var/flesh_color = "#FFC896" //Pink. var/single_gib_type = /obj/effect/decal/cleanable/blood/gibs @@ -94,10 +88,13 @@ //Used in icon caching. var/race_key = 0 var/icon/icon_template + var/is_small var/show_ssd = 1 var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them var/has_gender = TRUE + var/blacklisted = FALSE + var/dangerous_existence = FALSE //Death vars. var/death_message = "seizes up and falls limp, their eyes dead and lifeless..." @@ -154,9 +151,7 @@ "l_hand" = list("path" = /obj/item/organ/external/hand), "r_hand" = list("path" = /obj/item/organ/external/hand/right), "l_foot" = list("path" = /obj/item/organ/external/foot), - "r_foot" = list("path" = /obj/item/organ/external/foot/right) - ) - var/list/proc/species_abilities = list() + "r_foot" = list("path" = /obj/item/organ/external/foot/right)) /datum/species/New() //If the species has eyes, they are the default vision organ @@ -165,11 +160,11 @@ unarmed = new unarmed_type() -/datum/species/proc/get_random_name(var/gender) +/datum/species/proc/get_random_name(gender) var/datum/language/species_language = all_languages[language] return species_language.get_random_name(gender) -/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. +/datum/species/proc/create_organs(mob/living/carbon/human/H) //Handles creation of mob organs. QDEL_LIST(H.internal_organs) QDEL_LIST(H.bodyparts) @@ -262,27 +257,14 @@ . -= 2 return . -/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment. - grant_abilities(C) +/datum/species/proc/on_species_gain(mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment. return -/datum/species/proc/updatespeciescolor(var/mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. - return - -/datum/species/proc/grant_abilities(var/mob/living/carbon/human/H) - for(var/proc/ability in species_abilities) - H.verbs += ability - return - -/datum/species/proc/handle_pre_change(var/mob/living/carbon/human/H) - if(H.butcher_results)//clear it out so we don't butcher a actual human. +/datum/species/proc/on_species_loss(mob/living/carbon/human/H) + if(H.butcher_results) //clear it out so we don't butcher a actual human. H.butcher_results = null - remove_abilities(H) - return -/datum/species/proc/remove_abilities(var/mob/living/carbon/human/H) - for(var/proc/ability in species_abilities) - H.verbs -= ability +/datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. return // Do species-specific reagent handling here @@ -294,47 +276,42 @@ if(R.id == exotic_blood) H.blood_volume = min(H.blood_volume + round(R.volume, 0.1), BLOOD_VOLUME_NORMAL) H.reagents.del_reagent(R.id) - return 0 - return 1 + return FALSE + return TRUE // For special snowflake species effects // (Slime People changing color based on the reagents they consume) -/datum/species/proc/handle_life(var/mob/living/carbon/human/H) +/datum/species/proc/handle_life(mob/living/carbon/human/H) if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations)) H.setOxyLoss(0) H.SetLoseBreath(0) -/datum/species/proc/handle_dna(var/mob/living/carbon/C, var/remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here +/datum/species/proc/handle_dna(mob/living/carbon/human/H, remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here return -// Used for species-specific names (Vox, etc) -/datum/species/proc/makeName(var/gender,var/mob/living/carbon/human/H=null) - if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) - -/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). +/datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). return /datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.help_act(user, target))//adminfu only... - return 1 + return TRUE if(target.health >= config.health_threshold_crit) target.help_shake_act(user) - return 1 + return TRUE else user.do_cpr(target) /datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.grab_act(user, target)) - return 1 + return TRUE else target.grabbedby(user) - return 1 + return TRUE /datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) //Vampire code if(user.mind && user.mind.vampire && (user.mind in ticker.mode.vampires) && !user.mind.vampire.draining && user.zone_sel && user.zone_sel.selecting == "head" && target != user) - if((NO_BLOOD in target.species.species_traits) || target.species.exotic_blood || !target.blood_volume) + if((NO_BLOOD in target.dna.species.species_traits) || target.dna.species.exotic_blood || !target.blood_volume) to_chat(user, "They have no blood!") return if(target.mind && target.mind.vampire && (target.mind in ticker.mode.vampires)) @@ -352,9 +329,9 @@ return //end vampire codes if(attacker_style && attacker_style.harm_act(user, target)) - return 1 + return TRUE else - var/datum/unarmed_attack/attack = user.species.unarmed + var/datum/unarmed_attack/attack = user.dna.species.unarmed user.do_attack_animation(target, attack.animation_type) add_attack_logs(user, target, "Melee attacked with fists", target.ckey ? null : ATKLOG_ALL) @@ -364,12 +341,12 @@ else target.LAssailant = user - var/damage = rand(user.species.punchdamagelow, user.species.punchdamagehigh) + var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh) damage += attack.damage if(!damage) playsound(target.loc, attack.miss_sound, 25, 1, -1) target.visible_message("[user] tried to [pick(attack.attack_verb)] [target]!") - return 0 + return FALSE var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting)) @@ -380,7 +357,7 @@ target.visible_message("[user] [pick(attack.attack_verb)]ed [target]!") target.apply_damage(damage, BRUTE, affecting, armor_block, sharp = attack.sharp) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. - if((target.stat != DEAD) && damage >= user.species.punchstunthreshold) + if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold) target.visible_message("[user] has weakened [target]!", \ "[user] has weakened [target]!") target.apply_effect(4, WEAKEN, armor_block) @@ -390,7 +367,7 @@ /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(attacker_style && attacker_style.disarm_act(user, target)) - return 1 + return TRUE else add_attack_logs(user, target, "Disarmed", ATKLOG_ALL) user.do_attack_animation(target, ATTACK_EFFECT_DISARM) @@ -463,7 +440,7 @@ if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK)) add_attack_logs(M, H, "Melee attacked with fists (miss/block)") H.visible_message("[M] attempted to touch [H]!") - return 0 + return FALSE switch(M.a_intent) if(INTENT_HELP) @@ -487,11 +464,11 @@ /datum/species/proc/after_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE) return -/datum/species/proc/can_understand(var/mob/other) +/datum/species/proc/can_understand(mob/other) return // Called in life() when the mob has no client. -/datum/species/proc/handle_npc(var/mob/living/carbon/human/H) +/datum/species/proc/handle_npc(mob/living/carbon/human/H) return //Species unarmed attacks @@ -525,7 +502,7 @@ damage = 6 /datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user) - return 0 + return FALSE /datum/species/proc/handle_vision(mob/living/carbon/human/H) // Right now this just handles blind, blurry, and similar states @@ -631,7 +608,7 @@ Returns the path corresponding to the corresponding organ It'll return null if the organ doesn't correspond, so include null checks when using this! */ //Fethas Todo:Do i need to redo this? -/datum/species/proc/return_organ(var/organ_slot) +/datum/species/proc/return_organ(organ_slot) if(!(organ_slot in has_organ)) return null return has_organ[organ_slot] @@ -730,3 +707,14 @@ It'll return null if the organ doesn't correspond, so include null checks when u /datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source) if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling + +/proc/get_random_species(species_name = FALSE) // Returns a random non black-listed or hazardous species, either as a string or datum + var/static/list/random_species = list() + if(!random_species.len) + for(var/thing in subtypesof(/datum/species)) + var/datum/species/S = thing + if(!initial(S.dangerous_existence) && !initial(S.blacklisted)) + random_species += initial(S.name) + var/picked_species = pick(random_species) + var/datum/species/selected_species = GLOB.all_species[picked_species] + return species_name ? picked_species : selected_species.type \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/abductor.dm b/code/modules/mob/living/carbon/human/species/abductor.dm index 8aeb6f88a3d..f51870d9e00 100644 --- a/code/modules/mob/living/carbon/human/species/abductor.dm +++ b/code/modules/mob/living/carbon/human/species/abductor.dm @@ -3,7 +3,6 @@ name_plural = "Abductors" icobase = 'icons/mob/human_races/r_abductor.dmi' deform = 'icons/mob/human_races/r_abductor.dmi' - path = /mob/living/carbon/human/abductor language = "Abductor Mindlink" default_language = "Abductor Mindlink" eyes = "blank_eyes" @@ -16,7 +15,7 @@ "eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight. ) - species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS) + species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE) oxy_mod = 0 @@ -27,14 +26,21 @@ female_scream_sound = 'sound/goonstation/voice/male_scream.ogg' female_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg') female_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' //Abductors always scream like guys + var/team = 1 + var/scientist = FALSE // vars to not pollute spieces list with castes /datum/species/abductor/can_understand(mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member - return 1 + return TRUE -/datum/species/abductor/handle_post_spawn(mob/living/carbon/human/H) +/datum/species/abductor/on_species_gain(mob/living/carbon/human/H) + ..() H.gender = NEUTER - if(H.mind) - H.mind.abductor = new /datum/abductor H.languages.Cut() //Under no condition should you be able to speak any language H.add_language("Abductor Mindlink") //other than over the abductor's own mindlink - return ..() + var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR] + abductor_hud.add_hud_to(H) + +/datum/species/abductor/on_species_loss(mob/living/carbon/human/H) + ..() + var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR] + abductor_hud.remove_hud_from(H) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/diona.dm b/code/modules/mob/living/carbon/human/species/diona.dm new file mode 100644 index 00000000000..6f53be4d3c8 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/diona.dm @@ -0,0 +1,113 @@ +/datum/species/diona + name = "Diona" + name_plural = "Dionaea" + icobase = 'icons/mob/human_races/r_diona.dmi' + deform = 'icons/mob/human_races/r_def_plant.dmi' + language = "Rootspeak" + speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] + speech_chance = 20 + unarmed_type = /datum/unarmed_attack/diona + //primitive_form = "Nymph" + slowdown = 5 + remains_type = /obj/effect/decal/cleanable/ash + + + warning_low_pressure = 50 + hazard_low_pressure = -1 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 300 + heat_level_2 = 340 + heat_level_3 = 400 + + blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ + species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ + there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ + Minoris primary being ringed with a cloud of singing space-station-sized entities.

    The Dionaea coexist peacefully with \ + all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ + even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ + water and other radiation." + + species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) + clothing_flags = HAS_SOCKS + default_hair_colour = "#000000" + dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary + taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + skinned_type = /obj/item/stack/sheet/wood + + 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" + butt_sprite = "diona" + + reagent_tag = PROCESS_ORG + + 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/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/eyes/diona + has_limbs = list( + "chest" = list("path" = /obj/item/organ/external/chest/diona), + "groin" = list("path" = /obj/item/organ/external/groin/diona), + "head" = list("path" = /obj/item/organ/external/head/diona), + "l_arm" = list("path" = /obj/item/organ/external/arm/diona), + "r_arm" = list("path" = /obj/item/organ/external/arm/right/diona), + "l_leg" = list("path" = /obj/item/organ/external/leg/diona), + "r_leg" = list("path" = /obj/item/organ/external/leg/right/diona), + "l_hand" = list("path" = /obj/item/organ/external/hand/diona), + "r_hand" = list("path" = /obj/item/organ/external/hand/right/diona), + "l_foot" = list("path" = /obj/item/organ/external/foot/diona), + "r_foot" = list("path" = /obj/item/organ/external/foot/right/diona) + ) + + suicide_messages = list( + "is losing branches!", + "pulls out a secret stash of herbicide and takes a hearty swig!", + "is pulling themselves apart!") + +/datum/species/diona/can_understand(mob/other) + if(istype(other, /mob/living/simple_animal/diona)) + return 1 + return 0 + +/datum/species/diona/on_species_gain(mob/living/carbon/human/H) + ..() + H.gender = NEUTER + +/datum/species/diona/handle_life(mob/living/carbon/human/H) + H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. + var/rads = H.radiation / 25 + H.radiation = max(H.radiation-rads, 0) + H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) + H.adjustBruteLoss(-(rads)) + H.adjustToxLoss(-(rads)) + + 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 + H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) + + 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)) + if(H.nutrition < NUTRITION_LEVEL_STARVING+50) + H.take_overall_damage(10,0) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/drask.dm b/code/modules/mob/living/carbon/human/species/drask.dm new file mode 100644 index 00000000000..7914c4e7d70 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/drask.dm @@ -0,0 +1,62 @@ +/datum/species/drask + name = "Drask" + name_plural = "Drask" + icobase = 'icons/mob/human_races/r_drask.dmi' + deform = 'icons/mob/human_races/r_drask.dmi' + language = "Orluum" + eyes = "drask_eyes_s" + + speech_sounds = list('sound/voice/DraskTalk.ogg') + speech_chance = 20 + male_scream_sound = 'sound/voice/DraskTalk2.ogg' + female_scream_sound = 'sound/voice/DraskTalk2.ogg' + male_cough_sounds = 'sound/voice/DraskCough.ogg' + female_cough_sounds = 'sound/voice/DraskCough.ogg' + male_sneeze_sound = 'sound/voice/DraskSneeze.ogg' + female_sneeze_sound = 'sound/voice/DraskSneeze.ogg' + + burn_mod = 2 + //exotic_blood = "cryoxadone" + body_temperature = 273 + + blurb = "Hailing from Hoorlm, planet outside what is usually considered a habitable \ + orbit, the Drask evolved to live in extreme cold. Their strange bodies seem \ + to operate better the colder their surroundings are, and can regenerate rapidly \ + when breathing supercooled gas.

    On their homeworld, the Drask live long lives \ + in their labyrinthine settlements, carved out beneath Hoorlm's icy surface, where the air \ + is of breathable density." + + suicide_messages = list( + "is self-warming with friction!", + "is jamming fingers through their big eyes!", + "is sucking in warm air!", + "is holding their breath!") + + species_traits = list(LIPS, IS_WHITELISTED) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT + bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS + dietflags = DIET_OMNI + + cold_level_1 = -1 //Default 260 - Lower is better + cold_level_2 = -1 //Default 200 + cold_level_3 = -1 //Default 120 + coldmod = -1 + + heat_level_1 = 300 //Default 360 - Higher is better + heat_level_2 = 340 //Default 400 + heat_level_3 = 400 //Default 460 + heatmod = 2 + + flesh_color = "#a3d4eb" + reagent_tag = PROCESS_ORG + base_color = "#a3d4eb" + blood_color = "#a3d4eb" + butt_sprite = "drask" + + has_organ = list( + "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, //5 darksight. + "brain" = /obj/item/organ/internal/brain/drask + ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 74f3e97d879..c3fa38611b5 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -5,7 +5,6 @@ icobase = 'icons/mob/human_races/r_golem.dmi' deform = 'icons/mob/human_races/r_golem.dmi' - default_language = "Galactic Common" species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, NOGUNS) oxy_mod = 0 @@ -43,7 +42,8 @@ "is crumbling into dust!", "is smashing their body apart!") -/datum/species/golem/handle_post_spawn(var/mob/living/carbon/human/H) +/datum/species/golem/on_species_gain(mob/living/carbon/human/H) + ..() if(H.mind) H.mind.assigned_role = "Golem" H.mind.special_role = SPECIAL_ROLE_GOLEM @@ -54,7 +54,6 @@ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/golem(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/golem(H), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/gloves/golem(H), slot_gloves) - ..() ////////Adamantine Golem stuff I dunno where else to put it diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm new file mode 100644 index 00000000000..e8cb6b13083 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/grey.dm @@ -0,0 +1,51 @@ +/datum/species/grey + name = "Grey" + name_plural = "Greys" + icobase = 'icons/mob/human_races/r_grey.dmi' + deform = 'icons/mob/human_races/r_def_grey.dmi' + language = "Psionic Communication" + eyes = "grey_eyes_s" + butt_sprite = "grey" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/grey, + "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/grey //5 darksight. + ) + + brute_mod = 1.25 //greys are fragile + + default_genes = list(REMOTE_TALK) + + + species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_BODY_MARKINGS + dietflags = DIET_HERB + reagent_tag = PROCESS_ORG + blood_color = "#A200FF" + +/datum/species/grey/handle_dna(mob/living/carbon/human/H, remove) + ..() + H.dna.SetSEState(REMOTETALKBLOCK, !remove, 1) + genemutcheck(H, REMOTETALKBLOCK, null, MUTCHK_FORCED) + +/datum/species/grey/water_act(mob/living/carbon/human/H, volume, temperature, source) + ..() + H.take_organ_damage(5, min(volume, 20)) + H.emote("scream") + +/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) + var/speech_pref = H.client.prefs.speciesprefs + if(speech_pref) + H.mind.speech_span = "wingdings" + +/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) + if(R.id == "sacid") + H.reagents.del_reagent(R.id) + return 0 + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/human.dm b/code/modules/mob/living/carbon/human/species/human.dm new file mode 100644 index 00000000000..2a161ab9318 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/human.dm @@ -0,0 +1,20 @@ +/datum/species/human + name = "Human" + name_plural = "Humans" + icobase = 'icons/mob/human_races/r_human.dmi' + deform = 'icons/mob/human_races/r_def_human.dmi' + primitive_form = /datum/species/monkey + language = "Sol Common" + species_traits = list(LIPS, CAN_BE_FAT) + skinned_type = /obj/item/stack/sheet/animalhide/human + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS + dietflags = DIET_OMNI + blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ + colonies across a wide swathe of space. They hold a wide range of forms and creeds.

    \ + While the central Sol government maintains control of its far-flung people, powerful corporate \ + interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ + worlds tumultous at best." + + reagent_tag = PROCESS_ORG + //Has standard darksight of 2. \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/kidan.dm b/code/modules/mob/living/carbon/human/species/kidan.dm new file mode 100644 index 00000000000..583e098054b --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/kidan.dm @@ -0,0 +1,41 @@ +/datum/species/kidan + name = "Kidan" + name_plural = "Kidan" + icobase = 'icons/mob/human_races/r_kidan.dmi' + deform = 'icons/mob/human_races/r_def_kidan.dmi' + language = "Chittin" + unarmed_type = /datum/unarmed_attack/claws + + brute_mod = 0.8 + + species_traits = list(IS_WHITELISTED) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS + eyes = "kidan_eyes_s" + dietflags = DIET_HERB + blood_color = "#FB9800" + reagent_tag = PROCESS_ORG + //Default styles for created mobs. + default_headacc = "Normal Antennae" + butt_sprite = "kidan" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/kidan, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "lantern" = /obj/item/organ/internal/lantern + ) + + allowed_consumed_mobs = list(/mob/living/simple_animal/diona) + + suicide_messages = list( + "is attempting to bite their antenna off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is cracking their exoskeleton!", + "is stabbing themselves with their mandibles!", + "is holding their breath!") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm new file mode 100644 index 00000000000..fa3e4e321a9 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -0,0 +1,135 @@ +/datum/species/machine + name = "Machine" + name_plural = "Machines" + + blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ + robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ + to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ + generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ + inhuman in outlook and perspective." + + icobase = 'icons/mob/human_races/r_machine.dmi' + deform = 'icons/mob/human_races/r_machine.dmi' + language = "Trinary" + remains_type = /obj/effect/decal/remains/robot + skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources! + + 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..." + + species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS + dietflags = 0 //IPCs can't eat, so no diet + taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + blood_color = "#1F181F" + flesh_color = "#AAAAAA" + //Default styles for created mobs. + default_hair = "Blue IPC Screen" + can_revive_by_healing = 1 + has_gender = FALSE + reagent_tag = PROCESS_SYN + male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' + female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' + male_cough_sounds = list('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') + female_cough_sounds = list('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') + male_sneeze_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' + female_sneeze_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' + butt_sprite = "machine" + + has_organ = list( + "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, + "cell" = /obj/item/organ/internal/cell, + "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2. + "charger" = /obj/item/organ/internal/cyberimp/arm/power_cord + ) + + 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), + "head" = list("path" = /obj/item/organ/external/head/ipc), + "l_arm" = list("path" = /obj/item/organ/external/arm/ipc), + "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc), + "l_leg" = list("path" = /obj/item/organ/external/leg/ipc), + "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc), + "l_hand" = list("path" = /obj/item/organ/external/hand/ipc), + "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc), + "l_foot" = list("path" = /obj/item/organ/external/foot/ipc), + "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc) + ) + + suicide_messages = list( + "is powering down!", + "is smashing their own monitor!", + "is twisting their own neck!", + "is downloading extra RAM!", + "is frying their own circuits!", + "is blocking their ventilation port!") + + var/datum/action/innate/change_monitor/monitor + +/datum/species/machine/on_species_gain(mob/living/carbon/human/H) + ..() + monitor = new() + monitor.Grant(H) + +/datum/species/machine/on_species_loss(mob/living/carbon/human/H) + ..() + if(monitor) + monitor.Remove(H) + +/datum/species/machine/handle_death(mob/living/carbon/human/H) + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + if(!head_organ) + return + head_organ.h_style = "Bald" + head_organ.f_style = "Shaved" + spawn(100) + if(H && head_organ) + H.update_hair() + H.update_fhair() + +// Allows IPC's to change their monitor display +/datum/action/innate/change_monitor + name = "Change Monitor" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "scan_mode" + +/datum/action/innate/change_monitor/Activate() + var/mob/living/carbon/human/H = owner + var/obj/item/organ/external/head/head_organ = H.get_organ("head") + + if(!head_organ) //If the rock'em-sock'em robot's head came off during a fight, they shouldn't be able to change their screen/optics. + to_chat(H, "Where's your head at? Can't change your monitor/display without one.") + return + + var/datum/robolimb/robohead = all_robolimbs[head_organ.model] + if(!head_organ) + return + if(!robohead.is_monitor) //If they've got a prosthetic head and it isn't a monitor, they've no screen to adjust. Instead, let them change the colour of their optics! + var/optic_colour = input(H, "Select optic colour", H.m_colours["head"]) as color|null + if(H.incapacitated()) + to_chat(H, "You were interrupted while changing the colour of your optics.") + return + if(optic_colour) + H.change_markings(optic_colour, "head") + + else if(robohead.is_monitor) //Means that the character's head is a monitor (has a screen). Time to customize. + var/list/hair = list() + for(var/i in hair_styles_public_list) + var/datum/sprite_accessory/hair/tmp_hair = hair_styles_public_list[i] + if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. + hair += i + + var/new_style = input(H, "Select a monitor display", "Monitor Display", head_organ.h_style) as null|anything in hair + if(H.incapacitated()) + to_chat(src, "You were interrupted while changing your monitor display.") + return + if(new_style) + H.change_hair(new_style) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index c5003b21330..5e926a23870 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -8,10 +8,11 @@ damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi' damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi' blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi' - path = /mob/living/carbon/human/monkey language = null default_language = "Chimpanzee" - greater_form = "Human" + species_traits = list(NO_EXAMINE) + skinned_type = /obj/item/stack/sheet/animalhide/monkey + greater_form = /datum/species/human is_small = 1 has_fine_manipulation = 0 ventcrawler = 1 @@ -34,7 +35,7 @@ brute_mod = 1.5 burn_mod = 1.5 -/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) +/datum/species/monkey/handle_npc(mob/living/carbon/human/H) if(H.stat != CONSCIOUS) return if(prob(33) && H.canmove && isturf(H.loc) && !H.pulledby) //won't move if being pulled @@ -45,16 +46,17 @@ /datum/species/monkey/get_random_name() return "[lowertext(name)] ([rand(100,999)])" -/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) +/datum/species/monkey/on_species_gain(mob/living/carbon/human/H) + ..() H.real_name = "[lowertext(name)] ([rand(100,999)])" H.name = H.real_name H.butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/monkey = 5) +/datum/species/monkey/handle_dna(mob/living/carbon/human/H, remove) ..() - -/datum/species/monkey/handle_dna(var/mob/living/carbon/human/H) - H.dna.SetSEState(MONKEYBLOCK,1) - genemutcheck(H,MONKEYBLOCK,null,MUTCHK_FORCED) + if(!remove) + H.dna.SetSEState(MONKEYBLOCK, TRUE) + 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) @@ -99,7 +101,7 @@ icobase = 'icons/mob/human_races/monkeys/r_farwa.dmi' deform = 'icons/mob/human_races/monkeys/r_farwa.dmi' - greater_form = "Tajaran" + greater_form = /datum/species/tajaran default_language = "Farwa" flesh_color = "#AFA59E" base_color = "#000000" @@ -123,7 +125,7 @@ icobase = 'icons/mob/human_races/monkeys/r_wolpin.dmi' deform = 'icons/mob/human_races/monkeys/r_wolpin.dmi' - greater_form = "Vulpkanin" + greater_form = /datum/species/vulpkanin default_language = "Wolpin" flesh_color = "#966464" base_color = "#000000" @@ -147,7 +149,7 @@ icobase = 'icons/mob/human_races/monkeys/r_neara.dmi' deform = 'icons/mob/human_races/monkeys/r_neara.dmi' - greater_form = "Skrell" + greater_form = /datum/species/skrell default_language = "Neara" flesh_color = "#8CD7A3" blood_color = "#1D2CBF" @@ -162,7 +164,7 @@ deform = 'icons/mob/human_races/monkeys/r_stok.dmi' tail = "stoktail" - greater_form = "Unathi" + greater_form = /datum/species/unathi default_language = "Stok" flesh_color = "#34AF10" base_color = "#000000" diff --git a/code/modules/mob/living/carbon/human/species/nucleation.dm b/code/modules/mob/living/carbon/human/species/nucleation.dm new file mode 100644 index 00000000000..21d8a5c0012 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/nucleation.dm @@ -0,0 +1,41 @@ +/datum/species/nucleation + name = "Nucleation" + name_plural = "Nucleations" + icobase = 'icons/mob/human_races/r_nucleation.dmi' + blacklisted = TRUE + 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 \ + obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ + and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ + way as lepers were back on Earth." + 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 + species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE) + dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet + + //Default styles for created mobs. + default_hair = "Nucleation Crystals" + + reagent_tag = PROCESS_ORG + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "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 + ) + vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal + +/datum/species/nucleation/on_species_gain(mob/living/carbon/human/H) + ..() + H.light_color = "#1C1C00" + H.set_light(2) + +/datum/species/nucleation/handle_death(mob/living/carbon/human/H) + var/turf/T = get_turf(H) + H.visible_message("[H]'s body explodes, leaving behind a pile of microscopic crystals!") + explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death + qdel(H) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 692a23c470a..b49dd88d8e6 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -3,9 +3,11 @@ name_plural = "Plasmamen" icobase = 'icons/mob/human_races/r_plasmaman_sb.dmi' deform = 'icons/mob/human_races/r_plasmaman_pb.dmi' // TODO: Need deform. + dangerous_existence = TRUE //So so much //language = "Clatter" species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING) + skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently* dietflags = DIET_OMNI reagent_tag = PROCESS_ORG @@ -161,7 +163,7 @@ H.internal = H.get_item_by_slot(tank_slot) H.update_action_buttons_icon() -/datum/species/plasmaman/handle_life(var/mob/living/carbon/human/H) +/datum/species/plasmaman/handle_life(mob/living/carbon/human/H) if(!istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/eva/plasmaman)) var/datum/gas_mixture/environment = H.loc.return_air() if(environment && environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Plasmamen so long as there's enough oxygen (0.5 moles, same as it takes to burn gaseous plasma). @@ -177,7 +179,7 @@ H.update_fire() ..() -/datum/species/plasmaman/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) +/datum/species/plasmaman/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) if(R.id == "plasma") H.adjustBruteLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER) H.adjustFireLoss(-0.5*REAGENTS_EFFECT_MULTIPLIER) diff --git a/code/modules/mob/living/carbon/human/species/shadow.dm b/code/modules/mob/living/carbon/human/species/shadow.dm index 7480d7e3a66..df1ecd61484 100644 --- a/code/modules/mob/living/carbon/human/species/shadow.dm +++ b/code/modules/mob/living/carbon/human/species/shadow.dm @@ -4,8 +4,8 @@ icobase = 'icons/mob/human_races/r_shadow.dmi' deform = 'icons/mob/human_races/r_shadow.dmi' + dangerous_existence = TRUE - default_language = "Galactic Common" unarmed_type = /datum/unarmed_attack/claws ignored_by = list(/mob/living/simple_animal/hostile/faithless) @@ -29,7 +29,7 @@ "is twisting their own neck!", "is staring into the closest light source!") - var/grant_vision_toggle = 1 + var/grant_vision_toggle = TRUE var/datum/action/innate/shadow/darkvision/vision_toggle /datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is @@ -47,19 +47,19 @@ 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) - . = ..() +/datum/species/shadow/on_species_gain(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) - . = ..() +/datum/species/shadow/on_species_loss(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) +/datum/species/shadow/handle_life(mob/living/carbon/human/H) var/light_amount = 0 if(isturf(H.loc)) var/turf/T = H.loc diff --git a/code/modules/mob/living/carbon/human/species/shadowling.dm b/code/modules/mob/living/carbon/human/species/shadowling.dm new file mode 100644 index 00000000000..1ce7b5cd0e0 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/shadowling.dm @@ -0,0 +1,86 @@ +/datum/species/shadow/ling + //Normal shadowpeople but with enhanced effects + name = "Shadowling" + + icobase = 'icons/mob/human_races/r_shadowling.dmi' + deform = 'icons/mob/human_races/r_shadowling.dmi' + blacklisted = TRUE + + blood_color = "#555555" + flesh_color = "#222222" + + species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash + burn_mod = 1.5 //1.5x burn damage, 2x is excessive + oxy_mod = 0 + heatmod = 1.5 + + silent_steps = 1 + grant_vision_toggle = 0 + + has_organ = list( + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes) + +/datum/species/shadow/ling/handle_life(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 = 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") + var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes) + if(istype(E)) + E.receive_damage(-1) + H.heal_overall_damage(5, 5) + H.adjustToxLoss(-5) + H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!" + H.AdjustEyeBlurry(-1) + H.CureNearsighted() + H.CureBlind() + H.adjustCloneLoss(-1) + H.SetWeakened(0) + H.SetStunned(0) + ..() + + +/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful + name = "Lesser Shadowling" + + icobase = 'icons/mob/human_races/r_lshadowling.dmi' + deform = 'icons/mob/human_races/r_lshadowling.dmi' + + blood_color = "#CCCCCC" + flesh_color = "#AAAAAA" + + species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NO_EXAMINE) + burn_mod = 1.1 + oxy_mod = 0 + heatmod = 1.1 + +/datum/species/shadow/ling/lesser/handle_life(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 = 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) + H.adjustCloneLoss(-1) + ..() \ 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 9da4d1222f6..6a2b74fb671 100644 --- a/code/modules/mob/living/carbon/human/species/skeleton.dm +++ b/code/modules/mob/living/carbon/human/species/skeleton.dm @@ -6,13 +6,12 @@ icobase = 'icons/mob/human_races/r_skeleton.dmi' deform = 'icons/mob/human_races/r_skeleton.dmi' - path = /mob/living/carbon/human/skeleton - default_language = "Galactic Common" blood_color = "#FFFFFF" flesh_color = "#E6E6C6" species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE) + skinned_type = /obj/item/stack/sheet/bone oxy_mod = 0 @@ -40,7 +39,7 @@ "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) +/datum/species/skeleton/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) // Crazylemon is still silly if(R.id == "milk") H.heal_overall_damage(4,4) diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm new file mode 100644 index 00000000000..a7c24cd338c --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/skrell.dm @@ -0,0 +1,46 @@ +/datum/species/skrell + name = "Skrell" + name_plural = "Skrell" + icobase = 'icons/mob/human_races/r_skrell.dmi' + deform = 'icons/mob/human_races/r_def_skrell.dmi' + language = "Skrellian" + primitive_form = /datum/species/monkey/skrell + + blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ + the royals' or 'Light of the Crown'.

    Skrell are a highly advanced and logical race who live under the rule \ + of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ + herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ + the secrets of their empire to their allies." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS + dietflags = DIET_HERB + taste_sensitivity = TASTE_SENSITIVITY_DULL + flesh_color = "#8CD7A3" + blood_color = "#1D2CBF" + base_color = "#38b661" //RGB: 56, 182, 97. + default_hair_colour = "#38b661" + eyes = "skrell_eyes_s" + //Default styles for created mobs. + default_hair = "Skrell Male Tentacles" + reagent_tag = PROCESS_ORG + butt_sprite = "skrell" + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/skrell, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "headpocket" = /obj/item/organ/internal/headpocket + ) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their thumbs into their eye sockets!", + "is twisting their own neck!", + "makes like a fish and suffocates!", + "is strangling themselves with their own tendrils!") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm new file mode 100644 index 00000000000..583835b7358 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -0,0 +1,180 @@ +#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1 +#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds +#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower. + +#define SLIMEPERSON_HUNGERCOST 50 +#define SLIMEPERSON_MINHUNGER 250 +#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds + +/datum/species/slime + name = "Slime People" + name_plural = "Slime People" + language = "Bubblish" + icobase = 'icons/mob/human_races/r_slime.dmi' + deform = 'icons/mob/human_races/r_slime.dmi' + remains_type = /obj/effect/decal/remains/slime + + // More sensitive to the cold + cold_level_1 = 280 + cold_level_2 = 240 + cold_level_3 = 200 + coldmod = 3 + + oxy_mod = 0 + brain_mod = 2.5 + + male_cough_sounds = list('sound/effects/slime_squish.ogg') + female_cough_sounds = list('sound/effects/slime_squish.ogg') + + species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_SKIN_COLOR | NO_EYES + dietflags = DIET_CARN + reagent_tag = PROCESS_ORG + + blood_color = "#0064C8" + exotic_blood = "water" + blood_damage_type = TOX + + butt_sprite = "slime" + //Has default darksight of 2. + + has_organ = list( + "brain" = /obj/item/organ/internal/brain/slime + ) + + suicide_messages = list( + "is melting into a puddle!", + "is ripping out their own core!", + "is turning a dull, brown color and melting into a puddle!") + + var/reagent_skin_coloring = FALSE + var/datum/action/innate/regrow/grow + var/datum/action/innate/slimecolor/recolor + +/datum/species/slime/on_species_gain(mob/living/carbon/human/H) + ..() + grow = new() + grow.Grant(H) + recolor = new() + recolor.Grant(H) + +/datum/species/slime/on_species_loss(mob/living/carbon/human/H) + ..() + if(grow) + grow.Remove(H) + if(recolor) + recolor.Remove(H) + +/datum/species/slime/handle_life(mob/living/carbon/human/H) + // Slowly shifting to the color of the reagents + if(reagent_skin_coloring && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER) + var/blood_amount = H.blood_volume + var/r_color = mix_color_from_reagents(H.reagents.reagent_list) + var/new_body_color = BlendRGB(r_color, H.skin_colour, (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume))) + H.skin_colour = new_body_color + if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller + for(var/organname in H.bodyparts_by_name) + var/obj/item/organ/external/E = H.bodyparts_by_name[organname] + if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime)) + E.sync_colour_to_human(H) + H.update_hair(0) + H.update_body() + ..() + +/datum/action/innate/slimecolor + name = "Toggle Recolor" + check_flags = AB_CHECK_CONSCIOUS + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "greenglow" + +/datum/action/innate/slimecolor/Activate() + var/mob/living/carbon/human/H = owner + var/datum/species/slime/S = H.dna.species + if(S.reagent_skin_coloring) + S.reagent_skin_coloring = FALSE + to_chat(H, "You adjust your internal chemistry to filter out pigments from things you consume.") + else + S.reagent_skin_coloring = TRUE + to_chat(H, "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you.") + +/datum/action/innate/regrow + name = "Regrow limbs" + check_flags = AB_CHECK_CONSCIOUS + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "greenglow" + +/datum/action/innate/regrow/Activate() + var/mob/living/carbon/human/H = owner + if(H.nutrition < SLIMEPERSON_MINHUNGER) + to_chat(H, "You're too hungry to regenerate a limb!") + return + + var/list/missing_limbs = list() + for(var/l in H.bodyparts_by_name) + var/obj/item/organ/external/E = H.bodyparts_by_name[l] + if(!istype(E)) + var/list/limblist = H.dna.species.has_limbs[l] + var/obj/item/organ/external/limb = limblist["path"] + var/parent_organ = initial(limb.parent_organ) + var/obj/item/organ/external/parentLimb = H.bodyparts_by_name[parent_organ] + if(!istype(parentLimb)) + continue + missing_limbs[initial(limb.name)] = l + + if(!missing_limbs.len) + to_chat(H, "You're not missing any limbs!") + return + + var/limb_select = input(H, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs + var/chosen_limb = missing_limbs[limb_select] + + H.visible_message("[H] begins to hold still and concentrate on [H.p_their()] missing [limb_select]...", "You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)") + if(do_after(H, SLIMEPERSON_REGROWTHDELAY, needhand = 0, target = H)) + if(H.incapacitated()) + to_chat(H, "You cannot regenerate missing limbs in your current state.") + return + + if(H.nutrition < SLIMEPERSON_MINHUNGER) + to_chat(H, "You're too hungry to regenerate a limb!") + return + + var/obj/item/organ/external/O = H.bodyparts_by_name[chosen_limb] + + var/stored_brute = 0 + var/stored_burn = 0 + if(istype(O)) + to_chat(H, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!") + var/obj/item/organ/external/doomedStump = O + stored_brute = doomedStump.brute_dam + stored_burn = doomedStump.burn_dam + qdel(O) + + var/limb_list = H.dna.species.has_limbs[chosen_limb] + var/obj/item/organ/external/limb_path = limb_list["path"] + // Parent check + var/obj/item/organ/external/potential_parent = H.bodyparts_by_name[initial(limb_path.parent_organ)] + if(!istype(potential_parent)) + to_chat(H, "You've lost the organ that you've been growing your new part on!") + return // No rayman for you + // Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing. + // Bothersome. + var/obj/item/organ/external/new_limb = new limb_path(H) + new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid. + H.adjustBruteLoss(stored_brute) + H.adjustFireLoss(stored_burn) + H.update_body() + H.updatehealth() + H.UpdateDamageIcon() + H.nutrition -= SLIMEPERSON_HUNGERCOST + H.visible_message("[H] finishes regrowing [H.p_their()] missing [new_limb]!", "You finish regrowing your [limb_select]") + else + to_chat(H, "You need to hold still in order to regrow a limb!") + +#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER +#undef SLIMEPERSON_ICON_UPDATE_PERIOD +#undef SLIMEPERSON_BLOOD_SCALING_FACTOR + +#undef SLIMEPERSON_HUNGERCOST +#undef SLIMEPERSON_MINHUNGER +#undef SLIMEPERSON_REGROWTHDELAY \ 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 deleted file mode 100644 index 6b692601226..00000000000 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ /dev/null @@ -1,1068 +0,0 @@ -/datum/species/human - name = "Human" - name_plural = "Humans" - icobase = 'icons/mob/human_races/r_human.dmi' - deform = 'icons/mob/human_races/r_def_human.dmi' - primitive_form = "Monkey" - path = /mob/living/carbon/human/human - language = "Sol Common" - species_traits = list(LIPS, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS - dietflags = DIET_OMNI - blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ - colonies across a wide swathe of space. They hold a wide range of forms and creeds.

    \ - While the central Sol government maintains control of its far-flung people, powerful corporate \ - interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ - worlds tumultous at best." - - reagent_tag = PROCESS_ORG - //Has standard darksight of 2. - -/datum/species/unathi - name = "Unathi" - name_plural = "Unathi" - icobase = 'icons/mob/human_races/r_lizard.dmi' - deform = 'icons/mob/human_races/r_def_lizard.dmi' - path = /mob/living/carbon/human/unathi - default_language = "Galactic Common" - language = "Sinta'unathi" - tail = "sogtail" - unarmed_type = /datum/unarmed_attack/claws - primitive_form = "Stok" - - 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 \ - desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ - else, frequently even their own lives. They prefer warmer temperatures than most species and \ - their native tongue is a heavy hissing laungage called Sinta'Unathi." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING - dietflags = DIET_CARN - - cold_level_1 = 280 //Default 260 - Lower is better - cold_level_2 = 220 //Default 200 - cold_level_3 = 140 //Default 120 - - heat_level_1 = 380 //Default 360 - Higher is better - heat_level_2 = 420 //Default 400 - heat_level_3 = 480 //Default 460 - - flesh_color = "#34AF10" - reagent_tag = PROCESS_ORG - base_color = "#066000" - //Default styles for created mobs. - default_headacc = "Simple" - default_headacc_colour = "#404040" - butt_sprite = "unathi" - brute_mod = 1.05 - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/unathi, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "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, - /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - - var/datum/action/innate/tail_lash/lash = new() - - -/datum/species/unathi/handle_post_spawn(var/mob/living/carbon/human/H) - lash.Grant(H) - ..() - -/datum/action/innate/tail_lash - name = "Tail lash" - icon_icon = 'icons/effects/effects.dmi' - button_icon_state = "tail" - -/datum/action/innate/tail_lash/Activate() - var/mob/living/carbon/human/user = owner - if(!user.restrained() || !user.buckled) - to_chat(user, "You need freedom of movement to tail lash!") - return - if(user.getStaminaLoss() >= 50) - to_chat(user, "Rest before tail lashing again!") - return - for(var/mob/living/carbon/human/C in orange(1)) - var/obj/item/organ/external/E = C.get_organ(pick("l_leg", "r_leg", "l_foot", "r_foot", "groin")) - if(E) - user.changeNext_move(CLICK_CD_MELEE) - user.visible_message("[src] smacks [C] in [E] with their tail! ", "You hit [C] in [E] with your tail!") - user.adjustStaminaLoss(15) - C.apply_damage(5, BRUTE, E) - user.spin(20, 1) - playsound(user.loc, 'sound/weapons/slash.ogg', 50, 0) - - - -/datum/species/unathi/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/tajaran - name = "Tajaran" - name_plural = "Tajaran" - icobase = 'icons/mob/human_races/r_tajaran.dmi' - deform = 'icons/mob/human_races/r_def_tajaran.dmi' - path = /mob/living/carbon/human/tajaran - default_language = "Galactic Common" - language = "Siik'tajr" - tail = "tajtail" - unarmed_type = /datum/unarmed_attack/claws - - 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 \ - influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ - of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ - using unique inflections their mouths form." - - cold_level_1 = 240 - cold_level_2 = 180 - cold_level_3 = 100 - - heat_level_1 = 340 - heat_level_2 = 380 - heat_level_3 = 440 - - primitive_form = "Farwa" - - species_traits = list(LIPS, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING - dietflags = DIET_OMNI - taste_sensitivity = TASTE_SENSITIVITY_SHARP - reagent_tag = PROCESS_ORG - flesh_color = "#AFA59E" - base_color = "#424242" - butt_sprite = "tajaran" - - 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 /*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, - /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - -/datum/species/tajaran/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/vulpkanin - name = "Vulpkanin" - name_plural = "Vulpkanin" - icobase = 'icons/mob/human_races/r_vulpkanin.dmi' - deform = 'icons/mob/human_races/r_vulpkanin.dmi' - path = /mob/living/carbon/human/vulpkanin - default_language = "Galactic Common" - language = "Canilunzt" - primitive_form = "Wolpin" - tail = "vulptail" - unarmed_type = /datum/unarmed_attack/claws - - 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 \ - culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \ - to the degree it can cause conflict with more rigorous and strict authorities. They speak a guttural language known as 'Canilunzt' \ - which has a heavy emphasis on utilizing tail positioning and ear twitches to communicate intent." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR - dietflags = DIET_OMNI - hunger_drain = 0.11 - taste_sensitivity = TASTE_SENSITIVITY_SHARP - reagent_tag = PROCESS_ORG - flesh_color = "#966464" - base_color = "#CF4D2F" - butt_sprite = "vulp" - - scream_verb = "yelps" - - 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 /*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, - /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!") - -/datum/species/vulpkanin/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/skrell - name = "Skrell" - name_plural = "Skrell" - icobase = 'icons/mob/human_races/r_skrell.dmi' - deform = 'icons/mob/human_races/r_def_skrell.dmi' - path = /mob/living/carbon/human/skrell - default_language = "Galactic Common" - language = "Skrellian" - primitive_form = "Neara" - - blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ - the royals' or 'Light of the Crown'.

    Skrell are a highly advanced and logical race who live under the rule \ - of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ - herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ - the secrets of their empire to their allies." - - species_traits = list(LIPS) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS - dietflags = DIET_HERB - taste_sensitivity = TASTE_SENSITIVITY_DULL - flesh_color = "#8CD7A3" - blood_color = "#1D2CBF" - base_color = "#38b661" //RGB: 56, 182, 97. - default_hair_colour = "#38b661" - eyes = "skrell_eyes_s" - //Default styles for created mobs. - default_hair = "Skrell Male Tentacles" - reagent_tag = PROCESS_ORG - butt_sprite = "skrell" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/skrell, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "headpocket" = /obj/item/organ/internal/headpocket - ) - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their thumbs into their eye sockets!", - "is twisting their own neck!", - "makes like a fish and suffocates!", - "is strangling themselves with their own tendrils!") - -/datum/species/vox - name = "Vox" - name_plural = "Vox" - icobase = 'icons/mob/human_races/vox/r_vox.dmi' - deform = 'icons/mob/human_races/vox/r_def_vox.dmi' - path = /mob/living/carbon/human/vox - - default_language = "Galactic Common" - language = "Vox-pidgin" - tail = "voxtail" - speech_sounds = list('sound/voice/shriek1.ogg') - speech_chance = 20 - unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. - - blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ - scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ - alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ - refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ - smell.

    Most humans will never meet a Vox raider, instead learning of this insular species through \ - dealing with their traders and merchants; those that do rarely enjoy the experience." - - brute_mod = 1.2 //20% more brute damage. Fragile bird bones. - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - breathid = "n2" - - eyes = "vox_eyes_s" - - species_traits = list(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 - - blood_color = "#2299FC" - flesh_color = "#808D11" - //Default styles for created mobs. - default_hair = "Short Vox Quills" - default_hair_colour = "#614f19" //R: 97, G: 79, B: 25 - butt_sprite = "vox" - - reagent_tag = PROCESS_ORG - scream_verb = "shrieks" - male_scream_sound = 'sound/voice/shriek1.ogg' - female_scream_sound = 'sound/voice/shriek1.ogg' - male_cough_sounds = list('sound/voice/shriekcough.ogg') - female_cough_sounds = list('sound/voice/shriekcough.ogg') - male_sneeze_sound = 'sound/voice/shrieksneeze.ogg' - female_sneeze_sound = 'sound/voice/shrieksneeze.ogg' - - icon_skin_tones = list( - 1 = "Default Green", - 2 = "Dark Green", - 3 = "Brown", - 4 = "Grey", - 5 = "Emerald", - 6 = "Azure" - ) - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs/vox, - "liver" = /obj/item/organ/internal/liver/vox, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "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. - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!", - "is deeply inhaling oxygen!") - -/datum/species/vox/handle_death(var/mob/living/carbon/human/H) - H.stop_tail_wagging(1) - -/datum/species/vox/makeName(var/gender,var/mob/living/carbon/human/H=null) - var/sounds = rand(2,8) - var/i = 0 - var/newname = "" - - while(i<=sounds) - i++ - newname += pick(vox_name_syllables) - return capitalize(newname) - -/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H) - if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") - H.unEquip(H.wear_mask) - H.unEquip(H.l_hand) - - H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask) - var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null - if(tank_pref)//Diseasel, here you go - H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand) - else - H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand) - to_chat(H, "You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.") - H.internal = H.l_hand - H.update_action_buttons_icon() - -/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H) - updatespeciescolor(H) - H.update_icons() - //H.verbs += /mob/living/carbon/human/proc/leap - ..() - -/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H, var/owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race. - if(H.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis. - var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox. - var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox. - switch(H.s_tone) - if(6) //Azure Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi' - H.tail = "voxtail_azu" - if(5) //Emerald Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi' - H.tail = "voxtail_emrl" - if(4) //Grey Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi' - H.tail = "voxtail_gry" - if(3) //Brown Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi' - H.tail = "voxtail_brn" - if(2) //Dark Green Vox. - new_icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi' - new_deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi' - H.tail = "voxtail_dgrn" - else //Default Green Vox. - H.tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone. - - H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so. - H.update_dna() - -/datum/species/vox/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R) - if(R.id == "oxygen") //Armalis are above such petty things. - H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma. - H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) - return 0 //Handling reagent removal on our own. - - return ..() - -/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H) - H.verbs += /mob/living/carbon/human/proc/leap - H.verbs += /mob/living/carbon/human/proc/gut - ..() - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox Armalis" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - path = /mob/living/carbon/human/voxarmalis - unarmed_type = /datum/unarmed_attack/claws/armalis - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - - species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED) - bodyflags = HAS_TAIL - dietflags = DIET_OMNI //should inherit this from vox, this is here just in case - - blood_color = "#2299FC" - flesh_color = "#808D11" - - reagent_tag = PROCESS_ORG - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs/vox, - "liver" = /obj/item/organ/internal/liver, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "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. - - suicide_messages = list( - "is attempting to bite their tongue off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is holding their breath!", - "is huffing oxygen!") - -/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things. - return 1 - -/datum/species/kidan - name = "Kidan" - name_plural = "Kidan" - icobase = 'icons/mob/human_races/r_kidan.dmi' - deform = 'icons/mob/human_races/r_def_kidan.dmi' - path = /mob/living/carbon/human/kidan - default_language = "Galactic Common" - language = "Chittin" - unarmed_type = /datum/unarmed_attack/claws - - brute_mod = 0.8 - - species_traits = list(IS_WHITELISTED) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS - eyes = "kidan_eyes_s" - dietflags = DIET_HERB - blood_color = "#FB9800" - reagent_tag = PROCESS_ORG - //Default styles for created mobs. - default_headacc = "Normal Antennae" - butt_sprite = "kidan" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/kidan, - "kidneys" = /obj/item/organ/internal/kidneys, - "brain" = /obj/item/organ/internal/brain, - "appendix" = /obj/item/organ/internal/appendix, - "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. - "lantern" = /obj/item/organ/internal/lantern - ) - - allowed_consumed_mobs = list(/mob/living/simple_animal/diona) - - suicide_messages = list( - "is attempting to bite their antenna off!", - "is jamming their claws into their eye sockets!", - "is twisting their own neck!", - "is cracking their exoskeleton!", - "is stabbing themselves with their mandibles!", - "is holding their breath!") - -/datum/species/slime - name = "Slime People" - name_plural = "Slime People" - default_language = "Galactic Common" - language = "Bubblish" - icobase = 'icons/mob/human_races/r_slime.dmi' - deform = 'icons/mob/human_races/r_slime.dmi' - path = /mob/living/carbon/human/slime - remains_type = /obj/effect/decal/remains/slime - - // More sensitive to the cold - cold_level_1 = 280 - cold_level_2 = 240 - cold_level_3 = 200 - coldmod = 3 - - oxy_mod = 0 - brain_mod = 2.5 - - male_cough_sounds = list('sound/effects/slime_squish.ogg') - female_cough_sounds = list('sound/effects/slime_squish.ogg') - - species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | NO_EYES - dietflags = DIET_CARN - reagent_tag = PROCESS_ORG - - blood_color = "#0064C8" - exotic_blood = "water" - blood_damage_type = TOX - - butt_sprite = "slime" - //Has default darksight of 2. - - has_organ = list( - "brain" = /obj/item/organ/internal/brain/slime - ) - - suicide_messages = list( - "is melting into a puddle!", - "is ripping out their own core!", - "is turning a dull, brown color and melting into a puddle!") - - var/list/mob/living/carbon/human/recolor_list = list() - - var/datum/action/innate/regrow/grow = new() - - species_abilities = list( - /mob/living/carbon/human/verb/toggle_recolor_verb, - /mob/living/carbon/human/proc/regrow_limbs - ) - -/datum/species/slime/handle_post_spawn(var/mob/living/carbon/human/H) - grow.Grant(H) - ..() - -/datum/action/innate/regrow - name = "Regrow limbs" - icon_icon = 'icons/effects/effects.dmi' - button_icon_state = "greenglow" - -/datum/action/innate/regrow/Activate() - var/mob/living/carbon/human/user = owner - user.regrow_limbs() - - -/datum/species/slime/handle_life(var/mob/living/carbon/human/H) -//This is allegedly for code "style". Like a plaid sweater? -#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1 -#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds -#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower. - // Slowly shifting to the color of the reagents - if((H in recolor_list) && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER) - var/blood_amount = H.blood_volume - var/r_color = mix_color_from_reagents(H.reagents.reagent_list) - var/new_body_color = BlendRGB(r_color, H.skin_colour, (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume))) - H.skin_colour = new_body_color - if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller - for(var/organname in H.bodyparts_by_name) - var/obj/item/organ/external/E = H.bodyparts_by_name[organname] - if(istype(E) && E.dna.species == "Slime People") - E.sync_colour_to_human(H) - H.update_hair(0) - H.update_body() - ..() - -#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER -#undef SLIMEPERSON_ICON_UPDATE_PERIOD -#undef SLIMEPERSON_BLOOD_SCALING_FACTOR - -/mob/living/carbon/human/proc/toggle_recolor(var/silent = 0) - var/datum/species/slime/S = all_species[get_species()] - if(!istype(S)) - if(!silent) - to_chat(src, "You're not a slime person!") - return - - if(src in S.recolor_list) - S.recolor_list -= src - if(!silent) - to_chat(src, "You adjust your internal chemistry to filter out pigments from things you consume.") - else - S.recolor_list += src - if(!silent) - to_chat(src, "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you.") - -/mob/living/carbon/human/verb/toggle_recolor_verb() - set category = "IC" - set name = "Toggle Reagent Recoloring" - set desc = "While active, you'll slowly adjust your body's color to that of the reagents inside of you, moderated by how much blood you have." - - toggle_recolor() - - -/mob/living/carbon/human/proc/regrow_limbs() - set category = "IC" - set name = "Regrow Limbs" - set desc = "Regrow one of your missing limbs at the cost of a large amount of hunger" - -#define SLIMEPERSON_HUNGERCOST 50 -#define SLIMEPERSON_MINHUNGER 250 -#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds - - if(stat || paralysis || stunned) - to_chat(src, "You cannot regenerate missing limbs in your current state.") - return - - if(nutrition < SLIMEPERSON_MINHUNGER) - to_chat(src, "You're too hungry to regenerate a limb!") - return - - var/list/missing_limbs = list() - for(var/l in bodyparts_by_name) - var/obj/item/organ/external/E = bodyparts_by_name[l] - if(!istype(E)) - var/list/limblist = species.has_limbs[l] - var/obj/item/organ/external/limb = limblist["path"] - var/parent_organ = initial(limb.parent_organ) - var/obj/item/organ/external/parentLimb = bodyparts_by_name[parent_organ] - if(!istype(parentLimb)) - continue - missing_limbs[initial(limb.name)] = l - - if(!missing_limbs.len) - to_chat(src, "You're not missing any limbs!") - return - - var/limb_select = input(src, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs - var/chosen_limb = missing_limbs[limb_select] - - visible_message("[src] begins to hold still and concentrate on [p_their()] missing [limb_select]...", "You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)") - if(do_after(src, SLIMEPERSON_REGROWTHDELAY, needhand=0, target = src)) - if(stat || paralysis || stunned) - to_chat(src, "You cannot regenerate missing limbs in your current state.") - return - - if(nutrition < SLIMEPERSON_MINHUNGER) - to_chat(src, "You're too hungry to regenerate a limb!") - return - - var/obj/item/organ/external/O = bodyparts_by_name[chosen_limb] - - var/stored_brute = 0 - var/stored_burn = 0 - if(istype(O)) - to_chat(src, "You distribute the damaged tissue around your body, out of the way of your new pseudopod!") - var/obj/item/organ/external/doomedStump = O - stored_brute = doomedStump.brute_dam - stored_burn = doomedStump.burn_dam - qdel(O) - - var/limb_list = species.has_limbs[chosen_limb] - var/obj/item/organ/external/limb_path = limb_list["path"] - // Parent check - var/obj/item/organ/external/potential_parent = bodyparts_by_name[initial(limb_path.parent_organ)] - if(!istype(potential_parent)) - to_chat(src, "You've lost the organ that you've been growing your new part on!") - return // No rayman for you - // Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing. - // Bothersome. - var/obj/item/organ/external/new_limb = new limb_path(src) - new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid. - adjustBruteLoss(stored_brute) - adjustFireLoss(stored_burn) - update_body() - updatehealth() - UpdateDamageIcon() - nutrition -= SLIMEPERSON_HUNGERCOST - visible_message("[src] finishes regrowing [p_their()] missing [new_limb]!", "You finish regrowing your [limb_select]") - else - to_chat(src, "You need to hold still in order to regrow a limb!") - return - -#undef SLIMEPERSON_HUNGERCOST -#undef SLIMEPERSON_MINHUNGER -#undef SLIMEPERSON_REGROWTHDELAY - -/datum/species/slime/handle_pre_change(var/mob/living/carbon/human/H) - ..() - if(H in recolor_list) - H.toggle_recolor(silent = 1) - -/datum/species/grey - name = "Grey" - name_plural = "Greys" - icobase = 'icons/mob/human_races/r_grey.dmi' - deform = 'icons/mob/human_races/r_def_grey.dmi' - default_language = "Galactic Common" - language = "Psionic Communication" - eyes = "grey_eyes_s" - butt_sprite = "grey" - - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "lungs" = /obj/item/organ/internal/lungs, - "liver" = /obj/item/organ/internal/liver/grey, - "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/grey //5 darksight. - ) - - brute_mod = 1.25 //greys are fragile - - default_genes = list(REMOTE_TALK) - - - species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_BODY_MARKINGS - dietflags = DIET_HERB - reagent_tag = PROCESS_ORG - blood_color = "#A200FF" - -/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove) - if(!remove) - C.dna.SetSEState(REMOTETALKBLOCK,1,1) - genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) - else - C.dna.SetSEState(REMOTETALKBLOCK,0,1) - genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED) - ..() - -/datum/species/grey/water_act(var/mob/living/carbon/C, volume, temperature, source) - ..() - C.take_organ_damage(5,min(volume,20)) - C.emote("scream") - -/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H) - var/speech_pref = H.client.prefs.speciesprefs - if(speech_pref) - H.mind.speech_span = "wingdings" - -/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) - if(R.id == "sacid") - H.reagents.del_reagent(R.id) - return 0 - return ..() - -/datum/species/diona - name = "Diona" - name_plural = "Dionaea" - icobase = 'icons/mob/human_races/r_diona.dmi' - deform = 'icons/mob/human_races/r_def_plant.dmi' - path = /mob/living/carbon/human/diona - default_language = "Galactic Common" - language = "Rootspeak" - speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16] - speech_chance = 20 - unarmed_type = /datum/unarmed_attack/diona - //primitive_form = "Nymph" - slowdown = 5 - remains_type = /obj/effect/decal/cleanable/ash - - - warning_low_pressure = 50 - hazard_low_pressure = -1 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 300 - heat_level_2 = 340 - heat_level_3 = 400 - - blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ - species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ - there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ - Minoris primary being ringed with a cloud of singing space-station-sized entities.

    The Dionaea coexist peacefully with \ - all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ - even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ - water and other radiation." - - species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN) - clothing_flags = HAS_SOCKS - default_hair_colour = "#000000" - dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE - - 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" - butt_sprite = "diona" - - reagent_tag = PROCESS_ORG - - 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/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/eyes/diona - has_limbs = list( - "chest" = list("path" = /obj/item/organ/external/chest/diona), - "groin" = list("path" = /obj/item/organ/external/groin/diona), - "head" = list("path" = /obj/item/organ/external/head/diona), - "l_arm" = list("path" = /obj/item/organ/external/arm/diona), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/diona), - "l_leg" = list("path" = /obj/item/organ/external/leg/diona), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/diona), - "l_hand" = list("path" = /obj/item/organ/external/hand/diona), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/diona), - "l_foot" = list("path" = /obj/item/organ/external/foot/diona), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/diona) - ) - - suicide_messages = list( - "is losing branches!", - "pulls out a secret stash of herbicide and takes a hearty swig!", - "is pulling themselves apart!") - -/datum/species/diona/can_understand(var/mob/other) - if(istype(other, /mob/living/simple_animal/diona)) - return 1 - return 0 - -/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) - H.gender = NEUTER - - return ..() - -/datum/species/diona/handle_life(var/mob/living/carbon/human/H) - H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time. - var/rads = H.radiation / 25 - H.radiation = max(H.radiation-rads, 0) - H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10) - H.adjustBruteLoss(-(rads)) - H.adjustToxLoss(-(rads)) - - 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 - H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) - - 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)) - if(H.nutrition < NUTRITION_LEVEL_STARVING+50) - H.take_overall_damage(10,0) - ..() - -/datum/species/machine - name = "Machine" - name_plural = "Machines" - - blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \ - robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \ - to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \ - generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \ - inhuman in outlook and perspective." - - icobase = 'icons/mob/human_races/r_machine.dmi' - deform = 'icons/mob/human_races/r_machine.dmi' - path = /mob/living/carbon/human/machine - default_language = "Galactic Common" - language = "Trinary" - remains_type = /obj/effect/decal/remains/robot - - 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..." - - species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS - dietflags = 0 //IPCs can't eat, so no diet - taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE - blood_color = "#1F181F" - flesh_color = "#AAAAAA" - //Default styles for created mobs. - default_hair = "Blue IPC Screen" - can_revive_by_healing = 1 - has_gender = FALSE - reagent_tag = PROCESS_SYN - male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' - female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg' - male_cough_sounds = list('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg') - female_cough_sounds = list('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg') - male_sneeze_sound = 'sound/effects/mob_effects/machine_sneeze.ogg' - female_sneeze_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg' - butt_sprite = "machine" - - has_organ = list( - "brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain, - "cell" = /obj/item/organ/internal/cell, - "optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2. - "charger" = /obj/item/organ/internal/cyberimp/arm/power_cord - ) - - 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), - "head" = list("path" = /obj/item/organ/external/head/ipc), - "l_arm" = list("path" = /obj/item/organ/external/arm/ipc), - "r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc), - "l_leg" = list("path" = /obj/item/organ/external/leg/ipc), - "r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc), - "l_hand" = list("path" = /obj/item/organ/external/hand/ipc), - "r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc), - "l_foot" = list("path" = /obj/item/organ/external/foot/ipc), - "r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc) - ) - - suicide_messages = list( - "is powering down!", - "is smashing their own monitor!", - "is twisting their own neck!", - "is downloading extra RAM!", - "is frying their own circuits!", - "is blocking their ventilation port!") - - species_abilities = list( - /mob/living/carbon/human/proc/change_monitor - ) - -/datum/species/machine/handle_death(var/mob/living/carbon/human/H) - var/obj/item/organ/external/head/head_organ = H.get_organ("head") - if(!head_organ) - return - head_organ.h_style = "Bald" - head_organ.f_style = "Shaved" - spawn(100) - if(H) - H.update_hair() - H.update_fhair() - -/datum/species/drask - name = "Drask" - name_plural = "Drask" - icobase = 'icons/mob/human_races/r_drask.dmi' - deform = 'icons/mob/human_races/r_drask.dmi' - path = /mob/living/carbon/human/drask - default_language = "Galactic Common" - language = "Orluum" - eyes = "drask_eyes_s" - - speech_sounds = list('sound/voice/DraskTalk.ogg') - speech_chance = 20 - male_scream_sound = 'sound/voice/DraskTalk2.ogg' - female_scream_sound = 'sound/voice/DraskTalk2.ogg' - male_cough_sounds = 'sound/voice/DraskCough.ogg' - female_cough_sounds = 'sound/voice/DraskCough.ogg' - male_sneeze_sound = 'sound/voice/DraskSneeze.ogg' - female_sneeze_sound = 'sound/voice/DraskSneeze.ogg' - - burn_mod = 2 - //exotic_blood = "cryoxadone" - body_temperature = 273 - - blurb = "Hailing from Hoorlm, planet outside what is usually considered a habitable \ - orbit, the Drask evolved to live in extreme cold. Their strange bodies seem \ - to operate better the colder their surroundings are, and can regenerate rapidly \ - when breathing supercooled gas.

    On their homeworld, the Drask live long lives \ - in their labyrinthine settlements, carved out beneath Hoorlm's icy surface, where the air \ - is of breathable density." - - suicide_messages = list( - "is self-warming with friction!", - "is jamming fingers through their big eyes!", - "is sucking in warm air!", - "is holding their breath!") - - species_traits = list(LIPS, IS_WHITELISTED) - clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT - bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS - dietflags = DIET_OMNI - - cold_level_1 = -1 //Default 260 - Lower is better - cold_level_2 = -1 //Default 200 - cold_level_3 = -1 //Default 120 - coldmod = -1 - - heat_level_1 = 300 //Default 360 - Higher is better - heat_level_2 = 340 //Default 400 - heat_level_3 = 400 //Default 460 - heatmod = 2 - - flesh_color = "#a3d4eb" - reagent_tag = PROCESS_ORG - base_color = "#a3d4eb" - blood_color = "#a3d4eb" - butt_sprite = "drask" - - has_organ = list( - "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, //5 darksight. - "brain" = /obj/item/organ/internal/brain/drask - ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/tajaran.dm b/code/modules/mob/living/carbon/human/species/tajaran.dm new file mode 100644 index 00000000000..d4cdaf95944 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/tajaran.dm @@ -0,0 +1,58 @@ +/datum/species/tajaran + name = "Tajaran" + name_plural = "Tajaran" + icobase = 'icons/mob/human_races/r_tajaran.dmi' + deform = 'icons/mob/human_races/r_def_tajaran.dmi' + language = "Siik'tajr" + tail = "tajtail" + skinned_type = /obj/item/stack/sheet/fur + unarmed_type = /datum/unarmed_attack/claws + + 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 \ + influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ + of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ + using unique inflections their mouths form." + + cold_level_1 = 240 + cold_level_2 = 180 + cold_level_3 = 100 + + heat_level_1 = 340 + heat_level_2 = 380 + heat_level_3 = 440 + + primitive_form = /datum/species/monkey/tajaran + + species_traits = list(LIPS, CAN_BE_FAT) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING + dietflags = DIET_OMNI + taste_sensitivity = TASTE_SENSITIVITY_SHARP + reagent_tag = PROCESS_ORG + flesh_color = "#AFA59E" + base_color = "#424242" + butt_sprite = "tajaran" + + 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 /*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, + /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + +/datum/species/tajaran/handle_death(mob/living/carbon/human/H) + H.stop_tail_wagging(1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/unathi.dm b/code/modules/mob/living/carbon/human/species/unathi.dm new file mode 100644 index 00000000000..bcad7d9342e --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/unathi.dm @@ -0,0 +1,108 @@ +/datum/species/unathi + name = "Unathi" + name_plural = "Unathi" + icobase = 'icons/mob/human_races/r_lizard.dmi' + deform = 'icons/mob/human_races/r_def_lizard.dmi' + language = "Sinta'unathi" + tail = "sogtail" + skinned_type = /obj/item/stack/sheet/animalhide/lizard + unarmed_type = /datum/unarmed_attack/claws + primitive_form = /datum/species/monkey/unathi + + 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 \ + desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ + else, frequently even their own lives. They prefer warmer temperatures than most species and \ + their native tongue is a heavy hissing laungage called Sinta'Unathi." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING + dietflags = DIET_CARN + + cold_level_1 = 280 //Default 260 - Lower is better + cold_level_2 = 220 //Default 200 + cold_level_3 = 140 //Default 120 + + heat_level_1 = 380 //Default 360 - Higher is better + heat_level_2 = 420 //Default 400 + heat_level_3 = 480 //Default 460 + + flesh_color = "#34AF10" + reagent_tag = PROCESS_ORG + base_color = "#066000" + //Default styles for created mobs. + default_headacc = "Simple" + default_headacc_colour = "#404040" + butt_sprite = "unathi" + brute_mod = 1.05 + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs, + "liver" = /obj/item/organ/internal/liver/unathi, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "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, + /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + + var/datum/action/innate/tail_lash/lash + + +/datum/species/unathi/on_species_gain(mob/living/carbon/human/H) + ..() + lash = new + lash.Grant(H) + +/datum/species/unathi/on_species_loss(mob/living/carbon/human/H) + ..() + if(lash) + lash.Remove(H) + +/datum/action/innate/tail_lash + name = "Tail lash" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "tail" + check_flags = AB_CHECK_LYING | AB_CHECK_CONSCIOUS | AB_CHECK_STUNNED + +/datum/action/innate/tail_lash/Activate() + var/mob/living/carbon/human/user = owner + if((user.restrained() && user.pulledby) || user.buckled) + to_chat(user, "You need freedom of movement to tail lash!") + return + if(user.getStaminaLoss() >= 50) + to_chat(user, "Rest before tail lashing again!") + return + for(var/mob/living/carbon/human/C in orange(1)) + var/obj/item/organ/external/E = C.get_organ(pick("l_leg", "r_leg", "l_foot", "r_foot", "groin")) + if(E) + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("[user] smacks [C] in [E] with their tail! ", "You hit [C] in [E] with your tail!") + user.adjustStaminaLoss(15) + C.apply_damage(5, BRUTE, E) + user.spin(20, 1) + playsound(user.loc, 'sound/weapons/slash.ogg', 50, 0) + add_attack_logs(user, C, "tail whipped") + if(user.restrained()) + if(prob(50)) + user.Weaken(5) + user.visible_message("[user] loses [user.p_their()] balance!", "You lose your balance!") + return + if(user.getStaminaLoss() >= 60) //Bit higher as you don't need to start, just would need to keep going with the tail lash. + to_chat(user, "You run out of momentum!") + return + + + +/datum/species/unathi/handle_death(mob/living/carbon/human/H) + H.stop_tail_wagging(1) diff --git a/code/modules/mob/living/carbon/human/species/vox.dm b/code/modules/mob/living/carbon/human/species/vox.dm new file mode 100644 index 00000000000..1bc0b8b3b9e --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/vox.dm @@ -0,0 +1,197 @@ +/datum/species/vox + name = "Vox" + name_plural = "Vox" + icobase = 'icons/mob/human_races/vox/r_vox.dmi' + deform = 'icons/mob/human_races/vox/r_def_vox.dmi' + dangerous_existence = TRUE + language = "Vox-pidgin" + tail = "voxtail" + speech_sounds = list('sound/voice/shriek1.ogg') + speech_chance = 20 + unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too. + + blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ + scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ + alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ + refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ + smell.

    Most humans will never meet a Vox raider, instead learning of this insular species through \ + dealing with their traders and merchants; those that do rarely enjoy the experience." + + brute_mod = 1.2 //20% more brute damage. Fragile bird bones. + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + breathid = "n2" + + eyes = "vox_eyes_s" + + species_traits = list(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 + + blood_color = "#2299FC" + flesh_color = "#808D11" + //Default styles for created mobs. + default_hair = "Short Vox Quills" + default_hair_colour = "#614f19" //R: 97, G: 79, B: 25 + butt_sprite = "vox" + + reagent_tag = PROCESS_ORG + scream_verb = "shrieks" + male_scream_sound = 'sound/voice/shriek1.ogg' + female_scream_sound = 'sound/voice/shriek1.ogg' + male_cough_sounds = list('sound/voice/shriekcough.ogg') + female_cough_sounds = list('sound/voice/shriekcough.ogg') + male_sneeze_sound = 'sound/voice/shrieksneeze.ogg' + female_sneeze_sound = 'sound/voice/shrieksneeze.ogg' + + icon_skin_tones = list( + 1 = "Default Green", + 2 = "Dark Green", + 3 = "Brown", + 4 = "Grey", + 5 = "Emerald", + 6 = "Azure" + ) + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs/vox, + "liver" = /obj/item/organ/internal/liver/vox, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "stack" = /obj/item/organ/internal/stack //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. + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!", + "is deeply inhaling oxygen!") + +/datum/species/vox/handle_death(mob/living/carbon/human/H) + H.stop_tail_wagging(1) + +/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H) + if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime") + H.unEquip(H.wear_mask) + H.unEquip(H.l_hand) + + H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask) + var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null + if(tank_pref)//Diseasel, here you go + H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand) + else + H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand) + to_chat(H, "You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.") + H.internal = H.l_hand + H.update_action_buttons_icon() + +/datum/species/vox/on_species_gain(mob/living/carbon/human/H) + ..() + updatespeciescolor(H) + H.update_icons() + +/datum/species/vox/updatespeciescolor(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race. + if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis. + var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox. + var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox. + switch(H.s_tone) + if(6) //Azure Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi' + H.tail = "voxtail_azu" + if(5) //Emerald Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi' + H.tail = "voxtail_emrl" + if(4) //Grey Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi' + H.tail = "voxtail_gry" + if(3) //Brown Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi' + H.tail = "voxtail_brn" + if(2) //Dark Green Vox. + new_icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi' + new_deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi' + H.tail = "voxtail_dgrn" + else //Default Green Vox. + H.tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone. + + H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so. + H.update_dna() + +/datum/species/vox/handle_reagents(mob/living/carbon/human/H, datum/reagent/R) + if(R.id == "oxygen") //Armalis are above such petty things. + H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma. + H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM) + return FALSE //Handling reagent removal on our own. + + return ..() + +/datum/species/vox/armalis + name = "Vox Armalis" + name_plural = "Vox Armalis" + icobase = 'icons/mob/human_races/r_armalis.dmi' + deform = 'icons/mob/human_races/r_armalis.dmi' + unarmed_type = /datum/unarmed_attack/claws/armalis + blacklisted = TRUE + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + heat_level_1 = 2000 + heat_level_2 = 3000 + heat_level_3 = 4000 + + brute_mod = 0.2 + burn_mod = 0.2 + + eyes = "blank_eyes" + + species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED) + bodyflags = HAS_TAIL + dietflags = DIET_OMNI //should inherit this from vox, this is here just in case + + blood_color = "#2299FC" + flesh_color = "#808D11" + + reagent_tag = PROCESS_ORG + + tail = "armalis_tail" + icon_template = 'icons/mob/human_races/r_armalis.dmi' + + has_organ = list( + "heart" = /obj/item/organ/internal/heart, + "lungs" = /obj/item/organ/internal/lungs/vox, + "liver" = /obj/item/organ/internal/liver, + "kidneys" = /obj/item/organ/internal/kidneys, + "brain" = /obj/item/organ/internal/brain, + "eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2. + "stack" = /obj/item/organ/internal/stack //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. + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!", + "is huffing oxygen!") + +/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things. + return TRUE \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/vulpkanin.dm b/code/modules/mob/living/carbon/human/species/vulpkanin.dm new file mode 100644 index 00000000000..3e6ebc1d41d --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -0,0 +1,52 @@ +/datum/species/vulpkanin + name = "Vulpkanin" + name_plural = "Vulpkanin" + icobase = 'icons/mob/human_races/r_vulpkanin.dmi' + deform = 'icons/mob/human_races/r_vulpkanin.dmi' + language = "Canilunzt" + primitive_form = /datum/species/monkey/vulpkanin + tail = "vulptail" + skinned_type = /obj/item/stack/sheet/fur + unarmed_type = /datum/unarmed_attack/claws + + 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 \ + culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \ + to the degree it can cause conflict with more rigorous and strict authorities. They speak a guttural language known as 'Canilunzt' \ + which has a heavy emphasis on utilizing tail positioning and ear twitches to communicate intent." + + species_traits = list(LIPS) + clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS + bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR + dietflags = DIET_OMNI + hunger_drain = 0.11 + taste_sensitivity = TASTE_SENSITIVITY_SHARP + reagent_tag = PROCESS_ORG + flesh_color = "#966464" + base_color = "#CF4D2F" + butt_sprite = "vulp" + + scream_verb = "yelps" + + 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 /*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, + /mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble) + + suicide_messages = list( + "is attempting to bite their tongue off!", + "is jamming their claws into their eye sockets!", + "is twisting their own neck!", + "is holding their breath!") + +/datum/species/vulpkanin/handle_death(mob/living/carbon/human/H) + H.stop_tail_wagging(1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/apollo.dm b/code/modules/mob/living/carbon/human/species/wryn.dm similarity index 59% rename from code/modules/mob/living/carbon/human/species/apollo.dm rename to code/modules/mob/living/carbon/human/species/wryn.dm index 5a3e1d4cde9..219be4111b3 100644 --- a/code/modules/mob/living/carbon/human/species/apollo.dm +++ b/code/modules/mob/living/carbon/human/species/wryn.dm @@ -3,11 +3,11 @@ name_plural = "Wryn" icobase = 'icons/mob/human_races/r_wryn.dmi' deform = 'icons/mob/human_races/r_wryn.dmi' + blacklisted = TRUE language = "Wryn Hivemind" tail = "wryntail" punchdamagelow = 0 punchdamagehigh = 1 - //primitive = /mob/living/carbon/monkey/wryn slowdown = 1 warning_low_pressure = -300 hazard_low_pressure = 1 @@ -49,11 +49,11 @@ default_hair = "Antennae" -/datum/species/wryn/handle_death(var/mob/living/carbon/human/H) +/datum/species/wryn/handle_death(mob/living/carbon/human/H) for(var/mob/living/carbon/C in living_mob_list) if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) to_chat(C, "Your antennae tingle as you are overcome with pain...") - to_chat(C, "It feels like part of you has died.") + to_chat(C, "It feels like part of you has died.") // This is bullshit /datum/species/wryn/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) if(target.handcuffed && target.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) @@ -75,46 +75,4 @@ add_attack_logs(user, target, "Antennae removed") return 0 else - ..() - -/datum/species/nucleation - name = "Nucleation" - name_plural = "Nucleations" - icobase = 'icons/mob/human_races/r_nucleation.dmi' - 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 \ - obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \ - and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \ - way as lepers were back on Earth." - 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 - species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE) - dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet - - //Default styles for created mobs. - default_hair = "Nucleation Crystals" - - reagent_tag = PROCESS_ORG - has_organ = list( - "heart" = /obj/item/organ/internal/heart, - "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 - ) - vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal - -/datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H) - H.light_color = "#1C1C00" - H.set_light(2) - return ..() - -/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H) - var/turf/T = get_turf(H) - H.visible_message("[H]'s body explodes, leaving behind a pile of microscopic crystals!") - explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death -// new /obj/item/shard/supermatter( T ) - qdel(H) \ No newline at end of file + ..() \ 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 index 5f74f202603..e7a65129017 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -1,19 +1,19 @@ /mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() /mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE) - if(species) - amount = amount * species.stun_mod + if(dna.species) + amount = amount * dna.species.stun_mod ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 3a1ac4d3a83..450b7a6c1a4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -185,7 +185,7 @@ var/global/list/damage_icon_parts = list() previous_damage_appearance = damage_appearance - var/icon/standing = new /icon(species.damage_overlays, "00") + var/icon/standing = new /icon(dna.species.damage_overlays, "00") var/image/standing_image = new /image("icon" = standing) @@ -194,12 +194,12 @@ var/global/list/damage_icon_parts = list() O.update_icon() if(O.damage_state == "00") continue var/icon/DI - var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]" + var/cache_index = "[O.damage_state]/[O.icon_name]/[dna.species.blood_color]/[dna.species.name]" if(damage_icon_parts[cache_index] == null) - DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human - DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels - DI.Blend(species.blood_color, ICON_MULTIPLY) + DI = new /icon(dna.species.damage_overlays, O.damage_state) // the damage icon for whole human + DI.Blend(new /icon(dna.species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels + DI.Blend(dna.species.blood_color, ICON_MULTIPLY) damage_icon_parts[cache_index] = DI else DI = damage_icon_parts[cache_index] @@ -220,15 +220,15 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in mutations) var/skeleton = (SKELETON in mutations) - if(species && species.bodyflags & HAS_ICON_SKIN_TONE) - species.updatespeciescolor(src) + if(dna.species && dna.species.bodyflags & HAS_ICON_SKIN_TONE) + dna.species.updatespeciescolor(src) //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. //Create a new, blank icon for our mob to use. if(stand_icon) qdel(stand_icon) - stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") + stand_icon = new(dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi',"blank") var/icon_key = "" var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes) @@ -237,7 +237,7 @@ var/global/list/damage_icon_parts = list() else icon_key += "#000000" - for(var/organ_tag in species.has_limbs) + for(var/organ_tag in dna.species.has_limbs) var/obj/item/organ/external/part = bodyparts_by_name[organ_tag] if(isnull(part)) icon_key += "0" @@ -249,7 +249,8 @@ var/global/list/damage_icon_parts = list() icon_key += "1" if(part) - icon_key += "[part.species.race_key]" + var/datum/species/S = GLOB.all_species[part.dna.species.name] //This has to reference the species datums from round start, since they're global and unchanging + icon_key += "[S.race_key]" icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]" if(part.s_col) @@ -307,7 +308,7 @@ var/global/list/damage_icon_parts = list() //END CACHED ICON GENERATION. stand_icon.Blend(base_icon,ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this) overlays_standing[LIMBS_LAYER] = image(stand_icon) // Diverts limbs to their own layer so they can overlay things (i.e. tails). else overlays_standing[LIMBS_LAYER] = null // So we don't get the old species' sprite splatted on top of the new one's @@ -316,18 +317,18 @@ var/global/list/damage_icon_parts = list() overlays_standing[UNDERWEAR_LAYER] = null var/icon/underwear_standing = new/icon('icons/mob/underwear.dmi',"nude") - if(underwear && species.clothing_flags & HAS_UNDERWEAR) + if(underwear && dna.species.clothing_flags & HAS_UNDERWEAR) var/datum/sprite_accessory/underwear/U = underwear_list[underwear] if(U) underwear_standing.Blend(new /icon(U.icon, "uw_[U.icon_state]_s"), ICON_OVERLAY) - if(undershirt && species.clothing_flags & HAS_UNDERSHIRT) + if(undershirt && dna.species.clothing_flags & HAS_UNDERSHIRT) var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt] if(U2) underwear_standing.Blend(new /icon(U2.icon, "us_[U2.icon_state]_s"), ICON_OVERLAY) - if(socks && species.clothing_flags & HAS_SOCKS) + if(socks && dna.species.clothing_flags & HAS_SOCKS) var/datum/sprite_accessory/socks/U3 = socks_list[socks] if(U3) underwear_standing.Blend(new /icon(U3.icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY) @@ -339,7 +340,7 @@ var/global/list/damage_icon_parts = list() if(update_icons) update_icons() - if(lip_style && (LIPS in species.species_traits)) + if(lip_style && (LIPS in dna.species.species_traits)) var/icon/lips = icon("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]_s") lips.Blend(lip_color, ICON_ADD) @@ -369,7 +370,7 @@ var/global/list/damage_icon_parts = list() if(chest_organ && m_styles["body"]) var/body_marking = m_styles["body"] var/datum/sprite_accessory/body_marking_style = marking_styles_list[body_marking] - if(body_marking_style && body_marking_style.species_allowed && (species.name in body_marking_style.species_allowed)) + if(body_marking_style && body_marking_style.species_allowed && (dna.species.name in body_marking_style.species_allowed)) var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s") if(body_marking_style.do_colouration) b_marking_s.Blend(m_colours["body"], ICON_ADD) @@ -379,7 +380,7 @@ var/global/list/damage_icon_parts = list() if(head_organ && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example. var/head_marking = m_styles["head"] var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (head_organ.species.name in head_marking_style.species_allowed)) + if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed)) var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(m_colours["head"], ICON_ADD) @@ -407,10 +408,10 @@ var/global/list/damage_icon_parts = list() //base icons var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(head_organ.ha_style && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY)) + if(head_organ.ha_style && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)) var/datum/sprite_accessory/head_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) - if(head_organ.species.name in head_accessory_style.species_allowed) + if(head_organ.dna.species.name in head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(head_organ.headacc_colour, ICON_ADD) @@ -448,12 +449,12 @@ var/global/list/damage_icon_parts = list() if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic()))) var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style] - //if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN + //if(!src.get_int_organ(/obj/item/organ/internal/brain) && !ismachine(src))//make it obvious we have NO BRAIN // hair_standing.Blend(debrained_s, ICON_OVERLAY) if(hair_style && hair_style.species_allowed) - if((head_organ.species.name in hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... + if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(head_organ.species.name == "Slime People") // I am el worstos + if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos hair_s.Blend("[skin_colour]A0", ICON_AND) else if(hair_style.do_colouration) hair_s.Blend(head_organ.hair_colour, ICON_ADD) @@ -497,9 +498,9 @@ var/global/list/damage_icon_parts = list() if(head_organ.f_style) var/datum/sprite_accessory/facial_hair/facial_hair_style = facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) - if((head_organ.species.name in facial_hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... + if((head_organ.dna.species.name in facial_hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(head_organ.species.name == "Slime People") // I am el worstos + if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[skin_colour]A0", ICON_AND) else if(facial_hair_style.do_colouration) facial_s.Blend(head_organ.facial_colour, ICON_ADD) @@ -644,11 +645,11 @@ var/global/list/damage_icon_parts = list() if(w_uniform.icon_override) standing.icon = w_uniform.icon_override - else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.name]) - standing.icon = w_uniform.sprite_sheets[species.name] + else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[dna.species.name]) + standing.icon = w_uniform.sprite_sheets[dna.species.name] if(w_uniform.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "uniformblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "uniformblood") bloodsies.color = w_uniform.blood_color standing.overlays += bloodsies @@ -658,8 +659,8 @@ var/global/list/damage_icon_parts = list() if(!tie_color) tie_color = A.icon_state if(A.icon_override) standing.overlays += image("icon" = A.icon_override, "icon_state" = "[A.icon_state]") - else if(A.sprite_sheets && A.sprite_sheets[species.name]) - standing.overlays += image("icon" = A.sprite_sheets[species.name], "icon_state" = "[A.icon_state]") + else if(A.sprite_sheets && A.sprite_sheets[dna.species.name]) + standing.overlays += image("icon" = A.sprite_sheets[dna.species.name], "icon_state" = "[A.icon_state]") else standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") @@ -720,19 +721,19 @@ var/global/list/damage_icon_parts = list() var/image/standing if(gloves.icon_override) standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]") - else if(gloves.sprite_sheets && gloves.sprite_sheets[species.name]) - standing = image("icon" = gloves.sprite_sheets[species.name], "icon_state" = "[t_state]") + else if(gloves.sprite_sheets && gloves.sprite_sheets[dna.species.name]) + standing = image("icon" = gloves.sprite_sheets[dna.species.name], "icon_state" = "[t_state]") else standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]") if(gloves.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = gloves.blood_color standing.overlays += bloodsies overlays_standing[GLOVES_LAYER] = standing else if(blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = hand_blood_color overlays_standing[GLOVES_LAYER] = bloodsies else @@ -759,8 +760,8 @@ var/global/list/damage_icon_parts = list() if(glasses.icon_override) new_glasses = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]") - else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.species.name]) - new_glasses = image("icon" = glasses.sprite_sheets[head_organ.species.name], "icon_state" = "[glasses.icon_state]") + else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.dna.species.name]) + new_glasses = image("icon" = glasses.sprite_sheets[head_organ.dna.species.name], "icon_state" = "[glasses.icon_state]") else new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]") @@ -795,9 +796,9 @@ var/global/list/damage_icon_parts = list() if(l_ear.icon_override) t_type = "[t_type]_l" overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]") - else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.name]) + else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name]) t_type = "[t_type]_l" - overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.name], "icon_state" = "[t_type]") + overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]") else overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") @@ -811,9 +812,9 @@ var/global/list/damage_icon_parts = list() if(r_ear.icon_override) t_type = "[t_type]_r" overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]") - else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.name]) + else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name]) t_type = "[t_type]_r" - overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.name], "icon_state" = "[t_type]") + overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]") else overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]") @@ -837,20 +838,20 @@ var/global/list/damage_icon_parts = list() var/image/standing if(shoes.icon_override) standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]") - else if(shoes.sprite_sheets && shoes.sprite_sheets[species.name]) - standing = image("icon" = shoes.sprite_sheets[species.name], "icon_state" = "[shoes.icon_state]") + else if(shoes.sprite_sheets && shoes.sprite_sheets[dna.species.name]) + standing = image("icon" = shoes.sprite_sheets[dna.species.name], "icon_state" = "[shoes.icon_state]") else standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]") if(shoes.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = shoes.blood_color standing.overlays += bloodsies overlays_standing[SHOES_LAYER] = standing else if(feet_blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = feet_blood_color overlays_standing[SHOES_LAYER] = bloodsies else @@ -891,13 +892,13 @@ var/global/list/damage_icon_parts = list() var/image/standing if(head.icon_override) standing = image("icon" = head.icon_override, "icon_state" = "[head.icon_state]") - else if(head.sprite_sheets && head.sprite_sheets[species.name]) - standing = image("icon" = head.sprite_sheets[species.name], "icon_state" = "[head.icon_state]") + else if(head.sprite_sheets && head.sprite_sheets[dna.species.name]) + standing = image("icon" = head.sprite_sheets[dna.species.name], "icon_state" = "[head.icon_state]") else standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]") if(head.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood") bloodsies.color = head.blood_color standing.overlays += bloodsies overlays_standing[HEAD_LAYER] = standing @@ -925,8 +926,8 @@ var/global/list/damage_icon_parts = list() if(belt.icon_override) t_state = "[t_state]_be" overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]") - else if(belt.sprite_sheets && belt.sprite_sheets[species.name]) - overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[species.name], "icon_state" = "[t_state]") + else if(belt.sprite_sheets && belt.sprite_sheets[dna.species.name]) + overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[dna.species.name], "icon_state" = "[t_state]") else overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]") else @@ -949,8 +950,8 @@ var/global/list/damage_icon_parts = list() var/image/standing if(wear_suit.icon_override) standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]") - else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name]) - standing = image("icon" = wear_suit.sprite_sheets[species.name], "icon_state" = "[wear_suit.icon_state]") + else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name]) + standing = image("icon" = wear_suit.sprite_sheets[dna.species.name], "icon_state" = "[wear_suit.icon_state]") else if(FAT in mutations) if(wear_suit.flags_size & ONESIZEFITSALL) standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]") @@ -969,7 +970,7 @@ var/global/list/damage_icon_parts = list() if(wear_suit.blood_DNA) var/obj/item/clothing/suit/S = wear_suit - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") bloodsies.color = wear_suit.blood_color standing.overlays += bloodsies @@ -1035,14 +1036,14 @@ var/global/list/damage_icon_parts = list() if(wear_mask.icon_override) mask_icon = new(wear_mask.icon_override) standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") - else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.name]) - mask_icon = new(wear_mask.sprite_sheets[species.name]) - standing = image("icon" = wear_mask.sprite_sheets[species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") + else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name]) + mask_icon = new(wear_mask.sprite_sheets[dna.species.name]) + standing = image("icon" = wear_mask.sprite_sheets[dna.species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") else standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]") if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA) - var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood") + var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood") bloodsies.color = wear_mask.blood_color standing.overlays += bloodsies overlays_standing[FACEMASK_LAYER] = standing @@ -1062,8 +1063,8 @@ var/global/list/damage_icon_parts = list() //If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc. var/obj/item/rig/rig = back standing = rig.mob_icon - else if(back.sprite_sheets && back.sprite_sheets[species.name]) - standing = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]") + else if(back.sprite_sheets && back.sprite_sheets[dna.species.name]) + standing = image("icon" = back.sprite_sheets[dna.species.name], "icon_state" = "[back.icon_state]") else standing = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]") @@ -1163,7 +1164,7 @@ var/global/list/damage_icon_parts = list() var/icon/tail_marking_icon var/datum/sprite_accessory/body_markings/tail/tail_marking_style - if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS)) + if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS)) var/tail_marking = m_styles["tail"] tail_marking_style = marking_styles_list[tail_marking] tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]_s") @@ -1172,11 +1173,11 @@ var/global/list/damage_icon_parts = list() if(body_accessory) if(body_accessory.try_restrictions(src)) var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) @@ -1194,14 +1195,14 @@ var/global/list/damage_icon_parts = list() else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) - else if(tail && species.bodyflags & HAS_TAIL) //no tailless tajaran + else if(tail && dna.species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]_s") - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) tail_s.Blend(skin_colour, ICON_ADD) if(tail_marking_icon && !tail_marking_style.tails_allowed) tail_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank") under.Insert(new/icon(tail_s, dir=SOUTH), dir=SOUTH) @@ -1230,7 +1231,7 @@ var/global/list/damage_icon_parts = list() var/icon/tail_marking_icon var/datum/sprite_accessory/body_markings/tail/tail_marking_style - if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS)) + if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS)) var/tail_marking = m_styles["tail"] tail_marking_style = marking_styles_list[tail_marking] tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]w_s") @@ -1238,15 +1239,15 @@ var/global/list/damage_icon_parts = list() if(body_accessory) var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) - under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) + under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST) under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST) @@ -1255,23 +1256,23 @@ var/global/list/damage_icon_parts = list() // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank - over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank + over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH) overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation. overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) - else if(tail && species.bodyflags & HAS_TAIL) + else if(tail && dna.species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s") - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) tailw_s.Blend(skin_colour, ICON_ADD) if(tail_marking_icon && !tail_marking_style.tails_allowed) tailw_s.Blend(tail_marking_icon, ICON_OVERLAY) - if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. - var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") under.Insert(new/icon(tailw_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST) under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST) @@ -1279,7 +1280,7 @@ var/global/list/damage_icon_parts = list() overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. - var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay") + var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH) overlays_standing[TAIL_LAYER] = image(over) @@ -1314,8 +1315,8 @@ var/global/list/damage_icon_parts = list() var/icon/icon_file = new(icon_path) if(wear_suit.icon_state in icon_file.IconStates()) standing = image("icon" = icon_file, "icon_state" = "[wear_suit.icon_state]") - else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name]) - var/icon_path = "[wear_suit.sprite_sheets[species.name]]" + else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name]) + var/icon_path = "[wear_suit.sprite_sheets[dna.species.name]]" icon_path = "[copytext(icon_path, 1, findtext(icon_path, "/suit.dmi"))]/collar.dmi" //If this file doesn't exist, the end result is that COLLAR_LAYER will be unchanged (empty). if(fexists(icon_path)) //Just ensuring the nonexistance of a file with the above path won't cause a runtime. var/icon/icon_file = new(icon_path) diff --git a/code/modules/mob/living/carbon/slime/life.dm b/code/modules/mob/living/carbon/slime/life.dm index 80ed9fdbffd..5b0ee885ce7 100644 --- a/code/modules/mob/living/carbon/slime/life.dm +++ b/code/modules/mob/living/carbon/slime/life.dm @@ -337,7 +337,7 @@ if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men var/mob/living/carbon/human/H = L - if(H.species.name == "Slime People") + if(isslimeperson(H)) continue if(!L.canmove) // Only one slime can latch on at a time. diff --git a/code/modules/mob/living/carbon/superheroes.dm b/code/modules/mob/living/carbon/superheroes.dm index d9c7a9f12ef..50b22a2c8ed 100644 --- a/code/modules/mob/living/carbon/superheroes.dm +++ b/code/modules/mob/living/carbon/superheroes.dm @@ -217,7 +217,7 @@ to_chat(target, "You must follow the orders of [user], and help [user.p_them()] succeed in [user.p_their()] 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") + target.set_species(/datum/species/human) head_organ.h_style = "Bald" head_organ.f_style = "Shaved" target.s_tone = 35 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bff49e7c527..4cfdc7bb1f4 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1,4 +1,4 @@ -/mob/living/New() +/mob/living/Initialize() . = ..() var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED] medhud.add_to_hud(src) @@ -660,14 +660,14 @@ TH.transfer_mob_blood_dna(src) if(ishuman(src)) var/mob/living/carbon/human/H = src - if(H.species.blood_color) - TH.color = H.species.blood_color + if(H.dna.species.blood_color) + TH.color = H.dna.species.blood_color else TH.color = "#A10808" /mob/living/carbon/human/makeTrail(turf/T) - if((NO_BLOOD in species.species_traits) || species.exotic_blood || !bleed_rate || bleedsuppress) + if((NO_BLOOD in dna.species.species_traits) || dna.species.exotic_blood || !bleed_rate || bleedsuppress) return ..() diff --git a/code/modules/mob/living/silicon/decoy/death.dm b/code/modules/mob/living/silicon/decoy/death.dm index d3996e2fa70..624343af464 100644 --- a/code/modules/mob/living/silicon/decoy/death.dm +++ b/code/modules/mob/living/silicon/decoy/death.dm @@ -1,10 +1,10 @@ /mob/living/silicon/decoy/death(gibbed) - if(stat == DEAD) return + if(stat == DEAD) + return stat = DEAD icon_state = "ai-crash" - spawn(10) - explosion(loc, 3, 6, 12, 15) - for(var/obj/machinery/ai_status_display/O in world) //change status - O.mode = 2 - return ..(gibbed) \ No newline at end of file + if(atoms_share_level(O, src)) + O.mode = 2 + ..(0) + gib() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/decoy/decoy.dm b/code/modules/mob/living/silicon/decoy/decoy.dm index bbbfe19dadb..916d77992bf 100644 --- a/code/modules/mob/living/silicon/decoy/decoy.dm +++ b/code/modules/mob/living/silicon/decoy/decoy.dm @@ -4,9 +4,54 @@ icon_state = "ai" anchored = 1 // -- TLE canmove = 0 + a_intent = INTENT_HARM // This is apparently the only thing that stops other mobs walking through them as if they were thin air. /mob/living/silicon/decoy/New() src.icon = 'icons/mob/AI.dmi' src.icon_state = "ai" src.anchored = 1 - src.canmove = 0 \ No newline at end of file + src.canmove = 0 + +/mob/living/silicon/decoy/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/aicard)) + to_chat(user, "You cannot find an intellicard slot on [src].") + return TRUE + else + return ..() + +/mob/living/silicon/decoy/syndicate + faction = list("syndicate") + name = "R.O.D.G.E.R" + desc = "Red Operations, Depot General Emission Regulator" + icon_state = "ai-magma" + +/mob/living/silicon/decoy/syndicate/New() + . = ..() + icon_state = "ai-magma" + +/mob/living/silicon/decoy/syndicate/depot + var/raised_alert = FALSE + +/mob/living/silicon/decoy/syndicate/depot/proc/raise_alert() + raised_alert = TRUE + var/area/syndicate_depot/core/depotarea = get_area(src) // Cannot use myArea or areaMaster as neither will be defined for this mob type + if(istype(depotarea)) + depotarea.increase_alert("AI Unit Offline") + else + say("Connection failure!") + +/mob/living/silicon/decoy/syndicate/depot/death(pass) + if(!raised_alert) + raise_alert() + . = ..(pass) + +/mob/living/silicon/decoy/syndicate/depot/adjustBruteLoss(dmg) + . = ..(dmg) + updatehealth() + +/mob/living/silicon/decoy/syndicate/depot/adjustFireLoss(dmg) + . = ..(dmg) + updatehealth() + +/mob/living/silicon/decoy/syndicate/depot/ex_act(severity) + adjustBruteLoss(250) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/decoy/life.dm b/code/modules/mob/living/silicon/decoy/life.dm index 353bf4259ff..dc1324dc6dd 100644 --- a/code/modules/mob/living/silicon/decoy/life.dm +++ b/code/modules/mob/living/silicon/decoy/life.dm @@ -1,10 +1,5 @@ /mob/living/silicon/decoy/Life(seconds, times_fired) - if(src.stat == 2) - return - else - if(src.health <= config.health_threshold_dead && src.stat != 2) - death() - return + return /mob/living/silicon/decoy/updatehealth() @@ -13,3 +8,11 @@ stat = CONSCIOUS else health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() + update_stat() + + +/mob/living/silicon/decoy/update_stat() + if(stat == DEAD) + return + if(health <= 0) + death() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 5802bdeb9ec..cc5108d89f8 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -237,7 +237,7 @@ if(!E.is_robotic()) continue organ_found = 1 - to_chat(user, "[E.name]: [round(E.brute_dam)] [round(E.burn_dam)]") + to_chat(user, "[E.name]: [E.brute_dam] [E.burn_dam]") if(!organ_found) to_chat(user, "No prosthetics located.") to_chat(user, "
    ") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4f6707e93f0..755b874667a 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -131,8 +131,8 @@ var/list/robot_verbs_default = list( camera.status = 0 if(mmi == null) - mmi = new /obj/item/mmi/posibrain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a posibrain, but it works) - mmi.icon_state="posibrain-occupied" + mmi = new /obj/item/mmi/robotic_brain(src) //Give the borg an MMI if he spawns without for some reason. (probably not the correct way to spawn a robotic brain, but it works) + mmi.icon_state = "boris" initialize_components() //if(!unfinished) @@ -210,7 +210,7 @@ var/list/robot_verbs_default = list( if(prefix) modtype = prefix if(mmi) - if(istype(mmi, /obj/item/mmi/posibrain)) + if(istype(mmi, /obj/item/mmi/robotic_brain)) braintype = "Android" else braintype = "Cyborg" diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 9d7fa39ed87..6895dc21cbc 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -204,6 +204,10 @@ if(disabled) return + ed209_ai() + + +/mob/living/simple_animal/bot/ed209/proc/ed209_ai() var/list/targets = list() for(var/mob/living/carbon/C in view(7, src)) //Let's find us a target var/threatlevel = 0 diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 6cdffd48f16..007688fb7db 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -45,6 +45,7 @@ var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible. var/shut_up = 0 //self explanatory :) var/syndicate_aligned = FALSE // Will it only treat operatives? + var/drops_parts = TRUE /mob/living/simple_animal/bot/medbot/tox skin = "tox" @@ -77,6 +78,7 @@ name = "Suspicious Medibot" desc = "You'd better have insurance!" skin = "bezerk" + faction = list("syndicate") treatment_oxy = "perfluorodecalin" treatment_brute = "bicaridine" treatment_fire = "kelotane" @@ -91,6 +93,11 @@ ..() Radio.syndie = 1 +/mob/living/simple_animal/bot/medbot/syndicate/emagged + emagged = 2 + declare_crit = 0 + drops_parts = FALSE + /mob/living/simple_animal/bot/medbot/update_icon() overlays.Cut() if(skin) @@ -373,7 +380,7 @@ // is secretly a silicon if(ishuman(C)) var/mob/living/carbon/human/H = C - if(H.species && H.species.reagent_tag == PROCESS_SYN) + if(H.dna.species && H.dna.species.reagent_tag == PROCESS_SYN) return 0 if(emagged == 2) //Everyone needs our medicine. (Our medicine is toxins) @@ -554,36 +561,37 @@ visible_message("[src] blows apart!") var/turf/Tsec = get_turf(src) - switch(skin) - if("ointment") - new /obj/item/storage/firstaid/fire/empty(Tsec) - if("tox") - new /obj/item/storage/firstaid/toxin/empty(Tsec) - if("o2") - new /obj/item/storage/firstaid/o2/empty(Tsec) - if("brute") - new /obj/item/storage/firstaid/brute/empty(Tsec) - if("adv") - new /obj/item/storage/firstaid/adv/empty(Tsec) - if("bezerk") - var/obj/item/storage/firstaid/tactical/empty/T = new(Tsec) - T.syndicate_aligned = syndicate_aligned //This is a special case since Syndicate medibots and the mysterious medibot look the same; we also dont' want crew building Syndicate medibots if the mysterious medibot blows up. - if("fish") - new /obj/item/storage/firstaid/aquatic_kit(Tsec) - else - new /obj/item/storage/firstaid(Tsec) + if(drops_parts) + switch(skin) + if("ointment") + new /obj/item/storage/firstaid/fire/empty(Tsec) + if("tox") + new /obj/item/storage/firstaid/toxin/empty(Tsec) + if("o2") + new /obj/item/storage/firstaid/o2/empty(Tsec) + if("brute") + new /obj/item/storage/firstaid/brute/empty(Tsec) + if("adv") + new /obj/item/storage/firstaid/adv/empty(Tsec) + if("bezerk") + var/obj/item/storage/firstaid/tactical/empty/T = new(Tsec) + T.syndicate_aligned = syndicate_aligned //This is a special case since Syndicate medibots and the mysterious medibot look the same; we also dont' want crew building Syndicate medibots if the mysterious medibot blows up. + if("fish") + new /obj/item/storage/firstaid/aquatic_kit(Tsec) + else + new /obj/item/storage/firstaid(Tsec) - new /obj/item/assembly/prox_sensor(Tsec) + new /obj/item/assembly/prox_sensor(Tsec) - new /obj/item/healthanalyzer(Tsec) + new /obj/item/healthanalyzer(Tsec) + + if(prob(50)) + new /obj/item/robot_parts/l_arm(Tsec) if(reagent_glass) reagent_glass.forceMove(Tsec) reagent_glass = null - if(prob(50)) - new /obj/item/robot_parts/l_arm(Tsec) - if(emagged && prob(25)) playsound(loc, 'sound/voice/minsult.ogg', 50, 0) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 3243061273f..0efaefcce07 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -715,7 +715,7 @@ var/list/blood_dna = H.get_blood_dna_list() if(blood_dna) transfer_blood_dna(blood_dna) - currentBloodColor = H.species.blood_color + currentBloodColor = H.dna.species.blood_color return /mob/living/simple_animal/bot/mulebot/bot_control_message(command, mob/user, user_turf) diff --git a/code/modules/mob/living/simple_animal/bot/syndicate.dm b/code/modules/mob/living/simple_animal/bot/syndicate.dm new file mode 100644 index 00000000000..3ca3c6d1f2b --- /dev/null +++ b/code/modules/mob/living/simple_animal/bot/syndicate.dm @@ -0,0 +1,216 @@ + +/mob/living/simple_animal/bot/ed209/syndicate + name = "Syndicate Sentry Bot" + desc = "A syndicate security bot." + model = "Guardian" + icon = 'icons/mecha/mecha.dmi' + icon_state = "darkgygax" + radio_channel = "Syndicate" + health = 300 + maxHealth = 300 + declare_arrests = 0 + idcheck = 1 + arrest_type = 1 + auto_patrol = 1 + emagged = 2 + faction = list("syndicate") + shoot_sound = 'sound/weapons/wave.ogg' + anchored = 1 + pressure_resistance = 100 //100 kPa difference required to push + throw_pressure_limit = 120 + window_id = "syndiebot" + window_name = "Syndicate Bot Interface" + var/turf/saved_turf + var/stepsound = 'sound/mecha/mechstep.ogg' + var/area/syndicate_depot/core/depotarea + var/raised_alert = FALSE + var/pathing_failed = FALSE + var/turf/spawn_turf + +/mob/living/simple_animal/bot/ed209/syndicate/New() + ..() + if(access_card) + access_card.access = list(access_syndicate, access_syndicate_leader) + set_weapon() + update_icon() + spawn_turf = get_turf(src) + + +/mob/living/simple_animal/bot/ed209/syndicate/update_icon() + icon_state = initial(icon_state) + +/mob/living/simple_animal/bot/ed209/syndicate/turn_on() + . = ..() + update_icon() + +/mob/living/simple_animal/bot/ed209/syndicate/turn_off() + ..() + update_icon() + +/mob/living/simple_animal/bot/ed209/syndicate/get_controls(mob/user) + to_chat(user, "[src] has no accessible control panel!") + return + +/mob/living/simple_animal/bot/ed209/syndicate/show_controls(mob/M) + return + +/mob/living/simple_animal/bot/ed209/syndicate/Topic(href, href_list) + return + +/mob/living/simple_animal/bot/ed209/syndicate/retaliate(mob/living/carbon/human/H) + if(!H) + return + target = H + mode = BOT_HUNT + +/mob/living/simple_animal/bot/ed209/syndicate/emag_act(mob/user) + to_chat(user, "[src] has no card reader slot!") + +/mob/living/simple_animal/bot/ed209/syndicate/ed209_ai() + var/turf/current_turf = get_turf(src) + if(saved_turf && current_turf != saved_turf) + playsound(loc, stepsound, 40, 1) + if(spawn_turf && !atoms_share_level(src, spawn_turf)) + raise_alert("[src] lost in space.") + raised_alert = FALSE + raise_alert("[src] activated self-destruct.") + qdel(src) + saved_turf = current_turf + switch(mode) + if(BOT_IDLE) + walk_to(src,0) + look_for_perp() + if(!mode && auto_patrol) + mode = BOT_START_PATROL + if(BOT_HUNT) + if(frustration >= 8) + walk_to(src,0) + back_to_idle() + if(target) + if(isliving(target)) + if(target.stat == DEAD) + back_to_idle() + return + shootAt(target) + var/turf/olddist = get_dist(src, target) + walk_to(src, target,1,4) + if((get_dist(src, target)) >= (olddist)) + frustration++ + else + frustration = 0 + else + back_to_idle() + if(BOT_START_PATROL) + look_for_perp() + start_patrol() + if(BOT_PATROL) + look_for_perp() + bot_patrol() + else + back_to_idle() + return + +/mob/living/simple_animal/bot/ed209/syndicate/look_for_perp() + if(disabled) + return + for(var/mob/M in view(7, src)) + if(M.invisibility > see_invisible) + continue + if("syndicate" in M.faction) + continue + if(M.stat == DEAD) + continue + if((M.name == oldtarget_name) && (world.time < last_found + 100)) + continue + target = M + oldtarget_name = M.name + mode = BOT_HUNT + spawn(0) + handle_automated_action() + break + for(var/obj/spacepod/P in view(7, src)) + if((P.name == oldtarget_name) && (world.time < last_found + 100)) + continue + if(!P.pilot) + continue + if("syndicate" in P.pilot.faction) + continue + if(P.pilot.stat == DEAD) + continue + target = P + oldtarget_name = P.name + mode = BOT_HUNT + spawn(0) + handle_automated_action() + break + + +/mob/living/simple_animal/bot/ed209/syndicate/shootAt(atom/target) + if(lastfired && world.time - lastfired < shot_delay) + return + lastfired = world.time + var/obj/item/projectile/P = new projectile(loc) + playsound(loc, shoot_sound, 100, 1) + P.current = loc + P.starting = loc + P.firer = src + P.yo = target.y - loc.y + P.xo = target.x - loc.x + P.original = target + P.fire() + +/mob/living/simple_animal/bot/ed209/syndicate/explode() + if (!QDELETED(src)) + if(depotarea) + depotarea.list_remove(src, depotarea.guard_list) + walk_to(src,0) + visible_message("[src] blows apart!") + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, src) + s.start() + new /obj/effect/decal/cleanable/blood/oil(loc) + var/obj/effect/decal/mecha_wreckage/gygax/dark/wreck = new /obj/effect/decal/mecha_wreckage/gygax/dark(loc) + wreck.name = "sentry bot wreckage" + + raise_alert("[src] destroyed.") + qdel(src) + +/mob/living/simple_animal/bot/ed209/syndicate/set_weapon() + projectile = /obj/item/projectile/bullet/a40mm + +/mob/living/simple_animal/bot/ed209/syndicate/emp_act(severity) + return + +/mob/living/simple_animal/bot/ed209/UnarmedAttack(atom/A) + if(!on) + return + shootAt(A) + +/mob/living/simple_animal/bot/ed209/syndicate/cuff(mob/living/carbon/C) + shootAt(C) + +/mob/living/simple_animal/bot/ed209/syndicate/stun_attack(mob/living/carbon/C) + shootAt(C) + +/mob/living/simple_animal/bot/ed209/syndicate/speak() + return + +/mob/living/simple_animal/bot/ed209/syndicate/Process_Spacemove(movement_dir = 0) + return 1 + +/mob/living/simple_animal/bot/ed209/syndicate/start_patrol() + if(tries >= BOT_STEP_MAX_RETRIES) + if(!pathing_failed) + pathing_failed = TRUE + var/failmsg = "Depot: [src] at [loc.x],[loc.y],[loc.z] lacks patrol target." + if(istype(patrol_target)) + failmsg = "Depot: [src] at [loc.x],[loc.y],[loc.z] cannot reach [patrol_target.x],[patrol_target.y]" + log_debug(failmsg) + return ..() + +/mob/living/simple_animal/bot/ed209/syndicate/proc/raise_alert(reason) + if(raised_alert) + return + raised_alert = TRUE + if(depotarea) + depotarea.increase_alert(reason) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/corpse.dm b/code/modules/mob/living/simple_animal/corpse.dm index 772d6888222..31b40eb924b 100644 --- a/code/modules/mob/living/simple_animal/corpse.dm +++ b/code/modules/mob/living/simple_animal/corpse.dm @@ -115,6 +115,11 @@ corpseidjob = "Operative" corpseidaccess = "Syndicate" +/obj/effect/landmark/mobcorpse/syndicateautogib/createCorpse() + var/mob/living/carbon/human/M = new /mob/living/carbon/human(loc) + M.real_name = src.name + M.gib() + qdel(src) /obj/effect/landmark/mobcorpse/clown diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index 64fe7d05b9b..669271f3ead 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -54,7 +54,7 @@ /mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M) //Let people pick the little buggers up. if(M.a_intent == INTENT_HELP) - if(M.species && M.species.name == "Diona") + if(isdiona(M)) 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.") verbs += /mob/living/simple_animal/diona/proc/split @@ -82,7 +82,7 @@ if(ishuman(C)) var/mob/living/carbon/human/D = C - if(D.species && D.species.name == "Diona") + if(isdiona(D)) choices += C var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices @@ -142,7 +142,7 @@ 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(loc)) - adult.set_species("Diona") + adult.set_species(/datum/species/diona) if(istype(loc, /obj/item/holder/diona)) var/obj/item/holder/diona/L = loc @@ -156,8 +156,7 @@ adult.name = "diona ([rand(100,999)])" adult.real_name = adult.name 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") + adult.real_name = adult.dna.species.get_random_name() //I hate this being here of all places but unfortunately dna is based on real_name! for(var/obj/item/W in contents) unEquip(W) @@ -178,7 +177,7 @@ if(!M || !src) return - if(NO_BLOOD in M.species.species_traits) + if(NO_BLOOD in M.dna.species.species_traits) to_chat(src, "That donor has no blood to take.") 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 a8784a6d150..370418134c3 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -234,7 +234,7 @@ var/global/chicken_count = 0 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/layMessage = EGG_LAYING_MESSAGES var/list/validColors = list("brown","black","white") gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index b98d4181475..37ed25f15e8 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -157,7 +157,7 @@ if(istype(mmi, /obj/item/mmi)) icon_state = "spiderbot-chassis-mmi" icon_living = "spiderbot-chassis-mmi" - if(istype(mmi, /obj/item/mmi/posibrain)) + if(istype(mmi, /obj/item/mmi/robotic_brain)) icon_state = "spiderbot-chassis-posi" icon_living = "spiderbot-chassis-posi" diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 283936acb44..f3e31925228 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -178,7 +178,7 @@ if(ishuman(the_target)) var/mob/living/carbon/human/H = the_target - if(is_type_in_list(src, H.species.ignored_by)) + if(is_type_in_list(src, H.dna.species.ignored_by)) return 0 if(istype(the_target, /obj/mecha)) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm index 3462e8e18e7..7b10c0e828a 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/fish.dm @@ -27,4 +27,41 @@ speak_emote = list("gnashes") faction = list("carp") - flying = 1 \ No newline at end of file + flying = 1 + + +/mob/living/simple_animal/hostile/retaliate/carp/koi + name = "space koi" + desc = "A gentle space-faring koi." + icon = 'icons/obj/fish_items.dmi' + icon_state = "koi1" + icon_living = "koi1" + icon_dead = "koi1-dead" + + harm_intent_damage = 1 + melee_damage_lower = 2 + melee_damage_upper = 2 + speak_emote = list("blurps") + butcher_results = null + + 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 = 0 + maxbodytemp = 1500 + + gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE + +/mob/living/simple_animal/hostile/retaliate/carp/koi/New() + ..() + var/koinum = rand(1, 4) + icon_state = "koi[koinum]" + icon_living = "koi[koinum]" + icon_dead = "koi[koinum]-dead" + + +/mob/living/simple_animal/hostile/retaliate/carp/koi/Process_Spacemove(var/movement_dir) + return TRUE + +/mob/living/simple_animal/hostile/retaliate/carp/koi/honk + icon_state = "koi5" + icon_living = "koi5" + icon_dead = "koi5-dead" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index bf0bc1a7076..894c039b3f4 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -39,17 +39,20 @@ armour_penetration = 28 status_flags = 0 loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier, /obj/item/melee/energy/sword/saber/red, /obj/item/shield/energy) + var/melee_block_chance = 20 /mob/living/simple_animal/hostile/syndicate/melee/attackby(var/obj/item/O as obj, var/mob/user as mob, params) + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) if(O.force) - if(prob(80)) + if(prob(melee_block_chance)) + visible_message("[src] blocks the [O] with its shield! ") + else var/damage = O.force if(O.damtype == STAMINA) damage = 0 health -= damage visible_message("[src] has been attacked with the [O] by [user]. ") - else - visible_message("[src] blocks the [O] with its shield! ") playsound(loc, O.hitsound, 25, 1, -1) else to_chat(usr, "This weapon is ineffective, it does no damage.") @@ -65,19 +68,182 @@ visible_message("[src] blocks [Proj] with its shield!") return 0 +/mob/living/simple_animal/hostile/syndicate/melee/autogib + loot = list(/obj/effect/landmark/mobcorpse/syndicateautogib) -/mob/living/simple_animal/hostile/syndicate/melee/space +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot + name = "Syndicate Operative" + force_threshold = 6 // Prevents people using punches to bypass eshield + robust_searching = 1 // Together with stat_attack, ensures dionae/etc that regen are killed properly + stat_attack = 1 + universal_speak = 1 + melee_block_chance = 40 + var/area/syndicate_depot/core/depotarea + var/raised_alert = FALSE + var/alert_on_death = FALSE + var/alert_on_timeout = FALSE + var/alert_on_spacing = TRUE + var/alert_on_shield_breach = FALSE + var/seen_enemy = FALSE + var/seen_enemy_name = null + var/seen_revived_enemy = FALSE + var/aggro_cycles = 0 + var/scan_cycles = 0 + var/shield_key = FALSE + var/turf/spawn_turf + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/New() + ..() + name = "[name] [pick(last_names)]" + depotarea = areaMaster + spawn_turf = get_turf(src) + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/Aggro() + . = ..() + if(target && istype(depotarea)) + if(!seen_enemy) + seen_enemy = TRUE + playsound(loc, 'sound/weapons/saberon.ogg', 35, 1) + if(alert_on_shield_breach) + if(depotarea.shield_list.len) + raise_alert("[name] reports that an intruder is trying to breach the armory shield!") + alert_on_shield_breach = FALSE + raised_alert = FALSE + alert_on_death = TRUE + if(isliving(target)) + var/mob/living/M = target + depotarea.list_add(M, depotarea.hostile_list) + if(M.mind && M.mind.special_role == SPECIAL_ROLE_TRAITOR) + depotarea.saw_double_agent(M) + depotarea.declare_started() + seen_enemy_name = target.name + if(istype(target, /obj/mecha)) + depotarea.saw_mech(target) + if(istype(target, /obj/spacepod)) + depotarea.saw_pod(target) + if(depotarea.list_includes(target, depotarea.dead_list)) + seen_revived_enemy = TRUE + raise_alert("[name] reports intruder [target] has returned from death!") + depotarea.list_remove(target, depotarea.dead_list) + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/handle_automated_action() + if(seen_enemy) + aggro_cycles++ + if(alert_on_timeout && !raised_alert && aggro_cycles >= 60) + raise_alert("[name] has reported contact with hostile entity: [seen_enemy_name]") + if(scan_cycles >= 15 && istype(depotarea)) + scan_cycles = 0 + if(!atoms_share_level(src, spawn_turf)) + if(alert_on_spacing) + raise_alert("[src] lost in space.") + death() + return + for(var/mob/living/body in hearers(vision_range, targets_from)) + if(body.stat != DEAD) + continue + if(depotarea.list_includes(body, depotarea.dead_list)) + continue + if(faction_check(body)) + continue + say("Target [body]... terminated.") + depotarea.list_add(body, depotarea.dead_list) + pointed(body) + else + scan_cycles++ + ..() + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/proc/raise_alert(var/reason) + if(istype(depotarea) && (!raised_alert || seen_revived_enemy) && !depotarea.used_self_destruct) + raised_alert = TRUE + say("Intruder!") + depotarea.increase_alert(reason) + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/death() + if(alert_on_death) + if(seen_enemy_name) + raise_alert("[name] has died in combat with [seen_enemy_name].") + else + raise_alert("[name] has died.") + if(shield_key && depotarea) + depotarea.shields_key_check() + if(depotarea) + depotarea.list_remove(src, depotarea.guard_list) + return ..() + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/CanPass(atom/movable/mover, turf/target, height=0) + if(isliving(mover)) + var/mob/living/blocker = mover + if(faction_check(blocker)) + return 1 + return ..(mover, target, height) + + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer + name = "Syndicate Officer" + alert_on_death = TRUE + alert_on_timeout = TRUE + melee_block_chance = 60 + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory + name = "Syndicate Quartermaster" + icon_state = "syndicatemeleespace" + icon_living = "syndicatemeleespace" + 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 = 0 + maxHealth = 250 + health = 250 + melee_block_chance = 80 + alert_on_timeout = TRUE + alert_on_shield_breach = TRUE + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/death() + if(depotarea) + depotarea.declare_finished() + return ..() + + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/armory/Initialize() + . = ..() + if(istype(depotarea)) + var/list/key_candidates = list() + for(var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O in living_mob_list) + if(O == src) + continue + key_candidates += O + if(key_candidates.len) + var/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/officer/O = pick(key_candidates) + O.shield_key = TRUE + depotarea.shields_up() + + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space + name = "Syndicate Backup" 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 = 0 icon_state = "syndicatemeleespace" icon_living = "syndicatemeleespace" + speed = 1 + wander = 0 + alert_on_spacing = FALSE + +/mob/living/simple_animal/hostile/syndicate/melee/autogib/depot/space/Process_Spacemove(var/movement_dir = 0) + return + + + +/mob/living/simple_animal/hostile/syndicate/melee/space name = "Syndicate Commando" + 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 = 0 + icon_state = "syndicatemeleespace" + icon_living = "syndicatemeleespace" speed = 1 loot = list(/obj/effect/landmark/mobcorpse/syndicatecommando, /obj/item/melee/energy/sword/saber/red, /obj/item/shield/energy) /mob/living/simple_animal/hostile/syndicate/melee/space/Process_Spacemove(var/movement_dir = 0) return + /mob/living/simple_animal/hostile/syndicate/ranged ranged = 1 rapid = 1 @@ -97,10 +263,11 @@ speed = 1 loot = list(/obj/effect/landmark/mobcorpse/syndicatecommando, /obj/item/gun/projectile/automatic/c20r) - /mob/living/simple_animal/hostile/syndicate/ranged/space/Process_Spacemove(var/movement_dir = 0) return +/mob/living/simple_animal/hostile/syndicate/ranged/space/autogib + loot = list(/obj/effect/landmark/mobcorpse/syndicateautogib) /mob/living/simple_animal/hostile/viscerator 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 235a161c595..693ca724ac6 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 @@ -196,7 +196,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.tox_mod)) + if(!(H.dna.species.reagent_tag & PROCESS_ORG) || (!H.dna.species.tox_mod)) can_poison = 0 spider_specialattack(G,can_poison) else diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 57fe64f3265..5a88373f6f2 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -61,7 +61,8 @@ var/obj/item/clothing/accessory/petcollar/collar = null var/can_collar = 0 // can add collar to mob or not -//Hot simple_animal baby making vars + //Hot simple_animal baby making vars + var/childtype = null var/scan_ready = 1 var/simplespecies //Sorry, no spider+corgi buttbabies. @@ -79,7 +80,7 @@ var/death_sound = null //The sound played on death -/mob/living/simple_animal/New() +/mob/living/simple_animal/Initialize() ..() simple_animal_list += src verbs -= /mob/verb/observe @@ -570,3 +571,4 @@ /mob/living/simple_animal/SetEarDeaf() return + diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index fb62ad3a629..a5883fe93f2 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -56,11 +56,7 @@ if(abilities) client.verbs |= abilities - if(istype(src,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = src - if(H.species && H.species.abilities) - client.verbs |= H.species.abilities - + if(ishuman(src)) client.screen += client.void //HUD updates (antag hud, etc) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index beba84eaa3f..fc09105e948 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -24,7 +24,7 @@ ..() return QDEL_HINT_HARDDEL -/mob/New() +/mob/Initialize() mob_list += src if(stat == DEAD) dead_mob_list += src @@ -1080,9 +1080,6 @@ var/list/slot_equipment_priority = list( \ /mob/proc/activate_hand(selhand) return -/mob/proc/get_species() - return "" - /mob/dead/observer/verb/respawn() set name = "Respawn as NPC" set category = "Ghost" diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 458138b9db0..93941d6e7d2 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -410,7 +410,7 @@ return 1 var/mob/living/carbon/human/H = attacker - if(ishuman(H) && is_type_in_list(prey, H.species.allowed_consumed_mobs)) //species eating of other mobs + if(ishuman(H) && is_type_in_list(prey, H.dna.species.allowed_consumed_mobs)) //species eating of other mobs return 1 return 0 diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index d06028625b8..46b5d1b0606 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -1,7 +1,7 @@ /proc/issmall(A) if(A && istype(A, /mob/living/carbon/human)) var/mob/living/carbon/human/H = A - if(H.species && H.species.is_small) + if(H.dna.species && H.dna.species.is_small) return 1 return 0 @@ -16,9 +16,9 @@ return 0 /mob/living/carbon/human/isSynthetic() - if(get_species() == "Machine") - return 1 - return 0 + if(ismachine(src)) + return TRUE + return FALSE /mob/proc/get_screen_colour() @@ -356,7 +356,7 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM) if(hud_used && hud_used.action_intent) hud_used.action_intent.icon_state = "[a_intent]" - else if(isrobot(src) || islarva(src)) + else if(isrobot(src) || islarva(src) || isanimal(src)) switch(input) if(INTENT_HELP) a_intent = INTENT_HELP diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 274c1602e04..a2586dd65a1 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -395,7 +395,7 @@ var/arrivalmessage = announcer.arrivalmsg arrivalmessage = replacetext(arrivalmessage,"$name",character.real_name) arrivalmessage = replacetext(arrivalmessage,"$rank",rank ? "[rank]" : "visitor") - arrivalmessage = replacetext(arrivalmessage,"$species",character.species.name) + arrivalmessage = replacetext(arrivalmessage,"$species",character.dna.species.name) arrivalmessage = replacetext(arrivalmessage,"$age",num2text(character.age)) arrivalmessage = replacetext(arrivalmessage,"$gender",character.gender == FEMALE ? "Female" : "Male") announcer.say(";[arrivalmessage]") @@ -537,9 +537,6 @@ 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") mind.original = new_character mind.transfer_to(new_character) //won't transfer key since the mind is not active @@ -552,7 +549,7 @@ /mob/new_player/proc/check_prefs_are_sane() var/datum/species/chosen_species if(client.prefs.species) - chosen_species = all_species[client.prefs.species] + chosen_species = GLOB.all_species[client.prefs.species] if(!(chosen_species && (is_species_whitelisted(chosen_species) || has_admin_rights()))) // Have to recheck admin due to no usr at roundstart. Latejoins are fine though. log_runtime(EXCEPTION("[src] had species [client.prefs.species], though they weren't supposed to. Setting to Human."), src) @@ -591,19 +588,6 @@ if(!S) return 1 return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(IS_WHITELISTED in S.species_traits) -/mob/new_player/get_species() - var/datum/species/chosen_species - if(client.prefs.species) - chosen_species = all_species[client.prefs.species] - - if(!chosen_species) - return "Human" - - if(is_species_whitelisted(chosen_species) || has_admin_rights()) - return chosen_species.name - - return "Human" - /mob/new_player/get_gender() if(!client || !client.prefs) ..() return client.prefs.gender diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index d57c46e513c..fc97658896f 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -1,10 +1,10 @@ /datum/preferences //The mob should have a gender you want before running this proc. Will run fine without H /datum/preferences/proc/random_character(gender_override) - var/datum/species/S = all_species[species] + var/datum/species/S = GLOB.all_species[species] if(!istype(S)) //The species was invalid. Set the species to the default, fetch the datum for that species and generate a random character. species = initial(species) - S = all_species[species] + S = GLOB.all_species[species] var/datum/robolimb/robohead if(S.bodyflags & ALL_RPARTS) @@ -216,20 +216,20 @@ if(gender == FEMALE) g = "f" var/icon/icobase - var/datum/species/current_species = all_species[species] + var/datum/species/current_species = GLOB.all_species[species] //Icon-based species colour. var/coloured_tail if(current_species) if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. var/mob/living/carbon/human/H = new - H.species = current_species + H.dna.species = current_species H.s_tone = s_tone - H.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. + H.dna.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. var/obj/item/organ/external/chest/C = H.get_organ("chest") - icobase = C.icobase ? C.icobase : C.species.icobase - if(H.species.bodyflags & HAS_TAIL) - coloured_tail = H.tail ? H.tail : H.species.tail + icobase = C.icobase ? C.icobase : C.dna.species.icobase + if(H.dna.species.bodyflags & HAS_TAIL) + coloured_tail = H.tail ? H.tail : H.dna.species.tail qdel(H) else diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 82aebda3a42..a1ed4f0bde9 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -86,7 +86,7 @@ if(O.mind && O.mind.assigned_role == "Cyborg") if(O.mind.role_alt_title == "Android") - O.mmi = new /obj/item/mmi/posibrain(O) + O.mmi = new /obj/item/mmi/robotic_brain(O) else if(O.mind.role_alt_title == "Robot") O.mmi = null //Robots do not have removable brains. else diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 6e0be3b385f..5dd324945fa 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -36,6 +36,7 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/power_monitor()) hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) // ===== RESEARCH CONSOLE ===== /obj/machinery/modular_computer/console/preset/research diff --git a/code/modules/modular_computers/file_system/programs/command/comms.dm b/code/modules/modular_computers/file_system/programs/command/comms.dm index ef6cf016cd5..2ca6d9928a3 100644 --- a/code/modules/modular_computers/file_system/programs/command/comms.dm +++ b/code/modules/modular_computers/file_system/programs/command/comms.dm @@ -325,7 +325,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return 1 - var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") as text|null + var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return 1 @@ -344,7 +344,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return 1 - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null + var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return 1 @@ -363,7 +363,7 @@ to_chat(usr, "Arrays recycling. Please stand by.") SSnanoui.update_uis(src) return 1 - var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") as text|null + var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") if(!input || ..() || !(is_authenticated(usr) == COMM_AUTHENTICATION_MAX)) SSnanoui.update_uis(src) return 1 diff --git a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm new file mode 100644 index 00000000000..db9081f6ad1 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm @@ -0,0 +1,139 @@ +/datum/computer_file/program/supermatter_monitor + filename = "smmonitor" + filedesc = "Supermatter Monitoring" + ui_header = "smmon_0.gif" + program_icon_state = "smmon_0" + extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." + requires_ntnet = TRUE + transfer_access = access_construction + network_destination = "supermatter monitoring system" + size = 5 + var/last_status = SUPERMATTER_INACTIVE + var/list/supermatters + var/obj/machinery/power/supermatter_shard/active // Currently selected supermatter crystal. + + +/datum/computer_file/program/supermatter_monitor/process_tick() + ..() + var/new_status = get_status() + if(last_status != new_status) + last_status = new_status + if(last_status == SUPERMATTER_ERROR) + last_status = SUPERMATTER_INACTIVE + ui_header = "smmon_[last_status].gif" + program_icon_state = "smmon_[last_status]" + if(istype(computer)) + computer.update_icon() + +/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) + . = ..(user) + refresh() + +/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) + active = null + supermatters = null + ..() + +// Refreshes list of active supermatter crystals +/datum/computer_file/program/supermatter_monitor/proc/refresh() + supermatters = list() + var/turf/T = get_turf(nano_host()) + if(!T) + return + for(var/obj/machinery/power/supermatter_shard/S in SSair.atmos_machinery) + // Delaminating, not within coverage, not on a tile. + if(!(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T) || !istype(S.loc, /turf/simulated/))) + continue + supermatters.Add(S) + + if(!(active in supermatters)) + active = null + +/datum/computer_file/program/supermatter_monitor/proc/get_status() + . = SUPERMATTER_INACTIVE + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + . = max(., S.get_status()) + +/datum/computer_file/program/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) + assets.send(user) + ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400) + ui.set_auto_update(TRUE) + ui.set_layout_key("program") + ui.open() + +/datum/computer_file/program/supermatter_monitor/ui_data() + var/list/data = get_header_data() + + if(istype(active)) + var/turf/T = get_turf(active) + if(!T) + active = null + refresh() + return + var/datum/gas_mixture/air = T.return_air() + if(!air) + active = null + return + + data["active"] = TRUE + data["SM_integrity"] = active.get_integrity() + data["SM_power"] = active.power + data["SM_ambienttemp"] = air.temperature + data["SM_ambientpressure"] = air.return_pressure() + //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) + var/other_moles = 0.0 + for(var/datum/gas/G in air.trace_gases) + other_moles+=G.moles + var/TM = air.total_moles() + if(TM) + data["SM_gas_O2"] = round(100*air.oxygen/TM,0.01) + data["SM_gas_CO2"] = round(100*air.carbon_dioxide/TM,0.01) + data["SM_gas_N2"] = round(100*air.nitrogen/TM,0.01) + data["SM_gas_PL"] = round(100*air.toxins/TM,0.01) + if(other_moles) + data["SM_gas_OTHER"] = round(100*other_moles/TM,0.01) + else + data["SM_gas_OTHER"] = 0 + else + data["SM_gas_O2"] = 0 + data["SM_gas_CO2"] = 0 + data["SM_gas_N2"] = 0 + data["SM_gas_PH"] = 0 + data["SM_gas_OTHER"] = 0 + else + var/list/SMS = list() + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + var/area/A = get_area(S) + if(!A) + continue + + SMS.Add(list(list( + "area_name" = A.name, + "integrity" = S.get_integrity(), + "uid" = S.uid + ))) + + data["active"] = FALSE + data["supermatters"] = SMS + + return data + + +/datum/computer_file/program/supermatter_monitor/Topic(href, href_list) + if(..()) + return TRUE + if(href_list["clear"]) + active = null + return TRUE + if(href_list["refresh"]) + refresh() + return TRUE + if(href_list["set"]) + var/newuid = text2num(href_list["set"]) + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + if(S.uid == newuid) + active = S + return TRUE diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index ad7a8f5cff6..07810eb92a0 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -31,7 +31,8 @@ if(href_list["race"]) if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) - if(owner.change_species(href_list["race"])) + var/datum/species/S = GLOB.all_species[href_list["race"]] + if(owner.set_species(S.type)) cut_and_generate_data() // Species change creates new organs - runtimes ahoy if we forget this head_organ = owner.get_organ("head") @@ -44,24 +45,24 @@ if(href_list["skin_tone"]) if(can_change_skin_tone()) var/new_s_tone = null - if(owner.species.bodyflags & HAS_SKIN_TONE) + if(owner.dna.species.bodyflags & HAS_SKIN_TONE) new_s_tone = input(usr, "Choose your character's skin tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null if(isnum(new_s_tone) && can_still_topic(state)) new_s_tone = 35 - max(min(round(new_s_tone), 220),1) - else if(owner.species.bodyflags & HAS_ICON_SKIN_TONE) + else if(owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE) var/const/MAX_LINE_ENTRIES = 4 - var/prompt = "Choose your character's skin tone: 1-[owner.species.icon_skin_tones.len]\n(" - for(var/i = 1 to owner.species.icon_skin_tones.len) + var/prompt = "Choose your character's skin tone: 1-[owner.dna.species.icon_skin_tones.len]\n(" + for(var/i = 1 to owner.dna.species.icon_skin_tones.len) if(i > MAX_LINE_ENTRIES && !((i - 1) % MAX_LINE_ENTRIES)) prompt += "\n" - prompt += "[i] = [owner.species.icon_skin_tones[i]]" - if(i != owner.species.icon_skin_tones.len) + prompt += "[i] = [owner.dna.species.icon_skin_tones[i]]" + if(i != owner.dna.species.icon_skin_tones.len) prompt += ", " prompt += ")" new_s_tone = input(usr, prompt, "Skin Tone", owner.s_tone) as num|null if(isnum(new_s_tone) && can_still_topic(state)) - new_s_tone = max(min(round(new_s_tone), owner.species.icon_skin_tones.len), 1) + new_s_tone = max(min(round(new_s_tone), owner.dna.species.icon_skin_tones.len), 1) if(new_s_tone) return owner.change_skin_tone(new_s_tone) @@ -183,9 +184,9 @@ generate_data(check_whitelist, whitelist, blacklist) var/data[0] - data["specimen"] = owner.species.name + data["specimen"] = owner.dna.species.name data["gender"] = owner.gender - data["has_gender"] = owner.species.has_gender + data["has_gender"] = owner.dna.species.has_gender data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] @@ -283,25 +284,25 @@ return owner && (flags & flag) /datum/nano_module/appearance_changer/proc/can_change_skin_tone() - return owner && (flags & APPEARANCE_SKIN) && ((owner.species.bodyflags & HAS_SKIN_TONE) || (owner.species.bodyflags & HAS_ICON_SKIN_TONE)) + return owner && (flags & APPEARANCE_SKIN) && ((owner.dna.species.bodyflags & HAS_SKIN_TONE) || (owner.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) /datum/nano_module/appearance_changer/proc/can_change_skin_color() - return owner && (flags & APPEARANCE_SKIN) && (owner.species.bodyflags & HAS_SKIN_COLOR) + return owner && (flags & APPEARANCE_SKIN) && (owner.dna.species.bodyflags & HAS_SKIN_COLOR) /datum/nano_module/appearance_changer/proc/can_change_head_accessory() if(!head_organ) log_runtime(EXCEPTION("Missing head!"), owner) return 0 - return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY) + return owner && (flags & APPEARANCE_HEAD_ACCESSORY) && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY) /datum/nano_module/appearance_changer/proc/can_change_markings(var/location = "body") var/marking_flag = HAS_BODY_MARKINGS - var/body_flags = owner.species.bodyflags + var/body_flags = owner.dna.species.bodyflags if(location == "head") if(!head_organ) log_debug("Missing head!") return 0 - body_flags = head_organ.species.bodyflags + body_flags = head_organ.dna.species.bodyflags marking_flag = HAS_HEAD_MARKINGS if(location == "body") marking_flag = HAS_BODY_MARKINGS @@ -311,13 +312,13 @@ return owner && (flags & APPEARANCE_MARKINGS) && (body_flags & marking_flag) /datum/nano_module/appearance_changer/proc/can_change_body_accessory() - return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.species.bodyflags & HAS_TAIL) + return owner && (flags & APPEARANCE_BODY_ACCESSORY) && (owner.dna.species.bodyflags & HAS_TAIL) /datum/nano_module/appearance_changer/proc/can_change_alt_head() if(!head_organ) log_debug("Missing head!") return 0 - return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.species.bodyflags & HAS_ALT_HEADS) + return owner && (flags & APPEARANCE_ALT_HEAD) && (head_organ.dna.species.bodyflags & HAS_ALT_HEADS) /datum/nano_module/appearance_changer/proc/cut_and_generate_data() // Making the assumption that the available species remain constant diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index e13e48304ba..44eb3555a25 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -121,3 +121,12 @@ ..() new /obj/item/documents/syndicate/blue(src) update_icon() + +/obj/item/folder/syndicate/yellow + icon_state = "folder_syellow" + +/obj/item/folder/syndicate/yellow/full/New() + ..() + new /obj/item/documents/syndicate/yellow(src) + update_icon() + diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index e3cceb9738a..74bee9867ab 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -7,30 +7,23 @@ var/labels_left = 30 var/mode = 0 //off or on. -/obj/item/hand_labeler/afterattack(atom/A, mob/user as mob, proximity) - if(!proximity) return +/obj/item/hand_labeler/afterattack(atom/A, mob/user, proximity) + if(!proximity) + return if(!mode) //if it's off, give up. return - if(A == loc) // if placing the labeller into something (e.g. backpack) - return // don't set a label if(!labels_left) - to_chat(user, "No labels left.") + to_chat(user, "No labels left!") return if(!label || !length(label)) - to_chat(user, "No text set.") + to_chat(user, "No text set!") return if(length(A.name) + length(label) > 64) - to_chat(user, "Label too big.") + to_chat(user, "Label too big!") return - if(ishuman(A)) - to_chat(user, "You can't label humans.") - return - if(issilicon(A)) - to_chat(user, "You can't label cyborgs.") - return - if(istype(A, /obj/item/reagent_containers/glass)) - to_chat(user, "The label can't stick to the [A.name]. (Try using a pen)") + if(ismob(A)) + to_chat(user, "You can't label creatures!") // use a collar return user.visible_message("[user] labels [A] as [label].", \ diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index d37506b3d82..2fe57c5698f 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -34,6 +34,8 @@ var/contact_poison // Reagent ID to transfer on contact var/contact_poison_volume = 0 var/contact_poison_poisoner = null + var/paper_width = 400//Width of the window that opens + var/paper_height = 400//Height of the window that opens var/const/deffont = "Verdana" var/const/signfont = "Times New Roman" @@ -72,12 +74,12 @@ if((!user.say_understands(null, all_languages["Galactic Common"]) && !forceshow) || forcestars) //assuming all paper is written in common is better than hardcoded type checks data = "[name][stars(info)][stamps]" if(view) - usr << browse(data, "window=[name]") + usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") onclose(usr, "[name]") else data = "[name][infolinks ? info_links : info][stamps]" if(view) - usr << browse(data, "window=[name]") + usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") onclose(usr, "[name]") return data @@ -403,7 +405,8 @@ stamps += (!stamps || stamps == "" ? "
    " : "") + "" var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') - var/{x; y;} + var/x + var/y if(istype(S, /obj/item/stamp/captain) || istype(S, /obj/item/stamp/centcom)) x = rand(-2, 0) y = rand(-1, 2) @@ -476,6 +479,20 @@ /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" +/obj/item/paper/fortune + name = "fortune" + icon_state = "slip" + paper_height = 150 + +/obj/item/paper/fortune/New() + ..() + var/fortunemessage = pick(GLOB.fortune_cookie_messages) + info = "

    [fortunemessage]

    " + info += "

    Lucky numbers: [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)], [rand(1,49)]

    " + +/obj/item/paper/fortune/update_icon() + ..() + icon_state = initial(icon_state) /* * Premade paper */ diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 41799958c4f..ed5b7c1cfd4 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -260,7 +260,7 @@ emag_cooldown = world.time + EMAG_DELAY if(ishuman(ass)) //Suit checks are in check_ass var/mob/living/carbon/human/H = ass - temp_img = icon('icons/obj/butts.dmi', H.species.butt_sprite) + temp_img = icon('icons/obj/butts.dmi', H.dna.species.butt_sprite) else if(istype(ass,/mob/living/silicon/robot/drone)) temp_img = icon('icons/obj/butts.dmi', "drone") else if(istype(ass,/mob/living/simple_animal/diona)) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 43d418aadf7..125706bff28 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -1,21 +1,33 @@ -//Ported from /vg/station13, which was in turn forked from baystation12; -//Please do not bother them with bugs from this port, however, as it has been modified quite a bit. -//Modifications include removing the world-ending full supermatter variation, and leaving only the shard. +#define NITROGEN_RETARDATION_FACTOR 0.15 //Higher == N2 slows reaction more +#define THERMAL_RELEASE_MODIFIER 10000 //Higher == more heat released during reaction +#define PLASMA_RELEASE_MODIFIER 1500 //Higher == less phor.. plasma released by reaction +#define OXYGEN_RELEASE_MODIFIER 15000 //Higher == less oxygen released at high temperature/power +#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power -#define NITROGEN_RETARDATION_FACTOR 2 //Higher == N2 slows reaction more -#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction -#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction -#define OXYGEN_RELEASE_MODIFIER 325 //Higher == less oxygen released at high temperature/power -#define REACTION_POWER_MODIFIER 0.55 //Higher == more overall power +/* + How to tweak the SM + POWER_FACTOR directly controls how much power the SM puts out at a given level of excitation (power var). Making this lower means you have to work the SM harder to get the same amount of power. + CRITICAL_TEMPERATURE The temperature at which the SM starts taking damage. + CHARGING_FACTOR Controls how much emitter shots excite the SM. + DAMAGE_RATE_LIMIT Controls the maximum rate at which the SM will take damage due to high temperatures. +*/ + +//Controls how much power is produced by each collector in range - this is the main parameter for tweaking SM balance, as it basically controls how the power variable relates to the rest of the game. +#define POWER_FACTOR 1.0 +#define DECAY_FACTOR 700 //Affects how fast the supermatter power decays +#define CRITICAL_TEMPERATURE 10000 //K +#define CHARGING_FACTOR 0.05 +#define DAMAGE_RATE_LIMIT 4.5 //damage rate cap at power = 300, scales linearly with power -//These would be what you would get at point blank, decreases with distance +// Base variants are applied to everyone on the same Z level +// Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels) #define DETONATION_RADS 200 #define DETONATION_HALLUCINATION 600 -#define WARNING_DELAY 30 //seconds between warnings. +#define WARNING_DELAY 20 //seconds between warnings. /obj/machinery/power/supermatter_shard name = "supermatter shard" desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. You get headaches just from looking at it." @@ -35,15 +47,16 @@ var/safe_alert = "Crystalline hyperstructure returning to safe operating levels." var/warning_point = 50 var/warning_alert = "Danger! Crystal hyperstructure instability!" - var/emergency_point = 500 + var/emergency_point = 400 var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." - var/explosion_point = 900 + var/explosion_point = 600 var/emergency_issued = 0 var/explosion_power = 8 var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + var/last_zap = 0 // Time in 1/10th of seconds since the last tesla zap var/power = 0 var/oxygen = 0 // Moving this up here for easier debugging. @@ -51,38 +64,90 @@ //Temporary values so that we can optimize this //How much the bullets damage should be multiplied by when it is added to the internal variables var/config_bullet_energy = 2 - //How much of the power is left after processing is finished? -// var/config_power_reduction_per_tick = 0.5 //How much hallucination should it produce per unit of power? var/config_hallucination_power = 0.1 + var/debug = 0 + + var/disable_adminwarn = FALSE + + var/aw_normal = FALSE + var/aw_notify = FALSE + var/aw_warning = FALSE + var/aw_danger = FALSE + var/aw_emerg = FALSE + var/aw_delam = FALSE + var/obj/item/radio/radio //for logging var/has_been_powered = 0 var/has_reached_emergency = 0 +/obj/machinery/power/supermatter_shard/crystal + name = "supermatter crystal" + desc = "A strangely translucent and iridescent crystal." + base_icon_state = "darkmatter" + icon_state = "darkmatter" + anchored = TRUE + warning_point = 200 + emergency_point = 2000 + explosion_point = 3600 + gasefficency = 0.25 + explosion_power = 24 + + /obj/machinery/power/supermatter_shard/New() . = ..() poi_list |= src + //Added to the atmos_machine process as the SM is highly coupled with the atmospherics system. + //Having the SM run at a different rate then atmospherics causes odd behavior. + SSair.atmos_machinery += src radio = new(src) radio.listening = 0 investigate_log("has been created.", "supermatter") +/obj/machinery/power/supermatter_shard/proc/handle_admin_warnings() + if(disable_adminwarn) + return + + // Generic checks, similar to checks done by supermatter monitor program. + aw_normal = status_adminwarn_check(SUPERMATTER_NORMAL, aw_normal, "INFO: Supermatter crystal has been energised.(JMP).", FALSE) + aw_notify = status_adminwarn_check(SUPERMATTER_NOTIFY, aw_notify, "INFO: Supermatter crystal is approaching unsafe operating temperature.(JMP).", FALSE) + aw_warning = status_adminwarn_check(SUPERMATTER_WARNING, aw_warning, "WARN: Supermatter crystal is taking integrity damage!(JMP).", FALSE) + aw_danger = status_adminwarn_check(SUPERMATTER_DANGER, aw_danger, "WARN: Supermatter integrity is below 75%!(JMP).", TRUE) + aw_emerg = status_adminwarn_check(SUPERMATTER_EMERGENCY, aw_emerg, "CRIT: Supermatter integrity is below 50%!(JMP).", FALSE) + aw_delam = status_adminwarn_check(SUPERMATTER_DELAMINATING, aw_delam, "CRIT: Supermatter is delaminating!(JMP).", TRUE) + +/obj/machinery/power/supermatter_shard/proc/status_adminwarn_check(var/min_status, var/current_state, var/message, var/send_to_irc = FALSE) + var/status = get_status() + if(status >= min_status) + if(!current_state) + log_and_message_admins(message) + if(send_to_irc) + send2adminirc(message) + return TRUE + else + return FALSE + + /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") + if(damage > emergency_point) + emergency_lighting(0) QDEL_NULL(radio) poi_list.Remove(src) + SSair.atmos_machinery -= src return ..() /obj/machinery/power/supermatter_shard/proc/explode() investigate_log("has exploded.", "supermatter") - explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) + explosion(get_turf(src), explosion_power, explosion_power * 1.2, explosion_power * 1.5, explosion_power * 2, 1, 1) qdel(src) return -/obj/machinery/power/supermatter_shard/process() +/obj/machinery/power/supermatter_shard/process_atmos() var/turf/L = loc if(isnull(L)) // We have a null turf...something is wrong, stop processing this entity. @@ -91,11 +156,10 @@ if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. return //Yeah just stop. - if(istype(L, /turf/space)) // Stop processing this stuff if we've been ejected. - return - if(damage > warning_point) // while the core is still damaged and it's still worth noting its status if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY) + alarm() + emergency_lighting(1) var/stability = num2text(round((damage / explosion_point) * 100)) if(damage > emergency_point) @@ -112,6 +176,7 @@ else // Phew, we're safe radio.autosay("[safe_alert]", src.name) + emergency_lighting(0) lastwarning = world.timeofday if(damage > explosion_point) @@ -128,6 +193,11 @@ mob.apply_effect(rads, IRRADIATE) explode() + emergency_lighting(0) + + if(damage > warning_point && world.timeofday > last_zap) + last_zap = world.timeofday + rand(80,200) + supermatter_zap() //Ok, get the air from the turf var/datum/gas_mixture/env = L.return_air() @@ -135,52 +205,57 @@ //Remove gas from surrounding area var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles()) - if(!removed || !removed.total_moles()) - damage += max((power-1600)/10, 0) - power = min(power, 1600) - return 1 + //ensure that damage doesn't increase too quickly due to super high temperatures resulting from no coolant, for example. We dont want the SM exploding before anyone can react. + //We want the cap to scale linearly with power (and explosion_point). Let's aim for a cap of 5 at power = 300 (based on testing, equals roughly 5% per SM alert announcement). + var/damage_inc_limit = (power/300)*(explosion_point/1000)*DAMAGE_RATE_LIMIT + + if(!env || !removed || !removed.total_moles()) + damage += max((power - 15*POWER_FACTOR)/10, 0) + else + damage_archived = damage + + damage = max(0, damage + between(-DAMAGE_RATE_LIMIT, (removed.temperature - CRITICAL_TEMPERATURE) / 150, damage_inc_limit)) - damage_archived = damage - damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) - //Ok, 100% oxygen atmosphere = best reaction //Maxes out at 100% oxygen pressure - oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) - - var/temp_factor = 50 + oxygen = Clamp((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / removed.total_moles(), 0, 1) + var/temp_factor + var/equilibrium_power if(oxygen > 0.8) - // with a perfect gas mix, make the power less based on heat + //If chain reacting at oxygen > 0.8, we want the power at 800 K to stabilize at a power level of 400 + equilibrium_power = 400 icon_state = "[base_icon_state]_glow" else - // in normal mode, base the produced energy around the heat - temp_factor = 30 + //Otherwise, we want the power at 800 K to stabilize at a power level of 250 + equilibrium_power = 250 icon_state = base_icon_state - power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload - - //We've generated power, now let's transfer it to the collectors for storing/usage - transfer_energy() + temp_factor = ((equilibrium_power / DECAY_FACTOR) ** 3) / 800 + power = max((removed.temperature * temp_factor) * oxygen + power, 0) var/device_energy = power * REACTION_POWER_MODIFIER - //To figure out how much temperature to add each tick, consider that at one atmosphere's worth - //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature - //that the device energy is around 2140. At that stage, we don't want too much heat to be put out - //Since the core is effectively "cold" + var/heat_capacity = removed.heat_capacity() - //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock - //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. - removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER) - - removed.temperature = max(0, min(removed.temperature, 2500)) - - //Calculate how much gas to release removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + var/thermal_power = THERMAL_RELEASE_MODIFIER * device_energy + if(debug) + var/heat_capacity_new = removed.heat_capacity() + visible_message("[src]: Releasing [round(thermal_power)] W.") + visible_message("[src]: Releasing additional [round((heat_capacity_new - heat_capacity)*removed.temperature)] W with exhaust gasses.") + + removed.temperature += (device_energy) + + removed.temperature = max(0, min(removed.temperature, 10000)) + env.merge(removed) + air_update_turf() + transfer_energy() + for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them. if(l.glasses && istype(l.glasses, /obj/item/clothing/glasses/meson)) @@ -196,7 +271,8 @@ var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) l.apply_effect(rads, IRRADIATE) - power -= (power/500)**3 + power -= (power/DECAY_FACTOR)**3 + handle_admin_warnings() return 1 @@ -217,12 +293,13 @@ has_been_powered = 1 else damage += Proj.damage * config_bullet_energy + supermatter_zap() return 0 /obj/machinery/power/supermatter_shard/singularity_act() var/gain = 100 investigate_log("Supermatter shard consumed by singularity.","singulo") - message_admins("Singularity has consumed a supermatter shard and can now become stage six.") + message_admins("Singularity has consumed a supermatter shard and can now become stage six.(JMP).") visible_message("[src] is consumed by the singularity!") for(var/mob/M in mob_list) M << 'sound/effects/supermatter.ogg' //everyone gunna know bout this @@ -306,7 +383,6 @@ user.apply_effect(150, IRRADIATE) - /obj/machinery/power/supermatter_shard/Bumped(atom/AM as mob|obj) if(istype(AM, /mob/living)) AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their(TRUE)] body starts to glow and catch flame before flashing into ash.",\ @@ -335,6 +411,8 @@ qdel(AM) power += 200 + supermatter_zap() + //Some poor sod got eaten, go ahead and irradiate people nearby. for(var/mob/living/L in range(10)) @@ -346,3 +424,51 @@ "The unearthly ringing subsides and you notice you have new radiation burns.", 2) else L.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) + +/obj/machinery/power/supermatter_shard/proc/get_status() + var/turf/T = get_turf(src) + if(!T) + return SUPERMATTER_ERROR + var/datum/gas_mixture/air = T.return_air() + if(!air) + return SUPERMATTER_ERROR + + if(get_integrity() < 25) + return SUPERMATTER_DELAMINATING + + if(get_integrity() < 50) + return SUPERMATTER_EMERGENCY + + if(get_integrity() < 75) + return SUPERMATTER_DANGER + + if((get_integrity() < 100) || (air.temperature > CRITICAL_TEMPERATURE)) + return SUPERMATTER_WARNING + + if(air.temperature > (CRITICAL_TEMPERATURE * 0.8)) + return SUPERMATTER_NOTIFY + + if(power > 5) + return SUPERMATTER_NORMAL + return SUPERMATTER_INACTIVE + +/obj/machinery/power/supermatter_shard/proc/alarm() + switch(get_status()) + if(SUPERMATTER_DELAMINATING) + playsound(src, 'sound/misc/bloblarm.ogg', 100) + if(SUPERMATTER_EMERGENCY) + playsound(src, 'sound/machines/engine_alert1.ogg', 100) + if(SUPERMATTER_DANGER) + playsound(src, 'sound/machines/engine_alert2.ogg', 100) + if(SUPERMATTER_WARNING) + playsound(src, 'sound/machines/terminal_alert.ogg', 75) + +/obj/machinery/power/supermatter_shard/proc/emergency_lighting(active) + if(active) + post_status("alert", "radiation") + else + post_status("shuttle") + +/obj/machinery/power/supermatter_shard/proc/supermatter_zap() + playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5) + tesla_zap(src, 10, max(1000,power * damage / explosion_point)) diff --git a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm index 11873b5acdf..3e43c5638d1 100644 --- a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm +++ b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm @@ -38,4 +38,4 @@ if(get_step(T,direction) in mother.map) continue return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index a7baacb9583..24b77ee9bb5 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -119,6 +119,9 @@ ammo_type = /obj/item/ammo_casing/shotgun/rubbershot max_ammo = 6 +/obj/item/ammo_box/magazine/internal/shot/riot/short + max_ammo = 3 + /obj/item/ammo_box/magazine/internal/grenadelauncher name = "grenade launcher internal magazine" ammo_type = /obj/item/ammo_casing/a40mm diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 51bf515ca1e..165e75f1875 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -153,10 +153,10 @@ process_fire(target,user,1,params) -/obj/item/gun/proc/can_trigger_gun(var/mob/living/user) +/obj/item/gun/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) return 0 - if(restricted_species && restricted_species.len && !(user.get_species() in restricted_species)) + if(restricted_species && restricted_species.len && !is_type_in_list(user.dna.species, restricted_species)) to_chat(user, "[src] is incompatible with your biology!") return 0 return 1 diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index 7093d587b3c..95e1a586469 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -11,7 +11,7 @@ can_suppress = 0 var/charge_tick = 0 var/charge_delay = 15 - restricted_species = list("Vox", "Vox Armalis") + restricted_species = list(/datum/species/vox) /obj/item/gun/projectile/automatic/spikethrower/New() ..() @@ -79,7 +79,7 @@ force = 10 ammo_type = list(/obj/item/ammo_casing/energy/sonic) cell_type = /obj/item/stock_parts/cell/super - restricted_species = list("Vox Armalis") + restricted_species = list(/datum/species/vox/armalis) /obj/item/gun/energy/noisecannon/update_icon() return diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index e2067467ddb..7169b3d1443 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -28,7 +28,7 @@ /obj/item/gun/energy/gun/mini name = "miniature energy gun" - desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: stun and kill." + desc = "A small, pistol-sized energy gun with a built-in flashlight. It has two settings: disable and kill." icon_state = "mini" w_class = WEIGHT_CLASS_SMALL ammo_x_offset = 2 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 7559fc1a591..ccb28890786 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -196,9 +196,9 @@ /obj/item/gun/energy/wormhole_projector/process_chamber() ..() - select_fire() + select_fire(usr) -/obj/item/gun/energy/wormhole_projector/proc/portal_destroyed(obj/effect/portal/P) +/obj/item/gun/energy/wormhole_projector/portal_destroyed(obj/effect/portal/P) if(P.icon_state == "portal") blue = null if(orange) diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index c0678323409..55aa5977eb2 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -81,6 +81,7 @@ icon_state = "riotshotgun" mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." + sawn_state = SAWN_INTACT /obj/item/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() @@ -90,6 +91,109 @@ var/obj/item/melee/energy/W = A if(W.active) sawoff(user) + if(istype(A, /obj/item/pipe)) + unsaw(A, user) + +/obj/item/gun/projectile/shotgun/riot/sawoff(mob/user) + if(sawn_state == SAWN_OFF) + to_chat(user, "[src] has already been shortened!") + return + if(istype(loc, /obj/item/storage)) //To prevent inventory exploits + to_chat(user, "How do you plan to modify [src] while it's in a bag.") + return + if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click' + if(chambered.BB) + afterattack(user, user) + user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") + return + else + afterattack(user, user) + user.visible_message("The [src] goes click!", "The [src] you are holding goes click.") + if(magazine.ammo_count()) //Spill the mag onto the floor + user.visible_message("[user.name] opens [src] up and the shells go goes flying around!", "You open [src] up and the shells go goes flying everywhere!!") + while(get_ammo(0) > 0) + var/obj/item/ammo_casing/CB + CB = magazine.get_round(0) + if(CB) + CB.loc = get_turf(loc) + CB.update_icon() + + if(do_after(user, 30, target = src)) + user.visible_message("[user] shortens \the [src]!", "You shorten \the [src].") + post_sawoff() + return 1 + + +/obj/item/gun/projectile/shotgun/riot/proc/post_sawoff() + name = "assault shotgun" + desc = sawn_desc + w_class = WEIGHT_CLASS_NORMAL + current_skin = "riotshotgun-short" + item_state = "gun" //phil235 is it different with different skin? + slot_flags &= ~SLOT_BACK //you can't sling it on your back + slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) + sawn_state = SAWN_OFF + magazine.max_ammo = 3 + update_icon() + + +/obj/item/gun/projectile/shotgun/riot/proc/unsaw(obj/item/A, mob/user) + if(sawn_state == SAWN_INTACT) + to_chat(user, "[src] has not been shortened!") + return + if(istype(loc, /obj/item/storage)) //To prevent inventory exploits + to_chat(user, "How do you plan to modify [src] while it's in a bag.") + return + if(chambered) //if the gun is chambering live ammo, shoot self, if chambering empty ammo, 'click' + if(chambered.BB) + afterattack(user, user) + user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") + return + else + afterattack(user, user) + user.visible_message("The [src] goes click!", "The [src] you are holding goes click.") + if(magazine.ammo_count()) //Spill the mag onto the floor + user.visible_message("[user.name] opens [src] up and the shells go goes flying around!", "You open [src] up and the shells go goes flying everywhere!!") + while(get_ammo() > 0) + var/obj/item/ammo_casing/CB + CB = magazine.get_round(0) + if(CB) + CB.loc = get_turf(loc) + CB.update_icon() + + if(do_after(user, 30, target = src)) + qdel(A) + user.visible_message("[user] lengthens [src]!", "You lengthen [src].") + post_unsaw(user) + return 1 + +/obj/item/gun/projectile/shotgun/riot/proc/post_unsaw() + name = initial(name) + desc = initial(desc) + w_class = initial(w_class) + current_skin = "riotshotgun" + item_state = initial(item_state) + slot_flags &= ~SLOT_BELT + slot_flags |= SLOT_BACK + sawn_state = SAWN_INTACT + magazine.max_ammo = 6 + update_icon() + +/obj/item/gun/projectile/shotgun/riot/update_icon() //Can't use the old proc as it makes it go to riotshotgun-short_sawn + ..() + if(current_skin) + icon_state = "[current_skin]" + else + icon_state = "[initial(icon_state)]" + +/obj/item/gun/projectile/shotgun/riot/short + mag_type = /obj/item/ammo_box/magazine/internal/shot/riot/short + +/obj/item/gun/projectile/shotgun/riot/short/New() + ..() + post_sawoff() + + /////////////////////// // BOLT ACTION RIFLE // diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e38a42ff88f..e19cd1165b5 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -83,7 +83,7 @@ var/blood_color = "#C80000" if(ishuman(target)) H = target - blood_color = H.species.blood_color + blood_color = H.dna.species.blood_color new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, blood_color) if(prob(33)) var/list/shift = list("x" = 0, "y" = 0) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 3fe2277ed3b..854fd1edbaf 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -24,15 +24,15 @@ var/exp_flash = 3 var/exp_fire = 2 -/obj/item/projectile/magic/death/on_hit(var/mob/living/carbon/G) +/obj/item/projectile/magic/death/on_hit(mob/living/carbon/C) . = ..() - if(isliving(G)) - if(G.get_species() == "Machine") //speshul snowfleks deserv speshul treetment - G.adjustFireLoss(6969) //remember - slimes love fire + if(isliving(C)) + if(ismachine(C)) //speshul snowfleks deserv speshul treetment + C.adjustFireLoss(6969) //remember - slimes love fire else - G.death() + C.death() - visible_message("[G] topples backwards as the death bolt impacts [G.p_them()]!") + visible_message("[C] topples backwards as the death bolt impacts [C.p_them()]!") /obj/item/projectile/magic/fireball/Range() var/turf/T1 = get_step(src,turn(dir, -45)) @@ -146,117 +146,120 @@ . = ..() wabbajack(change) -proc/wabbajack(mob/living/M) - if(istype(M)) - if(istype(M, /mob/living) && M.stat != DEAD) - if(M.notransform) - return - M.notransform = 1 - M.canmove = 0 - M.icon = null - M.overlays.Cut() - M.invisibility = 101 +/proc/wabbajack(mob/living/M) + if(istype(M) && M.stat != DEAD && !M.notransform) + M.notransform = TRUE + M.canmove = FALSE + M.icon = null + M.overlays.Cut() + M.invisibility = 101 - if(istype(M, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) - qdel(Robot.mmi) - Robot.notify_ai(1) - else - if(ishuman(M)) - var/mob/living/carbon/human/H = M - // Make sure there are no organs or limbs to drop - for(var/t in H.bodyparts) - qdel(t) - for(var/i in H.internal_organs) - qdel(i) - for(var/obj/item/W in M) - M.unEquip(W, 1) - qdel(W) + if(isrobot(M)) + var/mob/living/silicon/robot/Robot = M + QDEL_NULL(Robot.mmi) + Robot.notify_ai(1) + else + if(ishuman(M)) + var/mob/living/carbon/human/H = M + // Make sure there are no organs or limbs to drop + for(var/t in H.bodyparts) + qdel(t) + for(var/i in H.internal_organs) + qdel(i) + for(var/obj/item/W in M) + M.unEquip(W, 1) + qdel(W) - var/mob/living/new_mob + var/mob/living/new_mob - var/randomize = pick("robot","slime","xeno","human","animal") - switch(randomize) - if("robot") - if(prob(30)) - new_mob = new /mob/living/silicon/robot/syndicate(M.loc) - else - new_mob = new /mob/living/silicon/robot(M.loc) - new_mob.gender = M.gender - new_mob.invisibility = 0 - new_mob.job = "Cyborg" - var/mob/living/silicon/robot/Robot = new_mob - Robot.mmi = new /obj/item/mmi(new_mob) - if(ishuman(M)) - Robot.mmi.transfer_identity(M) //Does not transfer key/client. - if("slime") - new_mob = new /mob/living/carbon/slime/random(M.loc) - new_mob.universal_speak = 1 - if("xeno") - if(prob(50)) - new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc) - else - new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) - new_mob.universal_speak = 1 - if("animal") - if(prob(50)) - var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato") - switch(beast) - if("carp") new_mob = new /mob/living/simple_animal/hostile/carp(M.loc) - if("bear") new_mob = new /mob/living/simple_animal/hostile/bear(M.loc) - if("mushroom") new_mob = new /mob/living/simple_animal/hostile/mushroom(M.loc) - if("statue") new_mob = new /mob/living/simple_animal/hostile/statue(M.loc) - if("bat") new_mob = new /mob/living/simple_animal/hostile/scarybat(M.loc) - if("goat") new_mob = new /mob/living/simple_animal/hostile/retaliate/goat(M.loc) - if("tomato") new_mob = new /mob/living/simple_animal/hostile/killertomato(M.loc) - else - var/animal = pick("parrot","corgi","crab","pug","cat","mouse","chicken","cow","lizard","chick","fox") - switch(animal) - if("parrot") new_mob = new /mob/living/simple_animal/parrot(M.loc) - if("corgi") new_mob = new /mob/living/simple_animal/pet/corgi(M.loc) - if("crab") new_mob = new /mob/living/simple_animal/crab(M.loc) - if("cat") new_mob = new /mob/living/simple_animal/pet/cat(M.loc) - if("mouse") new_mob = new /mob/living/simple_animal/mouse(M.loc) - if("chicken") new_mob = new /mob/living/simple_animal/chicken(M.loc) - if("cow") new_mob = new /mob/living/simple_animal/cow(M.loc) - if("lizard") new_mob = new /mob/living/simple_animal/lizard(M.loc) - if("fox") new_mob = new /mob/living/simple_animal/pet/fox(M.loc) - else new_mob = new /mob/living/simple_animal/chick(M.loc) - new_mob.universal_speak = 1 - if("human") - new_mob = new /mob/living/carbon/human/human(M.loc) - // Include standard, whitelisted, and monkey species... - var/list/new_species = list("Human","Tajaran","Skrell","Unathi","Diona","Vulpkanin") - new_species |= whitelisted_species - for(var/SN in all_species) - var/datum/species/S = all_species[SN] - if(S.greater_form) // Monkeys - new_species |= SN - new_species -= "Vox Armalis" // ... but not Armalis. They're not really designed to be playable - new_species |= "Golem" // Also, golems, sure, why not - var/picked_species = pick(new_species) - var/mob/living/carbon/human/H = new_mob - H.set_species(picked_species) - randomize = picked_species - var/datum/preferences/A = new() //Randomize appearance for the human - A.copy_to(new_mob) + var/randomize = pick("robot", "slime", "xeno", "human", "animal") + switch(randomize) + if("robot") + if(prob(30)) + new_mob = new /mob/living/silicon/robot/syndicate(M.loc) else - return - - M.create_attack_log("[key_name(M)] became [new_mob.real_name].") - new_mob.attack_log = M.attack_log - - new_mob.a_intent = INTENT_HARM - if(M.mind) - M.mind.transfer_to(new_mob) + new_mob = new /mob/living/silicon/robot(M.loc) + new_mob.gender = M.gender + new_mob.invisibility = 0 + new_mob.job = "Cyborg" + var/mob/living/silicon/robot/Robot = new_mob + Robot.mmi = new /obj/item/mmi(new_mob) + if(ishuman(M)) + Robot.mmi.transfer_identity(M) //Does not transfer key/client. + if("slime") + new_mob = new /mob/living/carbon/slime/random(M.loc) + new_mob.universal_speak = TRUE + if("xeno") + if(prob(50)) + new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc) + else + new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) + new_mob.universal_speak = TRUE + if("animal") + if(prob(50)) + var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato") + switch(beast) + if("carp") + new_mob = new /mob/living/simple_animal/hostile/carp(M.loc) + if("bear") + new_mob = new /mob/living/simple_animal/hostile/bear(M.loc) + if("mushroom") + new_mob = new /mob/living/simple_animal/hostile/mushroom(M.loc) + if("statue") + new_mob = new /mob/living/simple_animal/hostile/statue(M.loc) + if("bat") + new_mob = new /mob/living/simple_animal/hostile/scarybat(M.loc) + if("goat") + new_mob = new /mob/living/simple_animal/hostile/retaliate/goat(M.loc) + if("tomato") + new_mob = new /mob/living/simple_animal/hostile/killertomato(M.loc) + else + var/animal = pick("parrot", "corgi", "crab", "pug", "cat", "mouse", "chicken", "cow", "lizard", "chick", "fox") + switch(animal) + if("parrot") + new_mob = new /mob/living/simple_animal/parrot(M.loc) + if("corgi") + new_mob = new /mob/living/simple_animal/pet/corgi(M.loc) + if("crab") + new_mob = new /mob/living/simple_animal/crab(M.loc) + if("cat") + new_mob = new /mob/living/simple_animal/pet/cat(M.loc) + if("mouse") + new_mob = new /mob/living/simple_animal/mouse(M.loc) + if("chicken") + new_mob = new /mob/living/simple_animal/chicken(M.loc) + if("cow") + new_mob = new /mob/living/simple_animal/cow(M.loc) + if("lizard") + new_mob = new /mob/living/simple_animal/lizard(M.loc) + if("fox") + new_mob = new /mob/living/simple_animal/pet/fox(M.loc) + else + new_mob = new /mob/living/simple_animal/chick(M.loc) + new_mob.universal_speak = TRUE + if("human") + new_mob = new /mob/living/carbon/human(M.loc) + var/mob/living/carbon/human/H = new_mob + var/datum/preferences/A = new() //Randomize appearance for the human + A.species = get_random_species(TRUE) + A.copy_to(new_mob) + randomize = H.dna.species.name else - new_mob.key = M.key + return - to_chat(new_mob, "Your form morphs into that of a [randomize].") + M.create_attack_log("[key_name(M)] became [new_mob.real_name].") + new_mob.attack_log = M.attack_log - qdel(M) - return new_mob + new_mob.a_intent = INTENT_HARM + if(M.mind) + M.mind.transfer_to(new_mob) + else + new_mob.key = M.key + + to_chat(new_mob, "Your form morphs into that of a [randomize].") + + qdel(M) + return new_mob /obj/item/projectile/magic/animate name = "bolt of animation" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 2c774b7f3dd..2003e78b780 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -133,7 +133,7 @@ var/mob/living/M = target if(ishuman(target)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) + if(IS_PLANT in H.dna.species.species_traits) if(prob(15)) M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) @@ -166,7 +166,7 @@ var/mob/M = target if(ishuman(target)) //These rays make plantmen fat. var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) + if(IS_PLANT in H.dna.species.species_traits) H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL) else if(iscarbon(target)) M.show_message("The radiation beam dissipates harmlessly through your body.") diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 83a000fa693..73a591f9ddb 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -209,17 +209,17 @@ var/const/INGEST = 2 //Check if this mob's species is set and can process this type of reagent var/can_process = 0 //If we somehow avoided getting a species or reagent_tag set, we'll assume we aren't meant to process ANY reagents (CODERS: SET YOUR SPECIES AND TAG!) - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN + if(H.dna.species && H.dna.species.reagent_tag) + if((R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG + if((R.process_flags & ORGANIC) && (H.dna.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG can_process = 1 //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) + if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) can_process = 1 //If handle_reagents returns 0, it's doing the reagent removal on its own - var/species_handled = !(H.species.handle_reagents(H, R)) + var/species_handled = !(H.dna.species.handle_reagents(H, R)) can_process = can_process && !species_handled //If the mob can't process it, remove the reagent at it's normal rate without doing any addictions, overdoses, or on_mob_life() for the reagent if(can_process == 0) @@ -481,13 +481,13 @@ var/const/INGEST = 2 if(ishuman(M)) var/mob/living/carbon/human/H = M //Check if this mob's species is set and can process this type of reagent - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN + if(H.dna.species && H.dna.species.reagent_tag) + if((R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG + if((R.process_flags & ORGANIC) && (H.dna.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG can_process = 1 //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) + if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) can_process = 1 //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption) else diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index bdabfd21956..7426844e292 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -31,7 +31,7 @@ if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients if(prob(50)) M.adjustBruteLoss(-1) - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.4 ..() @@ -66,7 +66,7 @@ M.satiety += 30 if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.5 ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm index c9f89743e7c..f603d5eb0d1 100644 --- a/code/modules/reagents/chemistry/reagents/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -221,7 +221,7 @@ M.adjustFireLoss(-2*REAGENTS_EFFECT_MULTIPLIER) if(ishuman(M) && prob(33)) var/mob/living/carbon/human/H = M - if(!(NO_BLOOD in H.species.species_traits))//do not restore blood on things with no blood by nature. + if(!(NO_BLOOD in H.dna.species.species_traits))//do not restore blood on things with no blood by nature. if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 1 ..() diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm index a67fcd0f751..fdddea44bd2 100644 --- a/code/modules/reagents/chemistry/reagents/misc.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -155,7 +155,7 @@ /datum/reagent/iron/on_mob_life(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(!H.species.exotic_blood && !(NO_BLOOD in H.species.species_traits)) + if(!H.dna.species.exotic_blood && !(NO_BLOOD in H.dna.species.species_traits)) if(H.blood_volume < BLOOD_VOLUME_NORMAL) H.blood_volume += 0.8 ..() @@ -313,8 +313,8 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/head/head_organ = H.get_organ("head") - head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) H.update_hair() H.update_fhair() ..() @@ -335,14 +335,14 @@ var/datum/sprite_accessory/tmp_hair_style = hair_styles_full_list["Very Long Hair"] var/datum/sprite_accessory/tmp_facial_hair_style = facial_hair_styles_list["Very Long Beard"] - if(head_organ.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + if(head_organ.dna.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. head_organ.h_style = "Very Long Hair" else //Otherwise, give them a random hair style. - head_organ.h_style = random_hair_style(H.gender, head_organ.species.name) - if(head_organ.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + if(head_organ.dna.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. head_organ.f_style = "Very Long Beard" else //Otherwise, give them a random facial hair style. - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm index b54444ee2d4..f2a5e8b9e24 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -221,7 +221,7 @@ /datum/reagent/pyrosium name = "Pyrosium" id = "pyrosium" - description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K." + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents." color = "#B20000" // rgb: 139, 166, 233 process_flags = ORGANIC | SYNTHETIC diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 7bff61218c6..a3fc113339e 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -61,12 +61,12 @@ /datum/reagent/slimetoxin/on_mob_life(mob/living/M) if(ishuman(M)) var/mob/living/carbon/human/human = M - if(human.species.name != "Shadow") + if(!isshadowperson(human)) to_chat(M, "Your flesh rapidly mutates!") to_chat(M, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") to_chat(M, "Your body reacts violently to light. However, it naturally heals in darkness.") to_chat(M, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") + human.set_species(/datum/species/shadow) ..() /datum/reagent/aslimetoxin @@ -217,7 +217,7 @@ if(method == TOUCH) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Grey") + if(isgrey(H)) return if(volume > 25) @@ -246,7 +246,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Grey") + if(isgrey(H)) return if(volume >=10 && volume <=25) @@ -961,7 +961,7 @@ C.adjustToxLoss(lethality) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(IS_PLANT in H.species.species_traits) //plantmen take a LOT of damage + if(IS_PLANT in H.dna.species.species_traits) //plantmen take a LOT of damage H.adjustToxLoss(50) ..() else if(istype(M, /mob/living/simple_animal/diona)) //plantmen monkeys (diona) take EVEN MORE damage @@ -995,7 +995,7 @@ C.adjustToxLoss(2) if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() == "Kidan") //RIP + if(iskidan(H)) //RIP H.adjustToxLoss(20) /datum/reagent/capulettium diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index cd338cb048d..199edb72fb4 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -29,7 +29,7 @@ var/mob/living/carbon/human/H = M - if(H.get_species() != "Grey") //God this is so gross I hate it. + if(!isgrey(H)) //God this is so gross I hate it. return if(volume > 25) @@ -58,7 +58,7 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M - if(H.get_species() != "Grey") + if(!isgrey(H)) return if(volume < 10) diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index c7acc705150..a5d37cb8b60 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -26,6 +26,33 @@ empulse(location, round(created_volume / 24), round(created_volume / 14), 1) holder.clear_reagents() +/datum/chemical_reaction/beesplosion + name = "Bee Explosion" + id = "beesplosion" + result = null + required_reagents = list("honey" = 1, "strange_reagent" = 1, "radium" = 1) + result_amount = 1 + +/datum/chemical_reaction/beesplosion/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + if(created_volume < 5) + playsound(location,'sound/effects/sparks1.ogg', 100, 1) + else + playsound(location,'sound/creatures/bee.ogg', 100, 1) + var/list/beeagents = list() + for(var/X in holder.reagent_list) + var/datum/reagent/R = X + if(R.id in required_reagents) + continue + if(!R.can_synth) + continue + beeagents += R + var/bee_amount = round(created_volume * 0.2) + for(var/i in 1 to bee_amount) + var/mob/living/simple_animal/hostile/poison/bees/new_bee = new(location) + if(LAZYLEN(beeagents)) + new_bee.assign_reagent(pick(beeagents)) + /datum/chemical_reaction/nitroglycerin name = "Nitroglycerin" id = "nitroglycerin" diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index feee1bab8b4..771d627b421 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -13,7 +13,9 @@ possible_transfer_amounts = list(1,2,3,4,5,10,15,20,25,30) flags = OPENCONTAINER slot_flags = SLOT_BELT - var/ignore_flags = 0 + var/ignore_flags = FALSE + var/emagged = FALSE + var/safety_hypo = FALSE /obj/item/reagent_containers/hypospray/attack(mob/living/M, mob/user) if(!reagents.total_volume) @@ -31,8 +33,13 @@ for(var/datum/reagent/R in reagents.reagent_list) injected += R.name + var/primary_reagent_name = reagents.get_master_reagent_name() var/trans = reagents.trans_to(M, amount_per_transfer_from_this) + if(safety_hypo) + visible_message("[user] injects [M] with [trans] units of [primary_reagent_name].") + playsound(loc, 'sound/goonstation/items/hypo.ogg', 80, 0) + to_chat(user, "[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src].") var/contained = english_list(injected) @@ -41,6 +48,31 @@ return TRUE +/obj/item/reagent_containers/hypospray/on_reagent_change() + if(safety_hypo && !emagged) + var/found_forbidden_reagent = FALSE + for(var/datum/reagent/R in reagents.reagent_list) + if(!safe_chem_list.Find(R.id)) + reagents.del_reagent(R.id) + found_forbidden_reagent = TRUE + if(found_forbidden_reagent) + if(ismob(loc)) + to_chat(loc, "[src] identifies and removes a harmful substance.") + else + visible_message("[src] identifies and removes a harmful substance.") + +/obj/item/reagent_containers/hypospray/emag_act(mob/user) + if(safety_hypo && !emagged) + emagged = TRUE + ignore_flags = TRUE + to_chat(user, "You short out the safeties on [src].") + +/obj/item/reagent_containers/hypospray/safety + name = "medical hypospray" + desc = "A modified hypospray for quickly injecting safe medicinal chemicals." + icon_state = "combat_hypo" + safety_hypo = TRUE + /obj/item/reagent_containers/hypospray/CMO list_reagents = list("omnizine" = 30) diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 3658846a696..c7e276cae17 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -11,66 +11,57 @@ density = 0 pressure_resistance = 5*ONE_ATMOSPHERE level = 2 - var/ptype = 0 - // 0=straight, 1=bent, 2=junction-j1, 3=junction-j2, 4=junction-y, 5=trunk, 6=disposal bin, 7=outlet, 8=inlet - + var/ptype = PIPE_DISPOSALS_STRAIGHT //Use the defines + var/base_state var/dpdir = 0 // directions as disposalpipe - var/base_state = "pipe-s" + +/obj/structure/disposalconstruct/New(loc, pipe_type, direction) + ..() + if(pipe_type) + ptype = pipe_type + if(dir) + dir = direction + update() // update iconstate and dpdir due to dir and type /obj/structure/disposalconstruct/proc/update() + base_state = get_pipe_icon(ptype) + icon_state = "con[base_state]" var/flip = turn(dir, 180) var/left = turn(dir, 90) var/right = turn(dir, -90) - + name = get_pipe_name(ptype, PIPETYPE_DISPOSAL) switch(ptype) - if(0) - base_state = "pipe-s" + if(PIPE_DISPOSALS_STRAIGHT) dpdir = dir | flip - if(1) - base_state = "pipe-c" + if(PIPE_DISPOSALS_BENT) dpdir = dir | right - if(2) - base_state = "pipe-j1" + if(PIPE_DISPOSALS_JUNCTION_RIGHT) dpdir = dir | right | flip - if(3) - base_state = "pipe-j2" + if(PIPE_DISPOSALS_JUNCTION_LEFT) dpdir = dir | left | flip - if(4) - base_state = "pipe-y" + if(PIPE_DISPOSALS_Y_JUNCTION) dpdir = dir | left | right - if(5) - base_state = "pipe-t" + if(PIPE_DISPOSALS_TRUNK) dpdir = dir - // disposal bin has only one dir, thus we don't need to care about setting it - if(6) - if(anchored) - base_state = "disposal" - else - base_state = "condisposal" - - if(7) - base_state = "outlet" - dpdir = dir - - if(8) - base_state = "intake" - dpdir = dir - - if(9) - base_state = "pipe-j1s" + if(PIPE_DISPOSALS_SORT_RIGHT) dpdir = dir | right | flip - - if(10) - base_state = "pipe-j2s" + if(PIPE_DISPOSALS_SORT_LEFT) dpdir = dir | left | flip - - - if(ptype<6 || ptype>8) + // disposal bin has only one dir, thus we don't need to care about setting it + if(PIPE_DISPOSALS_BIN) + if(!anchored) + icon_state = "[base_state]-unanchored" + else + icon_state = base_state + if(PIPE_DISPOSALS_OUTLET) + dpdir = dir + icon_state = base_state + if(PIPE_DISPOSALS_CHUTE) + dpdir = dir + icon_state = base_state + if(!(ptype in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE))) icon_state = "con[base_state]" - else - icon_state = base_state - if(invisibility) // if invisible, fade icon icon -= rgb(0,0,0,128) @@ -116,33 +107,33 @@ dir = turn(dir, 180) switch(ptype) - if(2) - ptype = 3 - if(3) - ptype = 2 - if(9) - ptype = 10 - if(10) - ptype = 9 + if(PIPE_DISPOSALS_JUNCTION_RIGHT) + ptype = PIPE_DISPOSALS_JUNCTION_LEFT + if(PIPE_DISPOSALS_JUNCTION_LEFT) + ptype = PIPE_DISPOSALS_JUNCTION_RIGHT + if(PIPE_DISPOSALS_SORT_RIGHT) + ptype = PIPE_DISPOSALS_SORT_LEFT + if(PIPE_DISPOSALS_SORT_LEFT) + ptype = PIPE_DISPOSALS_SORT_RIGHT update() // returns the type path of disposalpipe corresponding to this item dtype /obj/structure/disposalconstruct/proc/dpipetype() switch(ptype) - if(0,1) + if(PIPE_DISPOSALS_STRAIGHT, PIPE_DISPOSALS_BENT) return /obj/structure/disposalpipe/segment - if(2,3,4) + if(PIPE_DISPOSALS_JUNCTION_RIGHT, PIPE_DISPOSALS_JUNCTION_LEFT, PIPE_DISPOSALS_Y_JUNCTION) return /obj/structure/disposalpipe/junction - if(5) + if(PIPE_DISPOSALS_TRUNK) return /obj/structure/disposalpipe/trunk - if(6) + if(PIPE_DISPOSALS_BIN) return /obj/machinery/disposal - if(7) + if(PIPE_DISPOSALS_OUTLET) return /obj/structure/disposaloutlet - if(8) + if(PIPE_DISPOSALS_CHUTE) return /obj/machinery/disposal/deliveryChute - if(9,10) + if(PIPE_DISPOSALS_SORT_RIGHT, PIPE_DISPOSALS_SORT_LEFT) return /obj/structure/disposalpipe/sortjunction return @@ -157,13 +148,13 @@ var/ispipe = 0 // Indicates if we should change the level of this pipe src.add_fingerprint(user) switch(ptype) - if(6) + if(PIPE_DISPOSALS_BIN) nicetype = "disposal bin" - if(7) + if(PIPE_DISPOSALS_OUTLET) nicetype = "disposal outlet" - if(8) + if(PIPE_DISPOSALS_CHUTE) nicetype = "delivery chute" - if(9, 10) + if(PIPE_DISPOSALS_SORT_RIGHT, PIPE_DISPOSALS_SORT_LEFT) nicetype = "sorting pipe" ispipe = 1 else @@ -197,7 +188,7 @@ return var/obj/structure/disposalpipe/CP = locate() in T - if(ptype>=6 && ptype <= 8) // Disposal or outlet + if(ptype in list(PIPE_DISPOSALS_BIN, PIPE_DISPOSALS_OUTLET, PIPE_DISPOSALS_CHUTE)) // Disposal or outlet if(CP) // There's something there if(!istype(CP,/obj/structure/disposalpipe/trunk)) to_chat(user, "The [nicetype] requires a trunk underneath it in order to work.") @@ -236,22 +227,22 @@ P.update_icon() //Needs some special treatment ;) - if(ptype==9 || ptype==10) + if(ptype == PIPE_DISPOSALS_SORT_RIGHT || ptype == PIPE_DISPOSALS_SORT_LEFT) var/obj/structure/disposalpipe/sortjunction/SortP = P SortP.updatedir() - else if(ptype==6) // Disposal bin + else if(ptype == PIPE_DISPOSALS_BIN) // Disposal bin var/obj/machinery/disposal/P = new /obj/machinery/disposal(src.loc) src.transfer_fingerprints_to(P) P.mode = 0 // start with pump off - else if(ptype==7) // Disposal outlet + else if(ptype == PIPE_DISPOSALS_OUTLET) // Disposal outlet var/obj/structure/disposaloutlet/P = new /obj/structure/disposaloutlet(src.loc) src.transfer_fingerprints_to(P) P.dir = dir - else if(ptype==8) // Disposal outlet + else if(ptype==PIPE_DISPOSALS_CHUTE) // Disposal outlet var/obj/machinery/disposal/deliveryChute/P = new /obj/machinery/disposal/deliveryChute(src.loc) src.transfer_fingerprints_to(P) @@ -265,3 +256,13 @@ else to_chat(user, "You need to attach it to the plating first!") return + +/obj/structure/disposalconstruct/rpd_act(mob/user, obj/item/rpd/our_rpd) + if(our_rpd.mode == RPD_ROTATE_MODE) + rotate() + else if(our_rpd.mode == RPD_FLIP_MODE) + flip() + else if(our_rpd.mode == RPD_DELETE_MODE) + our_rpd.delete_single_pipe(user, src) + else + ..() diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 00b3b06a3a5..476028b4532 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -97,7 +97,7 @@ to_chat(user, "You sliced the floorweld off the disposal unit.") var/obj/structure/disposalconstruct/C = new (src.loc) src.transfer_fingerprints_to(C) - C.ptype = 6 // 6 = disposal unit + C.ptype = PIPE_DISPOSALS_BIN C.anchored = 1 C.density = 1 C.update() @@ -889,21 +889,21 @@ var/obj/structure/disposalconstruct/C = new (src.loc) switch(base_icon_state) if("pipe-s") - C.ptype = 0 + C.ptype = PIPE_DISPOSALS_STRAIGHT if("pipe-c") - C.ptype = 1 + C.ptype = PIPE_DISPOSALS_BENT if("pipe-j1") - C.ptype = 2 + C.ptype = PIPE_DISPOSALS_JUNCTION_RIGHT if("pipe-j2") - C.ptype = 3 + C.ptype = PIPE_DISPOSALS_JUNCTION_LEFT if("pipe-y") - C.ptype = 4 + C.ptype = PIPE_DISPOSALS_Y_JUNCTION if("pipe-t") - C.ptype = 5 + C.ptype = PIPE_DISPOSALS_TRUNK if("pipe-j1s") - C.ptype = 9 + C.ptype = PIPE_DISPOSALS_SORT_RIGHT if("pipe-j2s") - C.ptype = 10 + C.ptype = PIPE_DISPOSALS_SORT_LEFT src.transfer_fingerprints_to(C) C.dir = dir C.density = 0 @@ -1339,7 +1339,7 @@ to_chat(user, "You sliced the floorweld off the disposal outlet.") var/obj/structure/disposalconstruct/C = new (src.loc) src.transfer_fingerprints_to(C) - C.ptype = 7 // 7 = outlet + C.ptype = PIPE_DISPOSALS_OUTLET C.update() C.anchored = 1 C.density = 1 diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index c40ed9fe73b..8b2f7c4197f 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -349,7 +349,7 @@ 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.ptype = PIPE_DISPOSALS_CHUTE C.update() C.anchored = 1 C.density = 1 diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 5cb51863851..bba85a5ff00 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -591,6 +591,14 @@ build_path = /obj/item/reagent_containers/syringe category = list("initial", "Medical") +/datum/design/safety_hypo + name = "Medical Hypospray" + id = "safetyhypo" + build_type = AUTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/reagent_containers/hypospray/safety + category = list("initial", "Medical") + /datum/design/prox_sensor name = "Proximity Sensor" id = "prox_sensor" diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 7fde20333c7..1589b78438b 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1120,6 +1120,15 @@ construction_time = 350 category = list("Misc") +/datum/design/integrated_robotic_chassis + name = "Integrated Robotic Chassis" + id = "integrated_robotic_chassis" + build_type = MECHFAB + build_path = /mob/living/carbon/human/machine/created + materials = list(MAT_METAL = 40000) + construction_time = 400 + category = list("Misc") + /datum/design/ipc_cell name = "IPC Microbattery" id = "ipc_cell" diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index f9a42928cf7..b5840d82265 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -103,15 +103,15 @@ build_path = /obj/item/mass_spectrometer category = list("Medical") -/datum/design/posibrain - name = "Positronic Brain" - desc = "The latest in Artificial Intelligences." - id = "mmi_posi" +/datum/design/robotic_brain + name = "Robotic Brain" + desc = "The latest in non-sentient Artificial Intelligences." + id = "mmi_robotic" req_tech = list("programming" = 5, "biotech" = 4, "plasmatech" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1700, MAT_GLASS = 1350, MAT_GOLD = 500) //Gold, because SWAG. construction_time = 75 - build_path = /obj/item/mmi/posibrain + build_path = /obj/item/mmi/robotic_brain category = list("Misc","Medical") /datum/design/mmi_radio_upgrade @@ -245,6 +245,36 @@ materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical") +/datum/design/alienbonegel + name = "Alien Bone Gel" + desc = "Advanced bone gel obtained through Abductor technology." + id = "alien_bonegel" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/bonegel/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + +/datum/design/alienbonesetter + name = "Alien Bone Setter" + desc = "An advanced bone setter obtained through Abductor technology." + id = "alien_bonesetter" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/bonesetter/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + +/datum/design/alienfixovein + name = "Alien FixOVein" + desc = "An advanced FixOVein obtained through Abductor technology." + id = "alien_fixovein" + req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) + build_path = /obj/item/FixOVein/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Medical") + ///////////////////////////////////////// //////////Cybernetic Implants//////////// ///////////////////////////////////////// diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 6fb2a891214..51b4f8512e1 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -43,15 +43,15 @@ if(shocked) shock(user,50) if(panel_open) - var/dat as text + var/list/dat = list() dat += "[src.name] Wires:
    " - for(var/wire in src.wires) - dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
    ") + for(var/wire in wires) + dat += "[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
    " - dat += text("The red light is [src.disabled ? "off" : "on"].
    ") - dat += text("The green light is [src.shocked ? "off" : "on"].
    ") - dat += text("The blue light is [src.hacked ? "off" : "on"].
    ") - user << browse("[src.name] Hacking[dat]","window=hack_win") + dat += "The red light is [src.disabled ? "off" : "on"].
    " + dat += "The green light is [src.shocked ? "off" : "on"].
    " + dat += "The blue light is [src.hacked ? "off" : "on"].
    " + user << browse("[src.name] Hacking[dat.Join("")]","window=hack_win") return diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index a24a9522b38..0e9053bbb44 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -26,11 +26,11 @@ //temp /datum/TCS_Compiler - var/datum/n_scriptOptions/nS_Options/options - var/datum/n_Scanner/nS_Scanner/scanner - var/list/tokens - var/datum/n_Parser/nS_Parser/parser - var/datum/node/BlockDefinition/GlobalBlock/program + var/datum/n_scriptOptions/nS_Options/options + var/datum/n_Scanner/nS_Scanner/scanner + var/list/tokens + var/datum/n_Parser/nS_Parser/parser + var/datum/node/BlockDefinition/GlobalBlock/program /* -- Compile a raw block of text -- */ @@ -248,7 +248,7 @@ But I like HTML, so back to no sanitizing.*/ var/message = interpreter.GetVar("$content") - var/regex/bannedTags = new ("( 0) throw EXCEPTION("Init told to resume when z-level still dirty. Z level: '[zpos]'") @@ -140,23 +144,15 @@ log_debug("Beginning initialization!") var/list/our_atoms = init_list // OURS NOW!!! (Keeping this list to ourselves will prevent hijack) init_list = list() - var/list/late_maps = list() - var/list/pipes = list() - var/list/cables = list() var/watch = start_watch() - for(var/schmoo in our_atoms) - var/atom/movable/AM = schmoo - if(AM) // to catch stuff like the nuke disk that no longer exists - - // This can mess with our state - we leave these for last - if(istype(AM, /obj/effect/landmark/map_loader)) - late_maps.Add(AM) - continue - AM.Initialize(TRUE) - if(istype(AM, /obj/machinery/atmospherics)) - pipes.Add(AM) - else if(istype(AM, /obj/structure/cable)) - cables.Add(AM) + listclearnulls(our_atoms) + var/list/late_maps = typecache_filter_list(our_atoms, maploader_typecache) + var/list/pipes = typecache_filter_list(our_atoms, atmos_machine_typecache) + var/list/cables = typecache_filter_list(our_atoms, cable_typecache) + // If we don't carefully add dirt around the map templates, bad stuff happens + // so we separate them out here + our_atoms -= late_maps + SSatoms.InitializeAtoms(our_atoms, FALSE) log_debug("Primary initialization finished in [stop_watch(watch)]s.") our_atoms.Cut() if(pipes.len) @@ -168,13 +164,14 @@ /datum/space_level/proc/do_pipes(list/pipes) var/watch = start_watch() - log_debug("Building pipenets on z-level '[zpos]'!") - for(var/schmoo in pipes) - var/obj/machinery/atmospherics/machine = schmoo - if(machine) - machine.build_network() + log_debug("Initializing atmos machines on z-level '[zpos]'!") + var/init_count = SSair._setup_atmos_machinery(pipes) + log_debug("Initialized [init_count] machines, took [stop_watch(watch)]s") + watch = start_watch() + log_debug("Initializing pipe networks on z-level '[zpos]'!") + init_count = SSair._setup_pipenets(pipes) + log_debug("Initialized pipenets for [init_count] machines, took [stop_watch(watch)]s") pipes.Cut() - log_debug("Took [stop_watch(watch)]s") /datum/space_level/proc/do_cables(list/cables) var/watch = start_watch() @@ -187,10 +184,8 @@ var/watch = start_watch() log_debug("Loading map templates on z-level '[zpos]'!") space_manager.add_dirt(zpos) // Let's not repeatedly resume init for each template - for(var/schmoo in late_maps) - var/obj/effect/landmark/map_loader/ML = schmoo - if(ML) - ML.Initialize() + for(var/atom/movable/AM in late_maps) + AM.Initialize() late_maps.Cut() space_manager.remove_dirt(zpos) log_debug("Took [stop_watch(watch)]s") diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm index b845404fa35..52273af71fe 100644 --- a/code/modules/spacepods/equipment.dm +++ b/code/modules/spacepods/equipment.dm @@ -2,6 +2,7 @@ if(my_atom.next_firetime > world.time) to_chat(usr, "Your weapons are recharging.") return + my_atom.next_firetime = world.time + fire_delay var/turf/firstloc var/turf/secondloc if(!my_atom.equipment_system || !my_atom.equipment_system.weapon_system) @@ -41,7 +42,6 @@ projone.dumbfire(my_atom.dir) projtwo.dumbfire(my_atom.dir) sleep(2) - my_atom.next_firetime = world.time + fire_delay /datum/spacepod/equipment var/obj/spacepod/my_atom diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 24123d52fc0..d4e7514e262 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -557,11 +557,14 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v /obj/spacepod/syndi name = "syndicate spacepod" - desc = "An armed spacepod painted in syndicate colors." + desc = "A spacepod painted in syndicate colors." icon_state = "pod_synd" health = 400 unlocked = FALSE +/obj/spacepod/syndi/unlocked + unlocked = TRUE + /obj/spacepod/sec/New() ..() var/obj/item/spacepod_equipment/weaponry/burst_taser/T = new /obj/item/spacepod_equipment/weaponry/taser diff --git a/code/modules/store/items.dm b/code/modules/store/items.dm index 285c75ad3f3..4c1610474ba 100644 --- a/code/modules/store/items.dm +++ b/code/modules/store/items.dm @@ -46,17 +46,23 @@ cost = 200 /datum/storeitem/dnd - name = "Dungeons & Dragons set" + name = "Dungeons & Dragons Set" desc = "A box containing minifigures suitable for a good game of D&D." typepath = /obj/item/storage/box/characters cost = 200 /datum/storeitem/dice - name = "Dice set" + name = "Dice Set" desc = "A box containing multiple different types of die." typepath = /obj/item/storage/box/dice cost = 200 +/datum/storeitem/candle + name = "Candles" + desc = "A box of candles. Use them to fool others into thinking you're out for a romantic dinner...or something." + typepath = /obj/item/storage/fancy/candle_box/full + cost = 200 + /datum/storeitem/nanomob_booster name = "Nano-Mob Hunter Trading Card Booster Pack" desc = "Contains 6 random Nano-Mob Hunter Trading Cards. May contain a holographic card!" @@ -65,58 +71,52 @@ /datum/storeitem/crayons name = "Crayons" - desc = "Let security know how they're doing by scrawling lovenotes all over their hallways." + desc = "Let security know how they're doing by scrawling love notes all over their hallways." typepath = /obj/item/storage/fancy/crayons cost = 350 /datum/storeitem/pipe - name = "smoking pipe" - desc = "A pipe, for smoking. Probably made of meershaum or something." + name = "Smoking Pipe" + desc = "A pipe, for smoking. Probably made of meerschaum or something." typepath = /obj/item/clothing/mask/cigarette/pipe cost = 350 -/datum/storeitem/candle - name = "Candles" - desc = "A box of chandles. Use them to fool others into thinking you're out for a romantic dinner...or something." - typepath = /obj/item/storage/fancy/candle_box/full - cost = 200 - /datum/storeitem/minigibber - name = "miniature gibber" + name = "Miniature Gibber" desc = "A miniature recreation of Nanotrasen's famous meat grinder." typepath = /obj/item/toy/minigibber cost = 400 /datum/storeitem/katana - name = "replica katana" + name = "Replica Katana" desc = "Woefully underpowered in D20." typepath = /obj/item/toy/katana cost = 500 -/datum/storeitem/piano_synth - name = "piano synthesizer" - desc = "An advanced electronic synthesizer that can be used as various instruments." - typepath = /obj/item/instrument/piano_synth - cost = 1000 - /datum/storeitem/violin - name = "space violin" + name = "Space Violin" desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\"" typepath = /obj/item/instrument/violin cost = 500 /datum/storeitem/guitar - name = "guitar" + name = "Guitar" desc = "It's made of wood and has bronze strings." typepath = /obj/item/instrument/guitar cost = 500 /datum/storeitem/eguitar - name = "electric guitar" + name = "Electric Guitar" desc = "Makes all your shredding needs possible." typepath = /obj/item/instrument/eguitar cost = 500 +/datum/storeitem/piano_synth + name = "Piano Synthesizer" + desc = "An advanced electronic synthesizer that can emulate various instruments." + typepath = /obj/item/instrument/piano_synth + cost = 1000 + /datum/storeitem/baby name = "Toddler" desc = "This baby looks almost real. Wait, did it just burp?" @@ -124,91 +124,91 @@ cost = 1000 /datum/storeitem/flag_slime - name = "Slime People flag" + name = "Slime People Flag" desc = "A flag proudly proclaiming the superior heritage of Slime People." typepath = /obj/item/flag/species/slime cost = 1000 /datum/storeitem/flag_skrell - name = "Skrell flag" + name = "Skrell Flag" desc = "A flag proudly proclaiming the superior heritage of Skrell." typepath = /obj/item/flag/species/skrell cost = 1000 /datum/storeitem/flag_vox - name = "Vox flag" + name = "Vox Flag" desc = "A flag proudly proclaiming the superior heritage of Vox." typepath = /obj/item/flag/species/vox cost = 1000 /datum/storeitem/flag_machine - name = "Synthetics flag" + name = "Synthetics Flag" desc = "A flag proudly proclaiming the superior heritage of Synthetics." typepath = /obj/item/flag/species/machine cost = 1000 /datum/storeitem/flag_diona - name = "Diona flag" + name = "Diona Flag" desc = "A flag proudly proclaiming the superior heritage of Dionae." typepath = /obj/item/flag/species/diona cost = 1000 /datum/storeitem/flag_human - name = "Human flag" + name = "Human Flag" desc = "A flag proudly proclaiming the superior heritage of Humans." typepath = /obj/item/flag/species/human cost = 1000 /datum/storeitem/flag_greys - name = "Greys flag" + name = "Greys Flag" desc = "A flag proudly proclaiming the superior heritage of Greys." typepath = /obj/item/flag/species/greys cost = 1000 /datum/storeitem/flag_kidan - name = "Kidan flag" + name = "Kidan Flag" desc = "A flag proudly proclaiming the superior heritage of Kidan." typepath = /obj/item/flag/species/kidan cost = 1000 /datum/storeitem/flag_taj - name = "Tajaran flag" + name = "Tajaran Flag" desc = "A flag proudly proclaiming the superior heritage of Tajara." typepath = /obj/item/flag/species/taj cost = 1000 /datum/storeitem/flag_unathi - name = "Unathi flag" + name = "Unathi Flag" desc = "A flag proudly proclaiming the superior heritage of Unathi." typepath = /obj/item/flag/species/unathi cost = 1000 /datum/storeitem/flag_vulp - name = "Vulpkanin flag" + name = "Vulpkanin Flag" desc = "A flag proudly proclaiming the superior heritage of Vulpkanin." typepath = /obj/item/flag/species/vulp cost = 1000 /datum/storeitem/flag_drask - name = "Drask flag" + name = "Drask Flag" desc = "A flag proudly proclaiming the superior heritage of Drask." typepath = /obj/item/flag/species/drask cost = 1000 /datum/storeitem/flag_plasma - name = "Plasmaman flag" + name = "Plasmaman Flag" desc = "A flag proudly proclaiming the superior heritage of Plasmamen." typepath = /obj/item/flag/species/plasma cost = 1000 /datum/storeitem/flag_ian - name = "Ian flag" + name = "Ian Flag" desc = "The banner of Ian, because SQUEEEEE." typepath = /obj/item/flag/ian cost = 1500 /datum/storeitem/banhammer - desc = "A banhammer" - name = "banhammer" + name = "Banhammer" + desc = "A Banhammer." typepath = /obj/item/banhammer cost = 2000 diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 715f3e9837b..1ae29143496 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -84,7 +84,7 @@ /proc/get_pain_modifier(mob/living/carbon/human/M) //returns modfier to make surgery harder if patient is conscious and feels pain if(M.stat) //stat=0 if CONSCIOUS, 1=UNCONSCIOUS and 2=DEAD. Operating on dead people is easy, too. Just sleeping won't work, though. return 1 - if(NO_PAIN in M.species.species_traits)//if you don't feel pain, you can hold still + if(NO_PAIN in M.dna.species.species_traits)//if you don't feel pain, you can hold still return 1 if(M.reagents.has_reagent("hydrocodone"))//really good pain killer return 0.99 diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm index 2e8a3b85300..42db2e97da1 100644 --- a/code/modules/surgery/limb_reattach.dm +++ b/code/modules/surgery/limb_reattach.dm @@ -32,7 +32,7 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting) - if(target.get_species() == "Machine") + if(ismachine(target)) // RIP bi-centennial man return 0 if(!affected) @@ -76,7 +76,7 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) if(affected) return 0 - var/list/organ_data = target.species.has_limbs["[target_zone]"] + var/list/organ_data = target.dna.species.has_limbs["[target_zone]"] return !isnull(organ_data) /datum/surgery_step/limb/attach @@ -233,7 +233,7 @@ for(var/part_name in L.part) if(!isnull(target.get_organ(part_name))) continue - var/list/organ_data = target.species.has_limbs["[part_name]"] + var/list/organ_data = target.dna.species.has_limbs["[part_name]"] if(!organ_data) continue // This will break if there's more than one stump ever diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index c6b2ac07f19..da559d38d5f 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -33,7 +33,7 @@ var/mob/living/carbon/human/H = HA if(!istype(H)) H = owner - var/icon/cybereyes_icon = new /icon('icons/mob/human_face.dmi', H.species.eyes) + var/icon/cybereyes_icon = new /icon('icons/mob/human_face.dmi', H.dna.species.eyes) cybereyes_icon.Blend(eye_colour, ICON_ADD) // Eye implants override native DNA eye color return cybereyes_icon diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index fecbdb05287..2a7057516f9 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -18,7 +18,7 @@ /mob/living/carbon/human/handle_blood() var/list/blood_data = get_blood_data(get_blood_id())//PROCCEPTION - if(NO_BLOOD in species.species_traits) + if(NO_BLOOD in dna.species.species_traits) bleed_rate = 0 return @@ -43,14 +43,14 @@ if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) to_chat(src, "You feel [word].") - apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1), species.blood_damage_type) + apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1), dna.species.blood_damage_type) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1), species.blood_damage_type) + apply_damage_type(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1), dna.species.blood_damage_type) if(prob(5)) EyeBlurry(6) to_chat(src, "You feel very [word].") if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) - apply_damage_type(5, species.blood_damage_type) + apply_damage_type(5, dna.species.blood_damage_type) if(prob(15)) Paralyse(rand(1,3)) to_chat(src, "You feel extremely [word].") @@ -99,9 +99,9 @@ add_splatter_floor(loc, 1) /mob/living/carbon/human/bleed(amt) - if(!(NO_BLOOD in species.species_traits)) + if(!(NO_BLOOD in dna.species.species_traits)) ..() - if(species.exotic_blood) + if(dna.species.exotic_blood) var/datum/reagent/R = chemical_reagents_list[get_blood_id()] if(istype(R) && isturf(loc)) R.reaction_turf(get_turf(src), amt) @@ -186,7 +186,7 @@ blood_data["blood_type"] = copytext(src.dna.b_type,1,0) blood_data["gender"] = gender blood_data["real_name"] = real_name - blood_data["blood_color"] = species.blood_color + blood_data["blood_color"] = dna.species.blood_color blood_data["factions"] = faction return blood_data @@ -199,9 +199,9 @@ return "blood" /mob/living/carbon/human/get_blood_id() - if(species.exotic_blood)//some races may bleed water..or kethcup.. - return species.exotic_blood - else if((NO_BLOOD in species.species_traits) || (NOCLONE in mutations)) + if(dna.species.exotic_blood)//some races may bleed water..or kethcup.. + return dna.species.exotic_blood + else if((NO_BLOOD in dna.species.species_traits) || (NOCLONE in mutations)) return return "blood" @@ -279,7 +279,7 @@ B.layer = BELOW_MOB_LAYER //So the blood lands ontop of things like posters, windows, etc. /mob/living/carbon/human/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) - if(!(NO_BLOOD in species.species_traits)) + if(!(NO_BLOOD in dna.species.species_traits)) ..() /mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip, shift_x, shift_y) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index bce0f0f8046..51d73fc9873 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -20,7 +20,7 @@ var/mob/living/carbon/human/H = HA if(!istype(H)) H = owner - var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.species.eyes) + var/icon/eyes_icon = new /icon('icons/mob/human_face.dmi', H.dna.species.eyes) eyes_icon.Blend(eye_colour, ICON_ADD) return eyes_icon diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 59643723d78..bd7cca63779 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -85,7 +85,7 @@ /obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/H, mob/living/carbon/human/user, obj/target) if(H == user && istype(H)) - if(NO_BLOOD in H.species.species_traits) + if(NO_BLOOD in H.dna.species.species_traits) to_chat(H, "\The [src] is not compatible with your form!") return playsound(user,'sound/effects/singlebeat.ogg', 40, 1) @@ -98,7 +98,7 @@ if(world.time > (last_pump + pump_delay)) if(ishuman(owner) && owner.client) //While this entire item exists to make people suffer, they can't control disconnects. var/mob/living/carbon/human/H = owner - if(!(NO_BLOOD in H.species.species_traits)) + if(!(NO_BLOOD in H.dna.species.species_traits)) H.blood_volume = max(H.blood_volume - blood_loss, 0) to_chat(H, "You have to keep pumping your blood!") if(H.client) @@ -131,7 +131,7 @@ var/mob/living/carbon/human/H = owner if(istype(H)) - if(!(NO_BLOOD in H.species.species_traits)) + if(!(NO_BLOOD in H.dna.species.species_traits)) H.blood_volume = min(H.blood_volume + cursed_heart.blood_loss*0.5, BLOOD_VOLUME_NORMAL) if(owner.client) owner.client.color = "" diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index 99bc996dce2..3c2b7e1cbd1 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -154,12 +154,12 @@ if(safe_nitro_min) if(N2_pp < safe_nitro_min) gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.nitrogen) - H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro) + H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro) else H.failed_last_breath = FALSE H.adjustOxyLoss(-5) gas_breathed = breath.nitrogen - H.clear_alert("nitro") + H.clear_alert("not_enough_nitro") //Exhale breath.nitrogen -= gas_breathed @@ -271,11 +271,11 @@ var/breath_temperature = breath.temperature var/species_traits = list() - if(H && H.species && H.species.species_traits) - species_traits = H.species.species_traits + if(H && H.dna.species && H.dna.species.species_traits) + species_traits = H.dna.species.species_traits if(!(COLDRES in H.mutations) && !(RESISTCOLD in species_traits)) // COLD DAMAGE - var/CM = abs(H.species.coldmod) + var/CM = abs(H.dna.species.coldmod) var/TC = 0 if(breath_temperature < cold_level_3_threshold) TC = cold_level_3_damage @@ -291,7 +291,7 @@ to_chat(H, "You feel [cold_message] in your [name]!") if(!(HEATRES in H.mutations) && !(RESISTHOT in species_traits)) // HEAT DAMAGE - var/HM = abs(H.species.heatmod) + var/HM = abs(H.dna.species.heatmod) var/TH = 0 if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold) TH = heat_level_1_damage @@ -315,7 +315,6 @@ name = "plasma filter" desc = "A spongy rib-shaped mass for filtering plasma from the air." icon_state = "lungs-plasma" - species = "Plasmaman" safe_oxygen_min = 0 //We don't breath this safe_toxins_min = 16 //We breathe THIS! @@ -324,7 +323,6 @@ /obj/item/organ/internal/lungs/vox name = "Vox lungs" desc = "They're filled with dust....wow." - species = "Vox" safe_oxygen_min = 0 //We don't breathe this safe_oxygen_max = 1 //This is toxic to us @@ -333,7 +331,6 @@ /obj/item/organ/internal/lungs/drask icon = 'icons/obj/surgery_drask.dmi' - species = "Drask" cold_message = "an invigorating coldness" cold_level_3_threshold = 60 diff --git a/code/modules/surgery/organs/mmi_holder.dm b/code/modules/surgery/organs/mmi_holder.dm new file mode 100644 index 00000000000..d4228fb9625 --- /dev/null +++ b/code/modules/surgery/organs/mmi_holder.dm @@ -0,0 +1,36 @@ +// Used for an MMI or robotic brain being installed into a human. +/obj/item/organ/internal/brain/mmi_holder + name = "Man-Machine Interface" + parent_organ = "chest" + status = ORGAN_ROBOT + var/obj/item/mmi/stored_mmi + +/obj/item/organ/internal/brain/mmi_holder/Destroy() + QDEL_NULL(stored_mmi) + return ..() + +/obj/item/organ/internal/brain/mmi_holder/insert(mob/living/target, special = 0) + ..() + // To supersede the over-writing of the MMI's name from `insert` + update_from_mmi() + +/obj/item/organ/internal/brain/mmi_holder/remove(mob/living/user, special = 0) + if(!special) + if(stored_mmi) + . = stored_mmi + if(owner.mind) + owner.mind.transfer_to(stored_mmi.brainmob) + stored_mmi.forceMove(get_turf(owner)) + stored_mmi = null + ..() + if(!QDELETED(src)) + qdel(src) + +/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() + if(!stored_mmi) + return + name = initial(stored_mmi.name) + desc = stored_mmi.desc + icon = stored_mmi.icon + icon_state = stored_mmi.icon_state + set_dna(stored_mmi.brainmob.dna) \ No newline at end of file diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index 6cca1117b28..991a5d252ce 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -19,7 +19,6 @@ // links chemical IDs to number of ticks for which they'll stay in the blood germ_level = 0 var/datum/dna/dna - var/datum/species/species = "Human" // Stuff for tracking if this is on a tile with an open freezer or not var/last_freezer_update_time = 0 @@ -30,6 +29,7 @@ var/tough = FALSE //can organ be easily damaged? var/emp_proof = FALSE //is the organ immune to EMPs? var/hidden_pain = FALSE //will it skip pain messages? + var/requires_robotic_bodypart = FALSE /obj/item/organ/Destroy() @@ -43,15 +43,13 @@ /obj/item/organ/proc/update_health() return -/obj/item/organ/New(var/mob/living/carbon/holder) +/obj/item/organ/New(mob/living/carbon/holder, datum/species/species_override = null) ..(holder) if(!max_damage) max_damage = min_broken_damage * 2 if(istype(holder)) - species = all_species["Human"] if(holder.dna) dna = holder.dna.Clone() - species = all_species[dna.species] else log_runtime(EXCEPTION("[holder] spawned without a proper DNA."), holder) var/mob/living/carbon/human/H = holder @@ -61,8 +59,9 @@ blood_DNA = list() blood_DNA[dna.unique_enzymes] = dna.b_type else - if(istext(species)) - species = all_species[species] + dna = new /datum/dna(null) + if(species_override) + dna.species = new species_override /obj/item/organ/proc/set_dna(var/datum/dna/new_dna) if(new_dna) @@ -92,7 +91,7 @@ return //Process infections - if(is_robotic() || sterile || (owner && (IS_PLANT in owner.species.species_traits))) + if(is_robotic() || sterile || (owner && (IS_PLANT in owner.dna.species.species_traits))) germ_level = 0 return @@ -154,7 +153,7 @@ germ_level++ if(germ_level >= INFECTION_LEVEL_ONE) - var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.species.body_temperature + var/fever_temperature = (owner.dna.species.heat_level_1 - owner.dna.species.body_temperature - 5)* min(germ_level/INFECTION_LEVEL_TWO, 1) + owner.dna.species.body_temperature owner.bodytemperature += between(0, (fever_temperature - T20C)/BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) if(germ_level >= INFECTION_LEVEL_TWO) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index bd064a7d062..04ce880d5f5 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -105,13 +105,12 @@ /obj/item/organ/external/New(var/mob/living/carbon/holder) ..() var/mob/living/carbon/human/H = holder - icobase = species.icobase - deform = species.deform + icobase = dna.species.icobase + deform = dna.species.deform if(istype(H)) replaced(H) sync_colour_to_human(H) - spawn(1) - get_icon() + get_icon() /obj/item/organ/external/replaced(var/mob/living/carbon/human/target) owner = target @@ -279,7 +278,8 @@ This function completely restores a damaged organ to perfect condition. for(var/obj/item/organ/external/EO in contents) EO.rejuvenate() - owner.updatehealth() + if(owner) + owner.updatehealth() update_icon() if(!owner) processing_objects |= src @@ -328,7 +328,7 @@ Note that amputating the affected organ does in fact remove the infection from t */ /obj/item/organ/external/proc/update_germs() - if(is_robotic() || (IS_PLANT in owner.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. + if(is_robotic() || (IS_PLANT in owner.dna.species.species_traits)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. germ_level = 0 return @@ -400,7 +400,7 @@ Note that amputating the affected organ does in fact remove the infection from t fracture() /obj/item/organ/external/proc/check_for_internal_bleeding(damage) - if(NO_BLOOD in owner.species.species_traits) + if(NO_BLOOD in owner.dna.species.species_traits) return var/local_damage = brute_dam + damage if(damage > 15 && local_damage > 30 && prob(damage) && !is_robotic()) @@ -449,7 +449,7 @@ Note that amputating the affected organ does in fact remove the infection from t ****************************************************/ //Handles dismemberment -/obj/item/organ/external/proc/droplimb(var/clean, var/disintegrate, var/ignore_children, var/nodamage) +/obj/item/organ/external/proc/droplimb(clean, disintegrate, ignore_children, nodamage) if(cannot_amputate || !owner) return @@ -494,16 +494,17 @@ Note that amputating the affected organ does in fact remove the infection from t parent.receive_damage(total_brute, total_burn, ignore_resists = TRUE) //Transfer the full damage to the parent, bypass limb damage reduction. parent = null - spawn(1) - if(victim) - victim.updatehealth() - victim.UpdateDamageIcon() - victim.regenerate_icons() dir = 2 + + if(victim) + victim.updatehealth() + victim.UpdateDamageIcon() + victim.regenerate_icons() + switch(disintegrate) if(DROPLIMB_SHARP) compile_icon() - add_blood(victim.blood_DNA, victim.species.blood_color) + add_blood(victim.blood_DNA, victim.dna.species.blood_color) var/matrix/M = matrix() M.Turn(rand(180)) src.transform = M @@ -513,7 +514,7 @@ Note that amputating the affected organ does in fact remove the infection from t dropped_part.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30) dir = 2 brute_dam = 0 - burn_dam = 0 //Reset the damage on the limb; the damage should have transferred to the parent; we don't want extra damage being re-applie when then limb is re-attached + burn_dam = 0 //Reset the damage on the limb; the damage should have transferred to the parent; we don't want extra damage being re-applied when then limb is re-attached return dropped_part else qdel(src) // If you flashed away to ashes, YOU FLASHED AWAY TO ASHES @@ -606,7 +607,7 @@ Note that amputating the affected organ does in fact remove the infection from t "You hear a loud cracking sound coming from \the [owner].",\ "Something feels like it shattered in your [name]!",\ "You hear a sickening crack.") - if(owner.species && !(NO_PAIN in owner.species.species_traits)) + if(owner.dna.species && !(NO_PAIN in owner.dna.species.species_traits)) owner.emote("scream") status |= ORGAN_BROKEN diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index d1c1070b19d..43d699c0408 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -16,7 +16,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/change_organ_icobase(var/new_icobase, var/new_deform, var/owner_sensitive) //Change the icobase/deform of this organ. If owner_sensitive is set, that means the proc won't mess with frankenstein limbs. if(owner_sensitive) //This and the below statements mean that the icobase/deform will only get updated if the limb is the same species as and is owned by the mob it's attached to. - if(species && owner.species && species.name != owner.species.name) + if(dna.species && owner.dna.species && dna.species.name != owner.dna.species.name) return if(dna.unique_enzymes != owner.dna.unique_enzymes) // This isn't MY arm return @@ -25,31 +25,31 @@ var/global/list/limb_icon_cache = list() deform = new_deform ? new_deform : deform /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/H) - if(is_robotic() && !(species && species.name == "Machine")) //machine people get skin color + if(is_robotic() && !istype(dna.species, /datum/species/machine)) //machine people get skin color return - if(species && H.species && species.name != H.species.name) + if(dna.species && H.dna.species && dna.species.name != H.dna.species.name) return if(dna.unique_enzymes != H.dna.unique_enzymes) // This isn't MY arm - if(!(H.species.bodyflags & HAS_ICON_SKIN_TONE)) + if(!(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE)) sync_colour_to_dna() return - if(!isnull(H.s_tone) && ((H.species.bodyflags & HAS_SKIN_TONE) || (H.species.bodyflags & HAS_ICON_SKIN_TONE))) + if(!isnull(H.s_tone) && ((H.dna.species.bodyflags & HAS_SKIN_TONE) || (H.dna.species.bodyflags & HAS_ICON_SKIN_TONE))) s_col = null s_tone = H.s_tone - if(H.species.bodyflags & HAS_SKIN_COLOR) + if(H.dna.species.bodyflags & HAS_SKIN_COLOR) s_tone = null s_col = H.skin_colour - if(H.species.bodyflags & HAS_ICON_SKIN_TONE) + if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE) var/obj/item/organ/external/chest/C = H.get_organ("chest") change_organ_icobase(C.icobase, C.deform) /obj/item/organ/external/proc/sync_colour_to_dna() if(is_robotic()) return - if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && ((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) + if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && ((dna.species.bodyflags & HAS_SKIN_TONE) || (dna.species.bodyflags & HAS_ICON_SKIN_TONE))) s_col = null s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) - if(species.bodyflags & HAS_SKIN_COLOR) + if(dna.species.bodyflags & HAS_SKIN_COLOR) s_tone = null s_col = rgb(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) @@ -64,11 +64,9 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/proc/get_icon(skeletal, fat) // Kasparrov, you monster - if(istext(species)) - species = all_species[species] if(force_icon) mob_icon = new /icon(force_icon, "[icon_name]") - if(species && species.name == "Machine") //snowflake for IPC's, sorry. + if(istype(dna.species, /datum/species/machine)) //snowflake for IPC's, sorry. if(s_col) mob_icon.Blend(s_col, ICON_ADD) else @@ -101,13 +99,13 @@ var/global/list/limb_icon_cache = list() if(!owner) return - if(species.has_organ["eyes"]) + if(dna.species.has_organ["eyes"]) var/icon/eyes_icon = owner.get_eyecon() if(eyes_icon) mob_icon.Blend(eyes_icon, ICON_OVERLAY) overlays |= eyes_icon - if(owner.lip_style && (LIPS in species.species_traits)) + if(owner.lip_style && (LIPS in dna.species.species_traits)) var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") overlays |= lip_icon mob_icon.Blend(lip_icon, ICON_OVERLAY) @@ -115,7 +113,7 @@ var/global/list/limb_icon_cache = list() var/head_marking = owner.m_styles["head"] if(head_marking && head_marking != "None") var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") + if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) @@ -123,7 +121,7 @@ var/global/list/limb_icon_cache = list() if(ha_style) var/datum/sprite_accessory/head_accessory_style = head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (species.name in head_accessory_style.species_allowed)) + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(headacc_colour, ICON_ADD) @@ -131,9 +129,9 @@ var/global/list/limb_icon_cache = list() if(f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (species.name in facial_hair_style.species_allowed)) || (src.species.bodyflags & ALL_RPARTS))) + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(istype(dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. else if(facial_hair_style.do_colouration) facial_s.Blend(facial_colour, ICON_ADD) @@ -141,9 +139,9 @@ var/global/list/limb_icon_cache = list() if(h_style && !(owner.head && (owner.head.flags & BLOCKHEADHAIR))) var/datum/sprite_accessory/hair_style = hair_styles_full_list[h_style] - if(hair_style && ((species.name in hair_style.species_allowed) || (src.species.bodyflags & ALL_RPARTS))) + if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(species.name == "Slime People") // I am el worstos + if(istype(dna.species, /datum/species/slime)) // I am el worstos hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. else if(hair_style.do_colouration) hair_s.Blend(hair_colour, ICON_ADD) @@ -184,7 +182,7 @@ var/global/list/limb_icon_cache = list() /obj/item/organ/external/chest/get_icon_state(skeletal) var/result = ..() - if(fat && !skeletal && !is_robotic() && (CAN_BE_FAT in species.species_traits)) + if(fat && !skeletal && !is_robotic() && (CAN_BE_FAT in dna.species.species_traits)) result[2] += "_fat" return result diff --git a/code/modules/surgery/organs/pain.dm b/code/modules/surgery/organs/pain.dm index e3386aef1b3..4863bd63901 100644 --- a/code/modules/surgery/organs/pain.dm +++ b/code/modules/surgery/organs/pain.dm @@ -34,7 +34,7 @@ mob/living/carbon/human/proc/custom_pain(message) if(stat >= UNCONSCIOUS) return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return if(reagents.has_reagent("morphine")) return @@ -54,7 +54,7 @@ mob/living/carbon/human/proc/handle_pain() if(stat >= UNCONSCIOUS) return - if(NO_PAIN in species.species_traits) + if(NO_PAIN in dna.species.species_traits) return if(reagents.has_reagent("morphine")) return diff --git a/code/modules/surgery/organs/parasites.dm b/code/modules/surgery/organs/parasites.dm index 900e60d9806..bea8d37ae38 100644 --- a/code/modules/surgery/organs/parasites.dm +++ b/code/modules/surgery/organs/parasites.dm @@ -35,7 +35,8 @@ /obj/item/organ/internal/body_egg/spider_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() M.reagents.del_reagent("spidereggs") //purge all remaining spider eggs reagent if caught, in time. - qdel(src) //We don't want people re-implanting these for near instant gibbings. + if(!QDELETED(src)) + qdel(src) // prevent people re-implanting them into others return null @@ -114,5 +115,6 @@ /obj/item/organ/internal/body_egg/terror_eggs/remove(var/mob/living/carbon/M, var/special = 0) ..() - qdel(src) // prevent people re-implanting them into others + if(!QDELETED(src)) + qdel(src) // prevent people re-implanting them into others return null diff --git a/code/modules/surgery/organs/subtypes/abductor.dm b/code/modules/surgery/organs/subtypes/abductor.dm index 6fd234bc501..58efd0094ed 100644 --- a/code/modules/surgery/organs/subtypes/abductor.dm +++ b/code/modules/surgery/organs/subtypes/abductor.dm @@ -1,4 +1,3 @@ /obj/item/organ/internal/eyes/abductor name = "abductor eyeballs" - dark_view = 3 - species = "Abductor" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index 951ca862317..be05b2917c3 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -6,7 +6,6 @@ amputation_point = "trunk" encased = null gendered_icon = 0 - species = "Diona" /obj/item/organ/external/groin/diona name = "fork" @@ -14,7 +13,6 @@ cannot_break = 1 amputation_point = "lower trunk" gendered_icon = 0 - species = "Diona" /obj/item/organ/external/arm/diona name = "left upper tendril" @@ -22,7 +20,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "upper left trunk" - species = "Diona" /obj/item/organ/external/arm/right/diona name = "right upper tendril" @@ -30,7 +27,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "upper right trunk" - species = "Diona" /obj/item/organ/external/leg/diona name = "left lower tendril" @@ -38,7 +34,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "lower left fork" - species = "Diona" /obj/item/organ/external/leg/right/diona name = "right lower tendril" @@ -46,7 +41,6 @@ min_broken_damage = 20 cannot_break = 1 amputation_point = "lower right fork" - species = "Diona" /obj/item/organ/external/foot/diona name = "left foot" @@ -54,7 +48,6 @@ min_broken_damage = 10 cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/foot/right/diona name = "right foot" @@ -62,19 +55,16 @@ min_broken_damage = 10 cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/hand/diona name = "left grasper" cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/hand/right/diona name = "right grasper" cannot_break = 1 amputation_point = "branch" - species = "Diona" /obj/item/organ/external/head/diona max_damage = 50 @@ -83,16 +73,6 @@ encased = null amputation_point = "upper trunk" gendered_icon = 0 - species = "Diona" - -//DIONA ORGANS. -/* /obj/item/organ/external/diona/removed() - var/mob/living/carbon/human/H = owner - ..() - if(!istype(H) || !H.bodyparts || !H.bodyparts.len) - H.death() - if(prob(50) && spawn_diona_nymph_from_organ(src)) - qdel(src) */ /obj/item/organ/diona/process() return @@ -101,31 +81,26 @@ name = "neural strata" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "Diona" /obj/item/organ/internal/brain/diona // Turns into a nymph instantly, no transplanting possible. name = "gas bladder" icon = 'icons/obj/objects.dmi' icon_state = "nymph" - species = "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" - species = "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" - species = "Diona" /obj/item/organ/internal/eyes/diona // Turns into a nymph instantly, no transplanting possible. name = "receptor node" icon = 'icons/mob/alien.dmi' icon_state = "claw" - species = "Diona" //TODO:Make absorb rads on insert @@ -133,15 +108,4 @@ name = "nutrient vessel" icon = 'icons/mob/alien.dmi' icon_state = "claw" - alcohol_intensity = 0.5 - species = "Diona" - -//TODO:Make absorb light on insert. - -/*/obj/item/organ/diona/removed(var/mob/living/user) - var/mob/living/carbon/human/H = owner - ..() - if(!istype(H) || !H.bodyparts || !H.bodyparts.len) - H.death() - if(prob(50) && spawn_diona_nymph_from_organ(src)) - qdel(src) */ + alcohol_intensity = 0.5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/drask.dm b/code/modules/surgery/organs/subtypes/drask.dm index 8560d2408ec..6e11cf2993e 100644 --- a/code/modules/surgery/organs/subtypes/drask.dm +++ b/code/modules/surgery/organs/subtypes/drask.dm @@ -4,31 +4,26 @@ icon = 'icons/obj/surgery_drask.dmi' icon_state = "innards" desc = "A greenish, slightly translucent organ. It is extremely cold." - species = "Drask" /obj/item/organ/internal/heart/drask name = "drask heart" icon = 'icons/obj/surgery_drask.dmi' parent_organ = "head" - species = "Drask" /obj/item/organ/internal/liver/drask name = "metabolic strainer" icon = 'icons/obj/surgery_drask.dmi' icon_state = "kidneys" alcohol_intensity = 0.8 - species = "Drask" /obj/item/organ/internal/brain/drask icon = 'icons/obj/surgery_drask.dmi' icon_state = "brain2" mmi_icon = 'icons/obj/surgery_drask.dmi' mmi_icon_state = "mmi_full" - species = "Drask" /obj/item/organ/internal/eyes/drask name = "drask eyeballs" icon = 'icons/obj/surgery_drask.dmi' desc = "Drask eyes. They look even stranger disembodied" - dark_view = 5 - species = "Drask" + dark_view = 5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm index 6c06da373b7..177e4ae5be1 100644 --- a/code/modules/surgery/organs/subtypes/grey.dm +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -1,11 +1,9 @@ /obj/item/organ/internal/liver/grey alcohol_intensity = 1.6 - species = "Grey" /obj/item/organ/internal/brain/grey icon_state = "brain-x" mmi_icon_state = "mmi_alien" - species = "Grey" /obj/item/organ/internal/brain/grey/insert(var/mob/living/carbon/M, var/special = 0) ..() @@ -17,5 +15,4 @@ /obj/item/organ/internal/eyes/grey name = "grey eyeballs" - dark_view = 5 - species = "Grey" + dark_view = 5 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/kidan.dm b/code/modules/surgery/organs/subtypes/kidan.dm index 37fd74a6d2a..d8fc67cc542 100644 --- a/code/modules/surgery/organs/subtypes/kidan.dm +++ b/code/modules/surgery/organs/subtypes/kidan.dm @@ -1,6 +1,5 @@ /obj/item/organ/internal/liver/kidan alcohol_intensity = 0.5 - species = "Kidan" #define KIDAN_LANTERN_HUNGERCOST 0.5 #define KIDAN_LANTERN_MINHUNGER 150 diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm index 7c68fc11f28..b66d13612a3 100644 --- a/code/modules/surgery/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -5,100 +5,90 @@ min_broken_damage = 30 encased = null status = ORGAN_ROBOT - species = "Machine" -/obj/item/organ/external/head/ipc/New() +/obj/item/organ/external/head/ipc/New(mob/living/carbon/holder, datum/species/species_override = null) + ..(holder, /datum/species/machine) // IPC heads need to be explicitly set to this since you can print them robotize("Morpheus Cyberkinetics") - ..() /obj/item/organ/external/chest/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/chest/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/groin/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/groin/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/arm/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/arm/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/arm/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/arm/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") + /obj/item/organ/external/leg/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/leg/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/leg/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/leg/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/foot/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/foot/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/foot/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/foot/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/hand/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/hand/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/external/hand/right/ipc encased = null status = ORGAN_ROBOT - species = "Machine" /obj/item/organ/external/hand/right/ipc/New() - robotize("Morpheus Cyberkinetics") ..() + robotize("Morpheus Cyberkinetics") /obj/item/organ/internal/cell name = "microbattery" @@ -110,84 +100,37 @@ slot = "heart" vital = TRUE status = ORGAN_ROBOT - species = "Machine" - -/obj/item/organ/internal/cell/New() - robotize() - ..() /obj/item/organ/internal/eyes/optical_sensor name = "optical sensor" icon = 'icons/obj/robot_component.dmi' icon_state = "camera" status = ORGAN_ROBOT - species = "Machine" // dead_icon = "camera_broken" weld_proof = 1 -/obj/item/organ/internal/eyes/optical_sensor/New() - robotize() - ..() - - /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.") . = ..() -// Used for an MMI or posibrain being installed into a human. -/obj/item/organ/internal/brain/mmi_holder - name = "brain" - organ_tag = "brain" - parent_organ = "chest" - vital = TRUE - max_damage = 200 - slot = "brain" - status = ORGAN_ROBOT - species = "Machine" - var/obj/item/mmi/stored_mmi - -/obj/item/organ/internal/brain/mmi_holder/Destroy() - QDEL_NULL(stored_mmi) - return ..() - -/obj/item/organ/internal/brain/mmi_holder/insert(var/mob/living/target,special = 0) - ..() - // To supersede the over-writing of the MMI's name from `insert` - update_from_mmi() - -/obj/item/organ/internal/brain/mmi_holder/remove(var/mob/living/user,special = 0) - if(!special) - if(stored_mmi) - . = stored_mmi - if(owner.mind) - owner.mind.transfer_to(stored_mmi.brainmob) - stored_mmi.forceMove(get_turf(owner)) - stored_mmi = null - ..() - qdel(src) - -/obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() - if(!stored_mmi) - return - name = stored_mmi.name - desc = stored_mmi.desc - icon = stored_mmi.icon - icon_state = stored_mmi.icon_state - set_dna(stored_mmi.brainmob.dna) +/obj/item/organ/internal/brain/mmi_holder/posibrain + name = "positronic brain" /obj/item/organ/internal/brain/mmi_holder/posibrain/New() - robotize() - stored_mmi = new /obj/item/mmi/posibrain/ipc(src) ..() - spawn(1) - if(owner) - stored_mmi.name = "positronic brain ([owner.real_name])" - stored_mmi.brainmob.real_name = owner.real_name - stored_mmi.brainmob.name = stored_mmi.brainmob.real_name - stored_mmi.icon_state = "posibrain-occupied" - update_from_mmi() - else - stored_mmi.loc = get_turf(src) - qdel(src) + stored_mmi = new /obj/item/mmi/robotic_brain/positronic(src) + if(!owner) + stored_mmi.forceMove(get_turf(src)) + qdel(src) + +/obj/item/organ/internal/brain/mmi_holder/posibrain/remove(mob/living/user, special = 0) + if(stored_mmi && dna) + stored_mmi.name = "[initial(name)] ([dna.real_name])" + stored_mmi.brainmob.real_name = dna.real_name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.icon_state = "posibrain-occupied" + if(!stored_mmi.brainmob.dna) + stored_mmi.brainmob.dna = dna.Clone() + . = ..() \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/nucleation.dm b/code/modules/surgery/organs/subtypes/nucleation.dm index 4223834501d..3be564fc800 100644 --- a/code/modules/surgery/organs/subtypes/nucleation.dm +++ b/code/modules/surgery/organs/subtypes/nucleation.dm @@ -3,7 +3,6 @@ name = "nucleation organ" icon = 'icons/obj/surgery.dmi' desc = "A crystalized human organ. /red It has a strangely iridescent glow." - species = "Nucleation" /obj/item/organ/internal/nucleation/resonant_crystal name = "resonant crystal" @@ -11,7 +10,6 @@ organ_tag = "resonant crystal" parent_organ = "head" slot = "res_crystal" - species = "Nucleation" /obj/item/organ/internal/nucleation/strange_crystal name = "strange crystal" @@ -19,14 +17,12 @@ organ_tag = "strange crystal" parent_organ = "chest" slot = "heart" - species = "Nucleation" /obj/item/organ/internal/eyes/luminescent_crystal name = "luminescent eyes" icon_state = "crystal-eyes" organ_tag = "luminescent eyes" light_color = "#1C1C00" - species = "Nucleation" /obj/item/organ/internal/eyes/luminescent_crystal/New() set_light(2) @@ -35,5 +31,4 @@ /obj/item/organ/internal/brain/crystal name = "crystallized brain" icon_state = "crystal-brain" - organ_tag = "crystallized brain" - species = "Nucleation" + organ_tag = "crystallized brain" \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/shadow.dm b/code/modules/surgery/organs/subtypes/shadow.dm index f81fc54bfb1..26a0bc50577 100644 --- a/code/modules/surgery/organs/subtypes/shadow.dm +++ b/code/modules/surgery/organs/subtypes/shadow.dm @@ -1,4 +1,3 @@ /obj/item/organ/internal/eyes/shadow name = "dark orbs" - dark_view = 8 - species = "Shadow" + dark_view = 8 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/skrell.dm b/code/modules/surgery/organs/subtypes/skrell.dm index cb87d1c11c1..fd8a02f18d3 100644 --- a/code/modules/surgery/organs/subtypes/skrell.dm +++ b/code/modules/surgery/organs/subtypes/skrell.dm @@ -1,6 +1,5 @@ /obj/item/organ/internal/liver/skrell alcohol_intensity = 4 - species = "Skrell" /obj/item/organ/internal/headpocket name = "headpocket" @@ -10,7 +9,6 @@ w_class = WEIGHT_CLASS_TINY parent_organ = "head" slot = "headpocket" - species = "Skrell" actions_types = list(/datum/action/item_action/organ_action/toggle) var/obj/item/storage/internal/pocket diff --git a/code/modules/surgery/organs/subtypes/standard.dm b/code/modules/surgery/organs/subtypes/standard.dm index 1a548de7d0a..e04c27284ae 100644 --- a/code/modules/surgery/organs/subtypes/standard.dm +++ b/code/modules/surgery/organs/subtypes/standard.dm @@ -136,9 +136,9 @@ if(owner.gloves) owner.unEquip(owner.gloves) if(owner.l_hand) - owner.unEquip(owner.l_hand,1) + owner.unEquip(owner.l_hand, TRUE) if(owner.r_hand) - owner.unEquip(owner.r_hand,1) + owner.unEquip(owner.r_hand, TRUE) . = ..() @@ -194,17 +194,14 @@ owner.unEquip(owner.r_ear) if(owner.wear_mask) owner.unEquip(owner.wear_mask) - spawn(1) - if(owner)//runtimer no runtiming - owner.update_hair() - owner.update_fhair() - owner.update_head_accessory() - owner.update_markings() + owner.update_hair() + owner.update_fhair() + owner.update_head_accessory() + owner.update_markings() . = ..() /obj/item/organ/external/head/replaced() name = limb_name - ..() /obj/item/organ/external/head/receive_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE) @@ -224,6 +221,11 @@ alt_head = initial(alt_head) icon_name = initial(icon_name) +/obj/item/organ/external/head/robotize(company, make_tough = 0, convert_all = 1) //Undoes alt_head business to avoid getting in the way of robotization. Make sure we pass all args down the line... + alt_head = initial(alt_head) + icon_name = initial(icon_name) + ..() + /obj/item/organ/external/head/set_dna(datum/dna/new_dna) ..() new_dna.write_head_attributes(src) diff --git a/code/modules/surgery/organs/subtypes/tajaran.dm b/code/modules/surgery/organs/subtypes/tajaran.dm index a1313934037..1857fc5e45a 100644 --- a/code/modules/surgery/organs/subtypes/tajaran.dm +++ b/code/modules/surgery/organs/subtypes/tajaran.dm @@ -1,17 +1,14 @@ /obj/item/organ/internal/liver/tajaran alcohol_intensity = 1.4 - species = "Tajaran" /obj/item/organ/internal/eyes/tajaran 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. replace_colours = LIST_TAJ_REPLACE dark_view = 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 replace_colours = LIST_TAJ_REPLACE diff --git a/code/modules/surgery/organs/subtypes/unathi.dm b/code/modules/surgery/organs/subtypes/unathi.dm index 0fb45319ce5..219ef0447e6 100644 --- a/code/modules/surgery/organs/subtypes/unathi.dm +++ b/code/modules/surgery/organs/subtypes/unathi.dm @@ -1,8 +1,6 @@ /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" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/vox.dm b/code/modules/surgery/organs/subtypes/vox.dm index f5b4b4edc07..960acf920a8 100644 --- a/code/modules/surgery/organs/subtypes/vox.dm +++ b/code/modules/surgery/organs/subtypes/vox.dm @@ -1,16 +1,12 @@ /obj/item/organ/internal/liver/vox alcohol_intensity = 1.6 - species = "Vox" /obj/item/organ/internal/stack - name = "cortical stack" + name = "vox cortical stack" icon_state = "brain-prosthetic" parent_organ = "head" organ_tag = "stack" slot = "vox_stack" status = ORGAN_ROBOT - vital = TRUE - -/obj/item/organ/internal/stack/vox - name = "vox cortical stack" \ No newline at end of file + vital = TRUE \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/vulpkanin.dm b/code/modules/surgery/organs/subtypes/vulpkanin.dm index be851c43486..959fbcc926c 100644 --- a/code/modules/surgery/organs/subtypes/vulpkanin.dm +++ b/code/modules/surgery/organs/subtypes/vulpkanin.dm @@ -1,18 +1,14 @@ /obj/item/organ/internal/liver/vulpkanin alcohol_intensity = 1.4 - species = "Vulpkanin" - /obj/item/organ/internal/eyes/vulpkanin 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. replace_colours = LIST_VULP_REPLACE dark_view = 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 - replace_colours = LIST_VULP_REPLACE + replace_colours = LIST_VULP_REPLACE \ No newline at end of file diff --git a/code/modules/surgery/organs/subtypes/wryn.dm b/code/modules/surgery/organs/subtypes/wryn.dm index ee1a12fd1ab..ab30c16f61f 100644 --- a/code/modules/surgery/organs/subtypes/wryn.dm +++ b/code/modules/surgery/organs/subtypes/wryn.dm @@ -6,8 +6,6 @@ icon_state = "antennae" parent_organ = "head" slot = "hivenode" - species = "Wryn" /obj/item/organ/internal/eyes/wryn - dark_view = 3 - species = "Wryn" + dark_view = 3 \ No newline at end of file diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 11e16d10b1a..32270c329c2 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -101,6 +101,9 @@ if(is_int_organ(tool)) current_type = "insert" I = tool + if(I.requires_robotic_bodypart) + to_chat(user, "[I] is an organ that requires a robotic interface[target].") + return -1 if(target_zone != I.parent_organ || target.get_organ_slot(I.slot)) to_chat(user, "There is no room for [I] in [target]'s [parse_zone(target_zone)]!") return -1 @@ -257,12 +260,14 @@ else if(current_type == "insert") I = tool - user.drop_item() - I.insert(target) - spread_germs_to_organ(I, user, tool) - if(!user.canUnEquip(I, 0)) + if(I.requires_robotic_bodypart) + to_chat(user, "[I] is an organ that requires a robotic interface[target].") + return FALSE + if(!user.drop_item()) to_chat(user, "[I] is stuck to your hand, you can't put it in [target]!") return 0 + I.insert(target) + spread_germs_to_organ(I, user, tool) if(affected) user.visible_message(" [user] has transplanted [tool] into [target]'s [affected.name].", diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 467f1e64a00..bcb5151d359 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -303,7 +303,7 @@ ..() /datum/surgery_step/internal/dethrall/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) - if(target.get_species() == "Lesser Shadowling") //Empowered thralls cannot be deconverted + if(isshadowlinglesser(target)) //Empowered thralls cannot be deconverted to_chat(target, "NOT LIKE THIS!") user.visible_message("[target] suddenly slams upward and knocks down [user]!", \ "[target] suddenly bolts up and slams you with tremendous force!") diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index a0e4c2a3976..9483818d153 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -24,7 +24,7 @@ /datum/surgery_step/reshape_face/end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/organ/external/head/head = target.get_organ(target_zone) - var/species_names = target.get_species() + var/species_names = target.dna.species.name if(head.disfigured) head.disfigured = FALSE user.visible_message("[user] successfully restores [target]'s appearance!", "You successfully restore [target]'s appearance.") diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 0fc8b2852cc..f9fb2ac20c2 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -347,12 +347,12 @@ to_chat(user, "You cannot install a computer brain into a meat enclosure.") return -1 - if(!target.species) + if(!target.dna.species) to_chat(user, "You have no idea what species this person is. Report this on the bug tracker.") return -1 - if(!target.species.has_organ["brain"]) - to_chat(user, "You're pretty sure [target.species.name_plural] don't normally have a brain.") + if(!target.dna.species.has_organ["brain"]) + to_chat(user, "You're pretty sure [target.dna.species.name_plural] don't normally have a brain.") return -1 if(target.get_int_organ(/obj/item/organ/internal/brain/)) @@ -541,3 +541,60 @@ user.visible_message(" [user]'s hand slips!", \ " Your hand slips!") return 0 + +/datum/surgery/cybernetic_customization + name = "Cybernetic Appearance Customization" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch, /datum/surgery_step/robotics/external/customize_appearance) + possible_locs = list("head", "chest", "l_arm", "r_arm", "r_leg", "l_leg") + requires_organic_bodypart = FALSE + +/datum/surgery/cybernetic_customization/can_start(mob/user, mob/living/carbon/human/target) + if(ishuman(target)) + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return FALSE + if(!(affected.status & ORGAN_ROBOT)) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance + name = "reprogram limb" + allowed_tools = list(/obj/item/multitool = 100) + time = 48 + +/datum/surgery_step/robotics/external/customize_appearance/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to reprogram the appearance of [target]'s [affected.name] with [tool]." , \ + "You begin to reprogram the appearance of [target]'s [affected.name] with [tool].") + ..() + +/datum/surgery_step/robotics/external/customize_appearance/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/chosen_appearance = input(user, "Select the company appearance for this limb.", "Limb Company Selection") as null|anything in selectable_robolimbs + if(!chosen_appearance) + return FALSE + var/obj/item/organ/external/affected = target.get_organ(target_zone) + affected.robotize(chosen_appearance, convert_all = FALSE) + if(istype(affected, /obj/item/organ/external/head)) + var/obj/item/organ/external/head/head = affected + head.h_style = "Bald" // nearly all the appearance changes for heads are non-monitors; we want to get rid of a floating screen + target.update_hair() + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + user.visible_message(" [user] reprograms the appearance of [target]'s [affected.name] with [tool].", \ + " You reprogram the appearance of [target]'s [affected.name] with [tool].") + affected.open = 0 + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to reprogram [target]'s [affected.name].", + " Your [tool.name] slips, failing to reprogram [target]'s [affected.name].") + return FALSE \ No newline at end of file diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 0c7aadc36c5..72bf70c7e81 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -67,10 +67,6 @@ //How much blood this step can get on surgeon. 1 - hands, 2 - full body. var/blood_level = 0 - var/list/allowed_mob = list() - var/list/disallowed_mob = list() - - /datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) var/success = 0 if(accept_hand) @@ -146,19 +142,8 @@ // Checks if this step applies to the user mob at all /datum/surgery_step/proc/is_valid_target(mob/living/carbon/human/target) if(!hasorgans(target)) - return 0 - - if(allowed_mob)//can i just remove this and/or change it? - for(var/species in allowed_mob) - if(target.get_species() == species) - return 1 - - if(disallowed_mob) - for(var/species in disallowed_mob) - if(target.get_species() == species) - return 0 - - return 1 + return FALSE + return TRUE // checks whether this step can be applied with the given user and target /datum/surgery_step/proc/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) @@ -195,7 +180,7 @@ //germ spread from surgeon touching the patient if(user.gloves) germ_level = user.gloves.germ_level - E.germ_level += germ_level + E.germ_level = max(germ_level, E.germ_level) spread_germs_by_incision(E, tool) //germ spread from environement to patient /proc/spread_germs_by_incision(obj/item/organ/external/E,obj/item/tool) @@ -206,7 +191,7 @@ for(var/mob/living/carbon/human/H in view(2, E.loc))//germs from people if(AStar(E.loc, H.loc, /turf/proc/Distance, 2, simulated_only = 0)) - if((!(BREATHLESS in H.mutations) || !(NO_BREATHE in H.species.species_traits)) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions + if((!(BREATHLESS in H.mutations) || !(NO_BREATHE in H.dna.species.species_traits)) && !H.wear_mask) //wearing a mask helps preventing people from breathing cooties into open incisions germs += H.germ_level * 0.25 for(var/obj/effect/decal/cleanable/M in view(2, E.loc))//germs from messes diff --git a/code/modules/vr/vr_controller.dm b/code/modules/vr/vr_controller.dm index 45bf2a6cc74..564291b2999 100644 --- a/code/modules/vr/vr_controller.dm +++ b/code/modules/vr/vr_controller.dm @@ -31,12 +31,12 @@ proc/build_virtual_avatar(mob/living/carbon/human/H, location, datum/map_templat var/mob/living/carbon/human/virtual_reality/vr_avatar location = get_turf(location) vr_avatar = new /mob/living/carbon/human/virtual_reality(location) - vr_avatar.set_species(H.species.name) if(istype(H, /mob/living/carbon/human/virtual_reality)) var/mob/living/carbon/human/virtual_reality/V = H vr_avatar.real_me = V.real_me else vr_avatar.real_me = H + vr_avatar.set_species(H.dna.species.type) vr_avatar.dna = H.dna.Clone() vr_avatar.name = H.name vr_avatar.real_name = H.real_name diff --git a/config/example/config.txt b/config/example/config.txt index 84e67d5f127..c8bdc8cffc9 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -304,7 +304,13 @@ PLAYER_REROUTE_CAP 0 #DISABLE_AWAY_MISSIONS ## Disable the loading of space ruins -DISABLE_SPACE_RUINS +#DISABLE_SPACE_RUINS + +## Minimum number of space ruins levels to generate +EXTRA_SPACE_RUINS_LEVELS_MIN 2 + +## Maximum number of space ruins levels to generate +EXTRA_SPACE_RUINS_LEVELS_MAX 4 ## Uncomment to disable the OOC/LOOC channel by default. #DISABLE_OOC diff --git a/config/names/diona.txt b/config/names/diona.txt deleted file mode 100644 index 3eb4b5f4498..00000000000 --- a/config/names/diona.txt +++ /dev/null @@ -1,13 +0,0 @@ -Blade of Grass Bent Before Wind -Glimmer Of The Stars -The Ripple Of the Waves -Colors Of Dusk -The Still Of Night -Silence Of The Wind -Gentle Breeze of the Summer Wind -Glistening Water under the Blazing Sun -Child of the Scorching Sun -Blessed Plant-ling of Eternal Fields -Grass-walker of the Soothing Plains -Element of the Undying Fiona -Spawn of Mother Nature's Busum \ No newline at end of file diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index f3fe28315f6..234c5ac2274 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -342,7 +342,8 @@ h1.alert, h2.alert {color: #000000;} .clown {color: #ff0000;} .shadowling {color: #3b2769;} .vulpkanin {color: #B97A57;} -.abductor {color: #800080;} +.abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .rough {font-family: 'Trebuchet MS', cursive, sans-serif;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .cult {color: #800080; font-weight: bold; font-style: italic;} diff --git a/html/changelog.html b/html/changelog.html index 9b19d74c332..28b7dfa242d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,258 @@ -->
    +

    09 August 2018

    +

    variableundefined updated:

    +
      +
    • banangarang's maid bot fluff sprites
    • +
    + +

    07 August 2018

    +

    Anasari updated:

    +
      +
    • Polaris card system partially ported. Credits to Jedr for the hand of card item_action sprites.
    • +
    +

    Kyep updated:

    +
      +
    • Simple_animal mobs now get a HUD button that lets them switch between HELP and HARM intents.
    • +
    • Replaced the Syndicate Supply Depot with a new version, rebuilt from scratch, that is much more challenging/interesting.
    • +
    • It is no longer possible to walk straight through decoy AI cores as if they were not there.
    • +
    • Syndicate grenade launcher turrets now actually launch grenades.
    • +
    +

    MarsM0nd updated:

    +
      +
    • Unathi can now tailwhip when they are supposed to be able to.
    • +
    • Tail whipping gets logged.
    • +
    + +

    06 August 2018

    +

    AffectedArc07 updated:

    +
      +
    • Barber no longer spawns with an extra pair of shoes in his bag
    • +
    +

    Tails2091 updated:

    +
      +
    • Fixed Therapy Dolls not working.
    • +
    • Made Prize Machine & Merch Sore readable.
    • +
    • Fixed capitalizations and typos in both lists.
    • +
    + +

    05 August 2018

    +

    Crazylemon64 updated:

    +
      +
    • Space ruins can no longer trap you upon border transition
    • +
    • There are now several levels of space ruins
    • +
    +

    Fox McCloud updated:

    +
      +
    • Adds in medical hyposprays
    • +
    + +

    03 August 2018

    +

    Fox McCloud updated:

    +
      +
    • IPC Change monitor is now an action button
    • +
    • Slime Color change is now an action button
    • +
    • Fixes staff of change leaving behind unknowns
    • +
    • Fixes Shadowlings not having shock resistant and thermal vision
    • +
    • Fixes staff of change gibbing people
    • +
    +

    Shazbot updated:

    +
      +
    • Adds in the ability to unsaw sawn off riot shotguns. Change: Changes the riot shotgun icon.
    • +
    + +

    02 August 2018

    +

    variableundefined updated:

    +
      +
    • Nightmares now works. Sleep well.
    • +
    • Megaphone actually logs in say log now.
    • +
    + +

    01 August 2018

    +

    Citinited updated:

    +
      +
    • Heaters and freezers now have min and max buttons
    • +
    +

    CornMyCob updated:

    +
      +
    • The description for miniature energy guns is now accurate
    • +
    • The third person text of someone reinforcing an airlock is now accurate
    • +
    +

    Tails2091 updated:

    +
      +
    • Karma refund now uses switch statement.
    • +
    +

    datlo updated:

    +
      +
    • Updated syndicate hardsuit description.
    • +
    + +

    31 July 2018

    +

    Tails2091 updated:

    +
      +
    • Claw Game Prize Ball now drops more than one ticket like it should.
    • +
    +

    variableundefined updated:

    +
      +
    • fix a runtime error with bluespace projector
    • +
    + +

    30 July 2018

    +

    Tails2091 updated:

    +
      +
    • Changed wannabe for loop to a real for loop.
    • +
    + +

    28 July 2018

    +

    KasparoVy updated:

    +
      +
    • You can now safely augment the heads of pointy-snooted Unathi, although your mileage may vary.
    • +
    + +

    27 July 2018

    +

    AffectedArc07 updated:

    +
      +
    • You can no longer use embeds in NTSL
    • +
    +

    Crazylemon64 updated:

    +
      +
    • Space hotel is back in business
    • +
    • Non-hotel SNPCs work again
    • +
    +

    Fox McCloud updated:

    +
      +
    • Extract posibrains should have the correct names now
    • +
    • Abductors can now purchase a mind device to speak into crewmembers minds or give directives to abductees
    • +
    • Abductors now have their own versions of the FixOVein, Bonesetter, and Bonegel. Credit to Triiodine for the sprites
    • +
    • Adds a new electric shock and chemical gland for abductors
    • +
    • viral gland generates random viruses and egg laying gland eggs now have random reagents in them
    • +
    +

    variableundefined updated:

    +
      +
    • Cyborg Analyzer no longer rounds off the damage number it displays.
    • +
    + +

    25 July 2018

    +

    variableundefined updated:

    +
      +
    • Fixes runtime error from medical kit change
    • +
    + +

    24 July 2018

    +

    Kyep updated:

    +
      +
    • Number of roundstart atmos suits in atmos increased from 2 to 4.
    • +
    + +

    22 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Fixes monkeys not having their own HUD
    • +
    • Fixes monkey to human transformations missing their HUD
    • +
    • Fixes changing species unequipping items
    • +
    • Fixes organs not being rejuvinated properly by mitocholide
    • +
    • Fixes shadowlings not being forced to hatch
    • +
    • Having a robotic head will allow you to use buzz, ping, beep, and the likes
    • +
    • Claw sharpening now works
    • +
    • Abductors have their own headset instead of a syndicate one
    • +
    • Can put monkeys in the gibber
    • +
    • gibbing some species will now generate different types of hides (monkeys give monkey hides, unathi give lizard hides, the likes)
    • +
    • fixes Vox name generation based on the wrong syllables
    • +
    • consolidates diona name lists; you'll no longer be asked to rename your Diona when you start the shift
    • +
    • botany grown diona can no longer rename themselves (as is consistent with ghost roles)
    • +
    • Fixes DNA scrambler so it gives a proper randomized species name
    • +
    • Fixed an edge case were Vox would have a permanent nitrogen alert
    • +
    • Fixes operatives being bald most of the time
    • +
    • Adds beesplosion chemical reaction
    • +
    +

    and taukausanake updated:

    +
      +
    • Swarmers can no longer destroy active clone pods.
    • +
    + +

    17 July 2018

    +

    Citinited updated:

    +
      +
    • volume pumps can be dispensed by the RPD again
    • +
    +

    datlo updated:

    +
      +
    • Provided abductors with an infection free surgery table.
    • +
    + +

    16 July 2018

    +

    Citinited updated:

    +
      +
    • RPD behaviour has been slightly tweaked - for example you can now rotate / flip / delete individual pipes by clicking on them without affecting other pipes on that tile.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Fixes hand labelers not being able to label storage objects
    • +
    • Cameras can now be destroyed with weapons that have a force of 12 or greater
    • +
    • Cameras have 2 wires as opposed to 6; camera focus and power wires still remain
    • +
    • You can use hand labelers on reagent containers now
    • +
    + +

    14 July 2018

    +

    Anasari updated:

    +
      +
    • Assuming there is heal left, bandages and ointments used on limbs now heal both the limb and the hand / foot. Bandages and ointments used on the torso now heal head, arms, and lower body. The one on lower body heals the legs too.
    • +
    +

    Aurorablade updated:

    +
      +
    • Adds Spess Koi and related event.
    • +
    +

    Citinited updated:

    +
      +
    • The tachyon-doppler array now has a logging interface, and can print off stored explosive logs. Brag to your friends about your bomb-making skills!
    • +
    +

    Fox McCloud updated:

    +
      +
    • Robotic brains have their own unique sprite and full flavortext's now
    • +
    • Fixed a bug where IRC's would have IPC names
    • +
    + +

    11 July 2018

    +

    Alffd updated:

    +
      +
    • Updates SM engine to modern standards
    • +
    • Ports SM monitoring system from Bay and TG
    • +
    • Adds station wide radiation alarm when crystal/shard goes critical
    • +
    • Tesla zapping
    • +
    +

    Citinited updated:

    +
      +
    • Fortune cookies now drop random fortunes if cooked with a blank piece of paper.
    • +
    +

    Fox McCloud updated:

    +
      +
    • Adds constructable Integrated Robotic Chassis
    • +
    • Adds surgery to customize existing robotic limb appearances
    • +
    • Positronic brains renamed to robotic brains
    • +
    +

    FreeStylaLT updated:

    +
      +
    • Added a Harmonica to Perma Brig
    • +
    +

    datlo updated:

    +
      +
    • Replaced instances of "Human" in ion laws by "Crew".
    • +
    • Fixed the ability of Service Borgs to spawn items on floors. Dosh!
    • +
    + +

    10 July 2018

    +

    Fox McCloud updated:

    +
      +
    • Can no longer take assisted organs at round-start (mechanical organs are still a go, but renamed to cybernetic organs)
    • +
    • Can now start the round with cybernetic lungs, liver, and kidneys
    • +
    • Can produce cybernetic eyes at R&D and mechfabs
    • +
    • Cybernetic internal organs no longer take reduced damage (this does not apply to augments)
    • +
    • Cybernetic internal organs can be rendered inoperable (this does not apply to augments)
    • +
    • Fixes mitocholide/oculine healing damage on cybernetic organs
    • +
    • Fixes being able to restart a dead heart in your hands or with a defib
    • +
    +

    09 July 2018

    Fox McCloud updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 62873f7bb24..e3a5c43a874 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -6593,3 +6593,177 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: Adds cybernetic heart, lungs, liver, and kidneys to R&D and Robotics; also adds cybernetic upgraded lungs - tweak: Heads are no longer vital organs, but brains still are +2018-07-10: + Fox McCloud: + - rscdel: Can no longer take assisted organs at round-start (mechanical organs are + still a go, but renamed to cybernetic organs) + - rscadd: Can now start the round with cybernetic lungs, liver, and kidneys + - rscadd: Can produce cybernetic eyes at R&D and mechfabs + - tweak: Cybernetic internal organs no longer take reduced damage (this does not + apply to augments) + - tweak: Cybernetic internal organs can be rendered inoperable (this does not apply + to augments) + - bugfix: Fixes mitocholide/oculine healing damage on cybernetic organs + - bugfix: Fixes being able to restart a dead heart in your hands or with a defib +2018-07-11: + Alffd: + - bugfix: Updates SM engine to modern standards + - rscadd: Ports SM monitoring system from Bay and TG + - rscadd: Adds station wide radiation alarm when crystal/shard goes critical + - rscadd: Tesla zapping + Citinited: + - rscadd: Fortune cookies now drop random fortunes if cooked with a blank piece + of paper. + Fox McCloud: + - rscadd: Adds constructable Integrated Robotic Chassis + - rscadd: Adds surgery to customize existing robotic limb appearances + - tweak: Positronic brains renamed to robotic brains + FreeStylaLT: + - rscadd: Added a Harmonica to Perma Brig + datlo: + - bugfix: Replaced instances of "Human" in ion laws by "Crew". + - bugfix: Fixed the ability of Service Borgs to spawn items on floors. Dosh! +2018-07-14: + Anasari: + - tweak: Assuming there is heal left, bandages and ointments used on limbs now heal + both the limb and the hand / foot. Bandages and ointments used on the torso + now heal head, arms, and lower body. The one on lower body heals the legs too. + Aurorablade: + - rscadd: Adds Spess Koi and related event. + Citinited: + - tweak: The tachyon-doppler array now has a logging interface, and can print off + stored explosive logs. Brag to your friends about your bomb-making skills! + Fox McCloud: + - tweak: Robotic brains have their own unique sprite and full flavortext's now + - bugfix: Fixed a bug where IRC's would have IPC names +2018-07-16: + Citinited: + - tweak: RPD behaviour has been slightly tweaked - for example you can now rotate + / flip / delete individual pipes by clicking on them without affecting other + pipes on that tile. + Fox McCloud: + - bugfix: Fixes hand labelers not being able to label storage objects + - rscadd: Cameras can now be destroyed with weapons that have a force of 12 or greater + - tweak: Cameras have 2 wires as opposed to 6; camera focus and power wires still + remain + - tweak: You can use hand labelers on reagent containers now +2018-07-17: + Citinited: + - bugfix: volume pumps can be dispensed by the RPD again + datlo: + - rscadd: Provided abductors with an infection free surgery table. +2018-07-22: + Fox McCloud: + - bugfix: Fixes monkeys not having their own HUD + - bugfix: Fixes monkey to human transformations missing their HUD + - bugfix: Fixes changing species unequipping items + - bugfix: Fixes organs not being rejuvinated properly by mitocholide + - bugfix: Fixes shadowlings not being forced to hatch + - rscadd: Having a robotic head will allow you to use buzz, ping, beep, and the + likes + - tweak: Claw sharpening now works + - rscadd: Abductors have their own headset instead of a syndicate one + - tweak: Can put monkeys in the gibber + - rscadd: gibbing some species will now generate different types of hides (monkeys + give monkey hides, unathi give lizard hides, the likes) + - bugfix: fixes Vox name generation based on the wrong syllables + - tweak: consolidates diona name lists; you'll no longer be asked to rename your + Diona when you start the shift + - rscdel: botany grown diona can no longer rename themselves (as is consistent with + ghost roles) + - bugfix: Fixes DNA scrambler so it gives a proper randomized species name + - bugfix: Fixed an edge case were Vox would have a permanent nitrogen alert + - bugfix: Fixes operatives being bald most of the time + - rscadd: Adds beesplosion chemical reaction + and taukausanake: + - tweak: Swarmers can no longer destroy active clone pods. +2018-07-24: + Kyep: + - tweak: Number of roundstart atmos suits in atmos increased from 2 to 4. +2018-07-25: + variableundefined: + - bugfix: Fixes runtime error from medical kit change +2018-07-27: + AffectedArc07: + - bugfix: You can no longer use embeds in NTSL + Crazylemon64: + - rscadd: Space hotel is back in business + - bugfix: Non-hotel SNPCs work again + Fox McCloud: + - bugfix: Extract posibrains should have the correct names now + - rscadd: Abductors can now purchase a mind device to speak into crewmembers minds + or give directives to abductees + - rscadd: Abductors now have their own versions of the FixOVein, Bonesetter, and + Bonegel. Credit to Triiodine for the sprites + - rscadd: Adds a new electric shock and chemical gland for abductors + - tweak: viral gland generates random viruses and egg laying gland eggs now have + random reagents in them + variableundefined: + - tweak: Cyborg Analyzer no longer rounds off the damage number it displays. +2018-07-28: + KasparoVy: + - bugfix: You can now safely augment the heads of pointy-snooted Unathi, although + your mileage may vary. +2018-07-30: + Tails2091: + - bugfix: Changed wannabe for loop to a real for loop. +2018-07-31: + Tails2091: + - bugfix: Claw Game Prize Ball now drops more than one ticket like it should. + variableundefined: + - bugfix: fix a runtime error with bluespace projector +2018-08-01: + Citinited: + - tweak: Heaters and freezers now have min and max buttons + CornMyCob: + - tweak: The description for miniature energy guns is now accurate + - tweak: The third person text of someone reinforcing an airlock is now accurate + Tails2091: + - bugfix: Karma refund now uses switch statement. + datlo: + - rscadd: Updated syndicate hardsuit description. +2018-08-02: + variableundefined: + - bugfix: Nightmares now works. Sleep well. + - tweak: Megaphone actually logs in say log now. +2018-08-03: + Fox McCloud: + - tweak: IPC Change monitor is now an action button + - tweak: Slime Color change is now an action button + - bugfix: Fixes staff of change leaving behind unknowns + - bugfix: Fixes Shadowlings not having shock resistant and thermal vision + - bugfix: Fixes staff of change gibbing people + Shazbot: + - rscadd: 'Adds in the ability to unsaw sawn off riot shotguns. Change: Changes + the riot shotgun icon.' +2018-08-05: + Crazylemon64: + - bugfix: Space ruins can no longer trap you upon border transition + - rscadd: There are now several levels of space ruins + Fox McCloud: + - rscadd: Adds in medical hyposprays +2018-08-06: + AffectedArc07: + - tweak: Barber no longer spawns with an extra pair of shoes in his bag + Tails2091: + - bugfix: Fixed Therapy Dolls not working. + - tweak: Made Prize Machine & Merch Sore readable. + - spellcheck: Fixed capitalizations and typos in both lists. +2018-08-07: + Anasari: + - rscadd: Polaris card system partially ported. Credits to Jedr for the hand of + card item_action sprites. + Kyep: + - rscadd: Simple_animal mobs now get a HUD button that lets them switch between + HELP and HARM intents. + - tweak: Replaced the Syndicate Supply Depot with a new version, rebuilt from scratch, + that is much more challenging/interesting. + - bugfix: It is no longer possible to walk straight through decoy AI cores as if + they were not there. + - bugfix: Syndicate grenade launcher turrets now actually launch grenades. + MarsM0nd: + - bugfix: Unathi can now tailwhip when they are supposed to be able to. + - rscadd: Tail whipping gets logged. +2018-08-09: + variableundefined: + - rscadd: banangarang's maid bot fluff sprites diff --git a/html/changelogs/AutoChangeLog-pr-9186.yml b/html/changelogs/AutoChangeLog-pr-9186.yml deleted file mode 100644 index 9b98775973d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-9186.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "Fox McCloud" -delete-after: True -changes: - - rscdel: "Can no longer take assisted organs at round-start (mechanical organs are still a go, but renamed to cybernetic organs)" - - rscadd: "Can now start the round with cybernetic lungs, liver, and kidneys" - - rscadd: "Can produce cybernetic eyes at R&D and mechfabs" - - tweak: "Cybernetic internal organs no longer take reduced damage (this does not apply to augments)" - - tweak: "Cybernetic internal organs can be rendered inoperable (this does not apply to augments)" - - bugfix: "Fixes mitocholide/oculine healing damage on cybernetic organs" - - bugfix: "Fixes being able to restart a dead heart in your hands or with a defib" diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 3acfa100085..5dd923111e6 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/custom_synthetic/custom-synthetic.dmi b/icons/mob/custom_synthetic/custom-synthetic.dmi index 6143f5ef4d7..a5e4d42bb49 100644 Binary files a/icons/mob/custom_synthetic/custom-synthetic.dmi and b/icons/mob/custom_synthetic/custom-synthetic.dmi differ diff --git a/icons/mob/ears.dmi b/icons/mob/ears.dmi index 13d5981c458..597029a456c 100644 Binary files a/icons/mob/ears.dmi and b/icons/mob/ears.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 760e82458d8..b4dea0cfa36 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/screen_simplemob.dmi b/icons/mob/screen_simplemob.dmi new file mode 100644 index 00000000000..e3295a84438 Binary files /dev/null and b/icons/mob/screen_simplemob.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 7bcd0607116..f556369cf69 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index 720fafd8847..0b4d8509104 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/fish_items.dmi b/icons/obj/fish_items.dmi index fd8eea36540..76a9486fee6 100644 Binary files a/icons/obj/fish_items.dmi and b/icons/obj/fish_items.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index 6825f6c652d..ff25b77ab45 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/custom.dmi b/icons/obj/food/custom.dmi new file mode 100644 index 00000000000..42d28790790 Binary files /dev/null and b/icons/obj/food/custom.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index 3a0ec216714..487b36d3e97 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/pasta.dmi b/icons/obj/food/pasta.dmi new file mode 100644 index 00000000000..0179c3f5cc7 Binary files /dev/null and b/icons/obj/food/pasta.dmi differ diff --git a/icons/obj/food/pizza.dmi b/icons/obj/food/pizza.dmi new file mode 100644 index 00000000000..c26e792f2a0 Binary files /dev/null and b/icons/obj/food/pizza.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index 288785052cd..e86a39361da 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi index 85d6026617f..fba8ad59431 100644 Binary files a/icons/obj/modular_console.dmi and b/icons/obj/modular_console.dmi differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi index 2daeee0c7a4..d04e68c2041 100644 Binary files a/icons/obj/modular_laptop.dmi and b/icons/obj/modular_laptop.dmi differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi index 2438f375f65..a6e3223a8d0 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index 0a269e0d8b7..ab76789a0f0 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/pipes/disposal.dmi index 707a064dd94..83440fc1b52 100644 Binary files a/icons/obj/pipes/disposal.dmi and b/icons/obj/pipes/disposal.dmi differ diff --git a/icons/obj/playing_cards.dmi b/icons/obj/playing_cards.dmi new file mode 100644 index 00000000000..315e4335979 Binary files /dev/null and b/icons/obj/playing_cards.dmi differ diff --git a/icons/program_icons/smmon_0.gif b/icons/program_icons/smmon_0.gif new file mode 100644 index 00000000000..7b716c4e1c5 Binary files /dev/null and b/icons/program_icons/smmon_0.gif differ diff --git a/icons/program_icons/smmon_1.gif b/icons/program_icons/smmon_1.gif new file mode 100644 index 00000000000..bbe319b820f Binary files /dev/null and b/icons/program_icons/smmon_1.gif differ diff --git a/icons/program_icons/smmon_2.gif b/icons/program_icons/smmon_2.gif new file mode 100644 index 00000000000..9c58edd340e Binary files /dev/null and b/icons/program_icons/smmon_2.gif differ diff --git a/icons/program_icons/smmon_3.gif b/icons/program_icons/smmon_3.gif new file mode 100644 index 00000000000..dc7c8734eed Binary files /dev/null and b/icons/program_icons/smmon_3.gif differ diff --git a/icons/program_icons/smmon_4.gif b/icons/program_icons/smmon_4.gif new file mode 100644 index 00000000000..8a75e6e1184 Binary files /dev/null and b/icons/program_icons/smmon_4.gif differ diff --git a/icons/program_icons/smmon_5.gif b/icons/program_icons/smmon_5.gif new file mode 100644 index 00000000000..59356beda0a Binary files /dev/null and b/icons/program_icons/smmon_5.gif differ diff --git a/icons/program_icons/smmon_6.gif b/icons/program_icons/smmon_6.gif new file mode 100644 index 00000000000..aea2f87921d Binary files /dev/null and b/icons/program_icons/smmon_6.gif differ diff --git a/nano/templates/doppler_array.tmpl b/nano/templates/doppler_array.tmpl new file mode 100644 index 00000000000..d3bb40744b2 --- /dev/null +++ b/nano/templates/doppler_array.tmpl @@ -0,0 +1,25 @@ +

      Logged explosions:

      +{{if data.explosion_data == 0}} +

      No explosions logged this shift.

      +{{else}} +
      + Time logged + Epicenter + Actual size + Theoretical size +
      +
      + {{for data.explosion_data}} +
      + + {{:value.logged_time}} + {{:value.epicenter}} + {{:value.actual_size_message}} + {{:value.theoretical_size_message}} + {{:helper.link("Delete", "trash", {"log_to_delete": value.unique_datum_id})}} + +
      + {{/for}} +
      + {{:helper.link("Print all logs", "print", {"print_logs": 'yes'}, data.printing ? 'disabled' : null)}} +{{/if}} diff --git a/nano/templates/freezer.tmpl b/nano/templates/freezer.tmpl index d21d625f017..582598e05c5 100644 --- a/nano/templates/freezer.tmpl +++ b/nano/templates/freezer.tmpl @@ -36,6 +36,7 @@
      {{:helper.displayBar(data.targetGasTemperature, data.minGasTemperature, data.maxGasTemperature)}}
      + {{:helper.link('Min', null, {'minimum' : 'yes'}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} {{:helper.link('-', null, {'temp' : -100}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} {{:helper.link('-', null, {'temp' : -10}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} {{:helper.link('-', null, {'temp' : -1}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}} @@ -43,6 +44,7 @@ {{:helper.link('+', null, {'temp' : 1}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} {{:helper.link('+', null, {'temp' : 10}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} {{:helper.link('+', null, {'temp' : 100}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}} + {{:helper.link('Max', null, {'maximum' : 'yes'}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}}
    diff --git a/nano/templates/rpd.tmpl b/nano/templates/rpd.tmpl index bd92b91c979..6a9c2ccb517 100644 --- a/nano/templates/rpd.tmpl +++ b/nano/templates/rpd.tmpl @@ -4,101 +4,104 @@ Used In File(s): /code/game/objects/items/weapons/rpd.dm

    Mode:

    {{for data.mainmenu}} - {{:helper.link(String(value.category), String(value.icon), {"mode": Number(value.mode)}, data.mode == Number(value.mode) ? "linkOn" : null)}} + {{:helper.link(value.category, value.icon, {mode: value.mode}, data.mode == value.mode ? "linkOn" : null)}} {{/for}}
    {{if data.mode == 1}}

    Pipe type:

    {{for data.pipemenu}} - {{:helper.link(String(value.pipecategory), null, {"pipetype": Number(value.pipemode)}, data.pipetype == Number(value.pipemode) ? "linkOn" : null)}} + {{:helper.link(value.category, null, {pipe_category: value.pipemode}, data.pipe_category == value.pipemode ? "linkOn" : null)}} {{/for}}

    Available pipes:

    {{for data.pipelist}} - {{if value.category == data.pipetype}} -
    {{:helper.link(String(value.pipename), "arrow-right", {"whatpipe": Number(value.id)}, data.whatpipe == Number(value.id) ? "linkOn" : null)}}
    + {{if value.pipe_type == 1 && value.pipe_category == data.pipe_category}} +
    {{:helper.link(value.pipe_name, "arrow-right", {whatpipe: value.pipe_id}, data.whatpipe == value.pipe_id ? "linkOn" : null)}}
    {{/if}} {{/for}}
    {{for data.pipelist}} + {{if value.pipe_type != 1 || value.pipe_id != data.whatpipe || value.orientations == 1}} + {{continue;}} + {{/if}}
    - {{if value.id == data.whatpipe && value.orientations != 1}} -
    - {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} -
    - {{/if}} - {{if value.id == data.whatpipe && value.orientations != 1 && value.bendy != 1}} +
    + {{:helper.link("Orient automatically", null, {iconrotation: 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
    + {{if value.bendy}}
    - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} +
    - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - -
    - {{/if}} - {{if value.id == data.whatpipe && value.orientations == 4 && value.bendy != 1}} -
    - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} +
    - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - -
    - {{/if}} - {{if value.id == data.whatpipe && value.bendy == 1}} -
    - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} +
    - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
    + {{else}} +
    + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} +
    - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - -
    -
    - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} +
    + {{if value.orientations == 4}} +
    + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} + +
    + {{/if}} {{/if}}
    {{/for}} {{else data.mode == 2}}

    Available pipes:

    - {{for data.dpipelist}} -
    {{:helper.link(String(value.pipename), "arrow-right", {"whatdpipe": Number(value.id)}, data.whatdpipe == Number(value.id) ? "linkOn" : null)}}
    + {{for data.pipelist}} + {{if value.pipe_type == 2}} +
    {{:helper.link(value.pipe_name, "arrow-right", {whatdpipe: value.pipe_id}, data.whatdpipe == value.pipe_id ? "linkOn" : null)}}
    + {{/if}} {{/for}}
    - {{for data.dpipelist}} + {{for data.pipelist}} + {{if value.pipe_type != 2 || value.pipe_id != data.whatdpipe || value.orientations == 1}} + {{continue;}} + {{/if}}
    - {{if value.id == data.whatdpipe && value.orientations != 1}} -
    - {{:helper.link("Orient automatically", null, {"iconrotation": 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
    + {{:helper.link("Orient automatically", null, {iconrotation: 0}, data.iconrotation == 0 ? "linkOn" : null)}} +
    +
    + {{:helper.link("", "arrow-right", {iconrotation: 1}, data.iconrotation == 1 ? "linkOn" : null)}} + +
    +
    + {{:helper.link("", "arrow-right", {iconrotation: 4}, data.iconrotation == 4 ? "linkOn" : null)}} + +
    + {{if value.orientations == 4}} +
    + {{:helper.link("", "arrow-right", {iconrotation: 2}, data.iconrotation == 2 ? "linkOn" : null)}} +
    - {{:helper.link("", "arrow-right", {"iconrotation": 1}, data.iconrotation == 1 ? "linkOn" : null)}} - -
    -
    - {{:helper.link("", "arrow-right", {"iconrotation": 4}, data.iconrotation == 4 ? "linkOn" : null)}} - -
    - {{/if}} - {{if value.id == data.whatdpipe && value.orientations == 4}} -
    - {{:helper.link("", "arrow-right", {"iconrotation": 2}, data.iconrotation == 2 ? "linkOn" : null)}} - -
    -
    - {{:helper.link("", "arrow-right", {"iconrotation": 8}, data.iconrotation == 8 ? "linkOn" : null)}} - + {{:helper.link("", "arrow-right", {iconrotation: 8}, data.iconrotation == 8 ? "linkOn" : null)}} +
    {{/if}}
    @@ -109,4 +112,4 @@ Used In File(s): /code/game/objects/items/weapons/rpd.dm

    Device ready to flip loose pipes...

    {{else data.mode == 5}}

    Device ready to eat loose pipes...

    -{{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/supermatter_monitor.tmpl b/nano/templates/supermatter_monitor.tmpl new file mode 100644 index 00000000000..3bc87984d79 --- /dev/null +++ b/nano/templates/supermatter_monitor.tmpl @@ -0,0 +1,111 @@ +{{if data.active}} + {{:helper.link('Back to Menu', null, {'clear' : 1})}}
    +
    +
    + Core Integrity: +
    +
    + {{:helper.displayBar(data.SM_integrity, 0, 100, (data.SM_integrity == 100) ? 'good' : (data.SM_integrity >= 50) ? 'average' : 'bad')}} {{:data.SM_integrity}}% +
    +
    + Relative EER: +
    +
    + {{if data.SM_power > 300}} + {{:data.SM_power}} MeV/cm3 + {{else data.SM_power > 150}} + {{:data.SM_power}} MeV/cm3 + {{else}} + {{:data.SM_power}} MeV/cm3 + {{/if}} +
    +
    + Temperature: +
    +
    + {{if data.SM_ambienttemp > 5000}} + {{:data.SM_ambienttemp}} K + {{else data.SM_ambienttemp > 4000}} + {{:data.SM_ambienttemp}} K + {{else}} + {{:data.SM_ambienttemp}} K + {{/if}} +
    +
    + Pressure: +
    +
    + {{if data.SM_ambientpressure > 10000}} + {{:data.SM_ambientpressure}} kPa + {{else data.SM_ambientpressure > 5000}} + {{:data.SM_ambientpressure}} kPa + {{else}} + {{:data.SM_ambientpressure}} kPa + {{/if}} +
    +
    +

    +
    + Gas Composition: +
    +
    +
    +
    + O2: +
    +
    + {{:data.SM_gas_O2}} % +
    +
    + CO2: +
    +
    + {{:data.SM_gas_CO2}} % +
    +
    + N2: +
    +
    + {{:data.SM_gas_N2}} % +
    +
    + PL: +
    +
    + {{:data.SM_gas_PL}} % +
    +
    + OTHER: +
    +
    + {{:data.SM_gas_OTHER}} % +
    +
    +
    +
    +{{else}} + {{:helper.link('Refresh', null, {'refresh' : 1})}}
    + {{for data.supermatters}} +
    +
    + Area: +
    +
    + {{:value.area_name}} +
    +
    + Integrity: +
    +
    + {{:value.integrity}} % +
    +
    + Options: +
    +
    + {{:helper.link('View Details', null, {'set' : value.uid})}} +
    +
    + {{/for}} +{{/if}} diff --git a/paradise.dme b/paradise.dme index 7daead01233..70eaa50867a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -45,6 +45,7 @@ #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" #include "code\__DEFINES\pda.dm" +#include "code\__DEFINES\pipes.dm" #include "code\__DEFINES\preferences.dm" #include "code\__DEFINES\process_scheduler.dm" #include "code\__DEFINES\qdel.dm" @@ -101,6 +102,7 @@ #include "code\_globalvars\station.dm" #include "code\_globalvars\unused.dm" #include "code\_globalvars\lists\flavor_misc.dm" +#include "code\_globalvars\lists\fortunes.dm" #include "code\_globalvars\lists\misc.dm" #include "code\_globalvars\lists\mobs.dm" #include "code\_globalvars\lists\names.dm" @@ -230,6 +232,7 @@ #include "code\datums\mixed.dm" #include "code\datums\mutable_appearance.dm" #include "code\datums\periodic_news.dm" +#include "code\datums\pipe_datums.dm" #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" #include "code\datums\ruins.dm" @@ -392,6 +395,7 @@ #include "code\game\world.dm" #include "code\game\area\ai_monitored.dm" #include "code\game\area\areas.dm" +#include "code\game\area\depot-areas.dm" #include "code\game\area\Dynamic areas.dm" #include "code\game\area\Space Station 13 areas.dm" #include "code\game\dna\dna2.dm" @@ -469,8 +473,10 @@ #include "code\game\gamemodes\malfunction\Malf_Modules.dm" #include "code\game\gamemodes\meteor\meteor.dm" #include "code\game\gamemodes\meteor\meteors.dm" +#include "code\game\gamemodes\miniantags\abduction\abductee_objectives.dm" #include "code\game\gamemodes\miniantags\abduction\abduction.dm" #include "code\game\gamemodes\miniantags\abduction\abduction_gear.dm" +#include "code\game\gamemodes\miniantags\abduction\abduction_outfits.dm" #include "code\game\gamemodes\miniantags\abduction\abduction_surgery.dm" #include "code\game\gamemodes\miniantags\abduction\gland.dm" #include "code\game\gamemodes\miniantags\abduction\machinery\camera.dm" @@ -630,6 +636,7 @@ #include "code\game\machinery\computer\communications.dm" #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\crew.dm" +#include "code\game\machinery\computer\depot.dm" #include "code\game\machinery\computer\HolodeckControl.dm" #include "code\game\machinery\computer\honkputer.dm" #include "code\game\machinery\computer\law.dm" @@ -950,6 +957,7 @@ #include "code\game\objects\structures\bedsheet_bin.dm" #include "code\game\objects\structures\coathanger.dm" #include "code\game\objects\structures\curtains.dm" +#include "code\game\objects\structures\depot.dm" #include "code\game\objects\structures\displaycase.dm" #include "code\game\objects\structures\door_assembly.dm" #include "code\game\objects\structures\door_assembly_types.dm" @@ -1010,6 +1018,7 @@ #include "code\game\objects\structures\crates_lockers\closets\secure\bar.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\cargo.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\chaplain.dm" +#include "code\game\objects\structures\crates_lockers\closets\secure\depot.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\engineering.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\freezer.dm" #include "code\game\objects\structures\crates_lockers\closets\secure\guncabinet.dm" @@ -1345,6 +1354,7 @@ #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" +#include "code\modules\events\koi_mirgration.dm" #include "code\modules\events\mass_hallucination.dm" #include "code\modules\events\meaty_gore.dm" #include "code\modules\events\meaty_ops.dm" @@ -1396,12 +1406,24 @@ #include "code\modules\food_and_drinks\drinks\drinks\drinkingglass.dm" #include "code\modules\food_and_drinks\drinks\drinks\mugs.dm" #include "code\modules\food_and_drinks\drinks\drinks\shotglass.dm" -#include "code\modules\food_and_drinks\food\candy.dm" #include "code\modules\food_and_drinks\food\condiment.dm" #include "code\modules\food_and_drinks\food\customizables.dm" -#include "code\modules\food_and_drinks\food\meat.dm" -#include "code\modules\food_and_drinks\food\seafood.dm" #include "code\modules\food_and_drinks\food\snacks.dm" +#include "code\modules\food_and_drinks\food\foods\baked_goods.dm" +#include "code\modules\food_and_drinks\food\foods\bread.dm" +#include "code\modules\food_and_drinks\food\foods\candy.dm" +#include "code\modules\food_and_drinks\food\foods\desserts.dm" +#include "code\modules\food_and_drinks\food\foods\ethnic.dm" +#include "code\modules\food_and_drinks\food\foods\ingredients.dm" +#include "code\modules\food_and_drinks\food\foods\junkfood.dm" +#include "code\modules\food_and_drinks\food\foods\meat.dm" +#include "code\modules\food_and_drinks\food\foods\misc.dm" +#include "code\modules\food_and_drinks\food\foods\pasta.dm" +#include "code\modules\food_and_drinks\food\foods\pizza.dm" +#include "code\modules\food_and_drinks\food\foods\sandwiches.dm" +#include "code\modules\food_and_drinks\food\foods\seafood.dm" +#include "code\modules\food_and_drinks\food\foods\side_dishes.dm" +#include "code\modules\food_and_drinks\food\foods\soups.dm" #include "code\modules\food_and_drinks\kitchen_machinery\candy_maker.dm" #include "code\modules\food_and_drinks\kitchen_machinery\cereal_maker.dm" #include "code\modules\food_and_drinks\kitchen_machinery\cooker.dm" @@ -1424,6 +1446,9 @@ #include "code\modules\food_and_drinks\recipes\recipes_microwave.dm" #include "code\modules\food_and_drinks\recipes\recipes_oven.dm" #include "code\modules\food_and_drinks\recipes\tablecraft\recipes_table.dm" +#include "code\modules\games\52card.dm" +#include "code\modules\games\cards.dm" +#include "code\modules\games\tarot.dm" #include "code\modules\holiday\christmas.dm" #include "code\modules\holiday\holiday.dm" #include "code\modules\hydroponics\biogenerator.dm" @@ -1620,7 +1645,7 @@ #include "code\modules\mob\living\carbon\brain\login.dm" #include "code\modules\mob\living\carbon\brain\MMI.dm" #include "code\modules\mob\living\carbon\brain\MMI_radio.dm" -#include "code\modules\mob\living\carbon\brain\posibrain.dm" +#include "code\modules\mob\living\carbon\brain\robotic_brain.dm" #include "code\modules\mob\living\carbon\brain\say.dm" #include "code\modules\mob\living\carbon\brain\update_status.dm" #include "code\modules\mob\living\carbon\human\appearance.dm" @@ -1646,15 +1671,28 @@ #include "code\modules\mob\living\carbon\human\interactive\functions.dm" #include "code\modules\mob\living\carbon\human\interactive\interactive.dm" #include "code\modules\mob\living\carbon\human\interactive\prefabs.dm" +#include "code\modules\mob\living\carbon\human\species\_species.dm" #include "code\modules\mob\living\carbon\human\species\abductor.dm" -#include "code\modules\mob\living\carbon\human\species\apollo.dm" +#include "code\modules\mob\living\carbon\human\species\diona.dm" +#include "code\modules\mob\living\carbon\human\species\drask.dm" #include "code\modules\mob\living\carbon\human\species\golem.dm" +#include "code\modules\mob\living\carbon\human\species\grey.dm" +#include "code\modules\mob\living\carbon\human\species\human.dm" +#include "code\modules\mob\living\carbon\human\species\kidan.dm" +#include "code\modules\mob\living\carbon\human\species\machine.dm" #include "code\modules\mob\living\carbon\human\species\monkey.dm" +#include "code\modules\mob\living\carbon\human\species\nucleation.dm" #include "code\modules\mob\living\carbon\human\species\plasmaman.dm" #include "code\modules\mob\living\carbon\human\species\shadow.dm" +#include "code\modules\mob\living\carbon\human\species\shadowling.dm" #include "code\modules\mob\living\carbon\human\species\skeleton.dm" -#include "code\modules\mob\living\carbon\human\species\species.dm" -#include "code\modules\mob\living\carbon\human\species\station.dm" +#include "code\modules\mob\living\carbon\human\species\skrell.dm" +#include "code\modules\mob\living\carbon\human\species\slime.dm" +#include "code\modules\mob\living\carbon\human\species\tajaran.dm" +#include "code\modules\mob\living\carbon\human\species\unathi.dm" +#include "code\modules\mob\living\carbon\human\species\vox.dm" +#include "code\modules\mob\living\carbon\human\species\vulpkanin.dm" +#include "code\modules\mob\living\carbon\human\species\wryn.dm" #include "code\modules\mob\living\carbon\slime\death.dm" #include "code\modules\mob\living\carbon\slime\emote.dm" #include "code\modules\mob\living\carbon\slime\examine.dm" @@ -1745,6 +1783,7 @@ #include "code\modules\mob\living\simple_animal\bot\medbot.dm" #include "code\modules\mob\living\simple_animal\bot\mulebot.dm" #include "code\modules\mob\living\simple_animal\bot\secbot.dm" +#include "code\modules\mob\living\simple_animal\bot\syndicate.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" @@ -1853,6 +1892,7 @@ #include "code\modules\modular_computers\file_system\programs\command\comms.dm" #include "code\modules\modular_computers\file_system\programs\engineering\alarm.dm" #include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\sm_monitor.dm" #include "code\modules\modular_computers\file_system\programs\generic\configurator.dm" #include "code\modules\modular_computers\file_system\programs\generic\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm" @@ -2189,6 +2229,7 @@ #include "code\modules\surgery\organs\kidneys.dm" #include "code\modules\surgery\organs\liver.dm" #include "code\modules\surgery\organs\lungs.dm" +#include "code\modules\surgery\organs\mmi_holder.dm" #include "code\modules\surgery\organs\organ.dm" #include "code\modules\surgery\organs\organ_external.dm" #include "code\modules\surgery\organs\organ_icon.dm" diff --git a/sound/creatures/bee.ogg b/sound/creatures/bee.ogg new file mode 100644 index 00000000000..ea8dcc2b369 Binary files /dev/null and b/sound/creatures/bee.ogg differ diff --git a/sound/goonstation/items/hypo.ogg b/sound/goonstation/items/hypo.ogg new file mode 100644 index 00000000000..8525a1b43c7 Binary files /dev/null and b/sound/goonstation/items/hypo.ogg differ diff --git a/sound/machines/engine_alert2.ogg b/sound/machines/engine_alert2.ogg new file mode 100644 index 00000000000..83f693617a7 Binary files /dev/null and b/sound/machines/engine_alert2.ogg differ