diff --git a/.travis.yml b/.travis.yml index 27dae76378e..af2cfc45cc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ git: env: global: - BYOND_MAJOR="510" - - BYOND_MINOR="1336" + - BYOND_MINOR="1346" matrix: - DM_MAPFILE="cyberiad" - DM_MAPFILE="metastation" diff --git a/README.md b/README.md index ff8ab8f6d80..6f8195ab8ea 100644 --- a/README.md +++ b/README.md @@ -120,8 +120,11 @@ including addons and modifications you have made. See [this](https://www.gnu.org/licenses/why-affero-gpl.html) for more information. -Any files located in the `Paradise/icons/goonstation` and `Paradise/sound/goonstation` -folders, and any of their subdirectories, are licensed under the +Any files located in the +`Paradise/goon`, +`Paradise/icons/goonstation`, or +`Paradise/sound/goonstation` +directories, or any subdirectories of mentioned directories are licensed under the Creative Commons 3.0 BY-NC-SA license (https://creativecommons.org/licenses/by-nc-sa/3.0) diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm index b50efa38848..dffbfccbf5a 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm @@ -111,9 +111,9 @@ "acg" = (/turf/simulated/wall/r_wall,/area/security/prison) "ach" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/prison) "aci" = (/obj/machinery/seed_extractor,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) -"acj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/flora/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "ack" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/security/prison) -"acl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/flora/kirbyplants{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/twohanded/required/kirbyplants{layer = 4.1},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acm" = (/obj/machinery/biogenerator,/obj/machinery/light/small{dir = 4},/obj/machinery/camera{c_tag = "Prison Hydroponics"; network = list("SS13","Prison")},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acn" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/prison) "aco" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/item/seeds/ambrosiavulgarisseed,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) @@ -150,7 +150,7 @@ "acT" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{tag = "icon-warndark (NORTHEAST)"; icon_state = "warndark"; dir = 5},/area/prison/solitary{name = "Prisoner Education Chamber"}) "acU" = (/obj/item/weapon/soap/nanotrasen,/obj/item/weapon/bikehorn/rubberducky,/obj/machinery/shower{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/prison) "acV" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/security/prison) -"acW" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/flora/kirbyplants{tag = "icon-plant-13"; icon_state = "plant-13"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) +"acW" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-13"; icon_state = "plant-13"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acX" = (/obj/structure/table,/obj/item/weapon/folder,/obj/item/weapon/paper/hydroponics,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/weapon/pen,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acY" = (/obj/structure/table,/obj/machinery/computer/library/public,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) "acZ" = (/obj/machinery/computer/arcade,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison) @@ -404,7 +404,7 @@ "ahN" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/sign/pods{pixel_y = 30},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "ahO" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/flasher_button{id = "insaneflash"; pixel_y = 26},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) "ahP" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison) -"ahQ" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'WARNING: Criminally Insane Inmates', describing the possible hazards of those contained within."; name = "WARNING: Criminally Insane Inmates"; pixel_y = 32},/turf/simulated/floor/plasteel,/area/security/prison) +"ahQ" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'WARNING: Criminally Insane Inmates', describing the possible hazards of those contained within."; name = "WARNING: Criminally Insane Inmates"; pixel_y = 32},/turf/simulated/floor/plasteel,/area/security/prison) "ahR" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/prison) "ahS" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/light/small{dir = 1},/obj/item/weapon/storage/secure/safe{name = "armory safe A"; pixel_x = 6; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) "ahT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) @@ -435,7 +435,7 @@ "ais" = (/obj/item/weapon/storage/toolbox/syndicate,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "ait" = (/obj/item/weapon/skeleton/r_arm,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "aiu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/airlock/external{name = "Solar Maintenance"; req_access = null; req_access_txt = "10; 13"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"aiv" = (/obj/structure/flora/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/security/prison) +"aiv" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/security/prison) "aiw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/prison) "aix" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/prison) "aiy" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/security/prison) @@ -455,7 +455,7 @@ "aiM" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/security/prison) "aiN" = (/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/obj/structure/reagent_dispensers/peppertank{pixel_x = 0; pixel_y = 29},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden) "aiO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) -"aiP" = (/obj/structure/rack,/obj/item/weapon/gun/energy/advtaser{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/advtaser,/obj/item/weapon/gun/energy/advtaser{pixel_x = 3; pixel_y = -3},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden) +"aiP" = (/obj/structure/rack,/obj/item/weapon/gun/energy/gun/advtaser{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/gun/advtaser,/obj/item/weapon/gun/energy/gun/advtaser{pixel_x = 3; pixel_y = -3},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/security/warden) "aiQ" = (/obj/machinery/syndicatebomb/training,/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden) "aiR" = (/obj/structure/rack,/obj/item/weapon/gun/energy/laser{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/laser,/obj/item/weapon/gun/energy/laser{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plasteel{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/security/warden) "aiS" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden) @@ -583,7 +583,7 @@ "alk" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness{name = "\improper Recreation Area"}) "all" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/shuttle/vox) "alm" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"aln" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"aln" = (/obj/structure/rack,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "alo" = (/obj/machinery/door/poddoor{id_tag = "trash"; name = "disposal bay door"},/turf/simulated/floor/plating,/area/maintenance/disposal) "alp" = (/obj/machinery/mass_driver{dir = 8; id_tag = "trash"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/disposal) "alq" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "garbage"; name = "disposal coveyor"},/turf/simulated/floor/plating,/area/maintenance/disposal) @@ -1326,7 +1326,7 @@ "azz" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "azA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{tag = "icon-platingdmg2"; icon_state = "platingdmg2"},/area/maintenance/starboard) "azB" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/maintenance/starboard) -"azC" = (/obj/structure/flora/kirbyplants,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) +"azC" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "azD" = (/obj/structure/spacepoddoor,/obj/machinery/door/poddoor/multi_tile/three_tile_ver{id_tag = "mechpodbay"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engine/mechanic_workshop) "azE" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "azF" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/maintenance/starboard) @@ -1648,7 +1648,7 @@ "aFJ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11},/turf/simulated/floor/plasteel,/area/crew_quarters/sleep) "aFK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/sign/pods{pixel_x = 30; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralcorner"},/area/crew_quarters/sleep) "aFL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboard) -"aFM" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/flora/kirbyplants{icon_state = "plant-20"; layer = 4.1; pixel_y = 3; tag = "icon-plant-20"},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering) +"aFM" = (/obj/effect/decal/cleanable/cobweb,/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-20"; layer = 4.1; pixel_y = 3; tag = "icon-plant-20"},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering) "aFN" = (/obj/item/clothing/head/helmet/space/rig/engineering,/obj/item/clothing/suit/space/rig/engineering,/obj/item/clothing/mask/breath,/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering) "aFO" = (/obj/structure/dispenser,/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering) "aFP" = (/obj/machinery/camera{c_tag = "Engineering - Storage"; dir = 2; network = list("SS13")},/obj/item/clothing/mask/breath,/obj/item/clothing/suit/space/rig/engineering,/obj/item/clothing/head/helmet/space/rig/engineering,/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering) @@ -1679,7 +1679,7 @@ "aGo" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 6},/area/security/nuke_storage) "aGp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "vault"},/area/security/nuke_storage) "aGq" = (/obj/machinery/camera/motion{c_tag = "Vault"; dir = 1; network = list("MiniSat")},/obj/machinery/light,/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 10},/area/security/nuke_storage) -"aGr" = (/obj/structure/safe,/obj/item/weapon/storage/secure/briefcase{contents = newlist(/obj/item/clothing/suit/armor/vest,/obj/item/weapon/gun/projectile/automatic/pistol,/obj/item/weapon/suppressor,/obj/item/clothing/mask/balaclava,/obj/item/bodybag,/obj/item/weapon/soap/nanotrasen)},/obj/item/weapon/storage/backpack/duffel{contents = newlist(/obj/item/clothing/under/lawyer,/obj/item/clothing/accessory/waistcoat,/obj/item/clothing/shoes/laceup,/obj/item/clothing/gloves/color/black,/obj/item/clothing/glasses/sunglasses,/obj/item/clothing/head/fedora); desc = "A large dufflebag for holding extra things. There is a NanoTrasen logo on the back."; icon_state = "duffle-syndieammo"; item_state = "duffle-syndieammo"},/obj/item/weapon/card/id/silver{access = list(12); assignment = "Reaper"; name = "Thirteen's ID Card (Reaper)"; registered_name = "Thirteen"},/obj/item/weapon/lazarus_injector,/obj/item/weapon/gun/energy/advtaser,/obj/item/weapon/gun/projectile/revolver/russian,/obj/item/ammo_box/a357,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/book{desc = "An undeniably handy book."; icon_state = "bookknock"; name = "A Simpleton's Guide to Safe-cracking with Stethoscopes"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 4},/area/security/nuke_storage) +"aGr" = (/obj/structure/safe,/obj/item/weapon/storage/secure/briefcase{contents = newlist(/obj/item/clothing/suit/armor/vest,/obj/item/weapon/gun/projectile/automatic/pistol,/obj/item/weapon/suppressor,/obj/item/clothing/mask/balaclava,/obj/item/bodybag,/obj/item/weapon/soap/nanotrasen)},/obj/item/weapon/storage/backpack/duffel{contents = newlist(/obj/item/clothing/under/lawyer,/obj/item/clothing/accessory/waistcoat,/obj/item/clothing/shoes/laceup,/obj/item/clothing/gloves/color/black,/obj/item/clothing/glasses/sunglasses,/obj/item/clothing/head/fedora); desc = "A large dufflebag for holding extra things. There is a NanoTrasen logo on the back."; icon_state = "duffle-syndieammo"; item_state = "duffle-syndieammo"},/obj/item/weapon/card/id/silver{access = list(12); assignment = "Reaper"; name = "Thirteen's ID Card (Reaper)"; registered_name = "Thirteen"},/obj/item/weapon/lazarus_injector,/obj/item/weapon/gun/energy/gun/advtaser,/obj/item/weapon/gun/projectile/revolver/russian,/obj/item/ammo_box/a357,/obj/item/clothing/accessory/stethoscope,/obj/item/weapon/book{desc = "An undeniably handy book."; icon_state = "bookknock"; name = "A Simpleton's Guide to Safe-cracking with Stethoscopes"},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 4},/area/security/nuke_storage) "aGs" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1; layer = 2.9},/turf/simulated/shuttle/plating,/area/shuttle/siberia) "aGt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Labor Camp Shuttle Airlock"; req_access_txt = "0"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/primary/fore) "aGu" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/door/poddoor/preopen{id_tag = "Secure Gate"; name = "brig shutters"},/turf/simulated/floor/plating,/area/security/brig) @@ -1955,9 +1955,9 @@ "aLE" = (/obj/structure/table,/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 21},/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plasteel,/area/construction) "aLF" = (/obj/structure/closet/toolcloset,/obj/machinery/light_construct{dir = 1},/turf/simulated/floor/plasteel,/area/construction) "aLG" = (/obj/structure/closet/toolcloset,/turf/simulated/floor/plasteel,/area/construction) -"aLH" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/supply) +"aLH" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/supply) "aLI" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/supply) -"aLJ" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/supply) +"aLJ" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/supply) "aLK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/quartermaster/miningdock{name = "\improper Mining Office"}) "aLL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/mining{name = "Mining Office"; req_access_txt = "48"},/turf/simulated/floor/plasteel,/area/quartermaster/miningdock{name = "\improper Mining Office"}) "aLM" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/quartermaster/storage) @@ -2058,7 +2058,7 @@ "aND" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/requests_console{department = "Law office"; pixel_x = 0; pixel_y = 32},/obj/machinery/newscaster{pixel_x = -31; pixel_y = 0},/turf/simulated/floor/wood,/area/lawoffice) "aNE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5; level = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "aNF" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/briefcase{pixel_x = -3; pixel_y = 2},/obj/item/weapon/storage/secure/briefcase{pixel_x = 2; pixel_y = -2},/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/wood,/area/lawoffice) -"aNG" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "Law Office APC"; pixel_y = 24},/obj/structure/flora/kirbyplants{icon_state = "plant-21"; layer = 4.1; tag = "icon-plant-21"},/turf/simulated/floor/wood,/area/lawoffice) +"aNG" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "Law Office APC"; pixel_y = 24},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-21"; layer = 4.1; tag = "icon-plant-21"},/turf/simulated/floor/wood,/area/lawoffice) "aNH" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/lawoffice) "aNI" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/fore) "aNJ" = (/obj/structure/toilet{pixel_y = 8},/obj/machinery/light/small{dir = 8},/obj/machinery/newscaster{pixel_x = 0; pixel_y = -32},/obj/effect/landmark{name = "blobstart"},/obj/machinery/door_control{id = "Toilet1"; name = "Lock Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet{name = "\improper Restrooms"}) @@ -2191,7 +2191,7 @@ "aQg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "aQh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/porta_turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aQi" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/flasher{pixel_x = 0; pixel_y = 24; id = "AI"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) -"aQj" = (/obj/structure/sign/kiddieplaque{pixel_y = 32},/obj/structure/table,/obj/machinery/camera/motion{c_tag = "AI Upload Chamber - Fore"; network = list("SS13","RD","AIUpload")},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) +"aQj" = (/obj/structure/sign/kiddieplaque{pixel_y = 32},/obj/structure/table,/obj/machinery/camera/motion{c_tag = "AI Upload Chamber - Fore"; network = list("SS13","RD","AIUpload")},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aQk" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aQl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/porta_turret,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai_upload) "aQm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) @@ -2475,7 +2475,7 @@ "aVE" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aVF" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "aVG" = (/obj/machinery/vending/coffee,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) -"aVH" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "plant-03"; layer = 4.1; tag = "icon-plant-03"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) +"aVH" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-03"; layer = 4.1; tag = "icon-plant-03"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aVI" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aVJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) "aVK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "neutralcorner"},/area/crew_quarters/locker) @@ -2665,10 +2665,10 @@ "aZm" = (/obj/structure/grille,/obj/structure/window/reinforced/tinted{dir = 5; health = 120; icon_state = "twindow"; reinf = 0},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "aZn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Arrivals Expansion Area"; req_access_txt = "32"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "aZo" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) -"aZp" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/supply) +"aZp" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/supply) "aZq" = (/turf/simulated/shuttle/wall{icon_state = "swall15"; dir = 2},/area/shuttle/supply) "aZr" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/turf/simulated/shuttle/plating,/area/shuttle/supply) -"aZs" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/supply) +"aZs" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/shuttle/supply) "aZt" = (/turf/simulated/wall,/area/quartermaster/storage) "aZu" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Cargo Bay - Port"; dir = 4; network = list("SS13")},/obj/machinery/conveyor{dir = 2; id = "QMLoad"; movedir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "aZv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/quartermaster/storage) @@ -2728,7 +2728,7 @@ "bax" = (/obj/item/weapon/wrench,/turf/simulated/floor/plating/airless,/area/engine/engineering) "bay" = (/obj/machinery/camera/emp_proof{c_tag = "Aft Arm - Far"; dir = 8; network = list("Singulo")},/turf/simulated/floor/plating/airless,/area/engine/engineering) "baz" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) -"baA" = (/obj/structure/flora/kirbyplants{icon_state = "plant-13"; layer = 4.1; tag = "icon-plant-13"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"baA" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-13"; layer = 4.1; tag = "icon-plant-13"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "baB" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "baC" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "baD" = (/obj/structure/stool/bed/chair,/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 21},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -2766,7 +2766,7 @@ "bbj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload_foyer) "bbk" = (/obj/machinery/door/airlock/highsecurity{name = "Secure Network Access"; req_access_txt = "19"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/turret_protected/ai_upload_foyer) "bbl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload_foyer) -"bbm" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/flora/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 9},/area/hallway/primary/central) +"bbm" = (/obj/machinery/alarm{pixel_y = 23},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 9},/area/hallway/primary/central) "bbn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/primary/central) "bbo" = (/obj/structure/sign/double/map/left{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/primary/central) "bbp" = (/obj/structure/sign/double/map/right{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = 32},/obj/machinery/camera{c_tag = "Central Primary Hallway - Fore"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 1},/area/hallway/primary/central) @@ -2776,7 +2776,7 @@ "bbt" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "redcorner"; dir = 4},/area/hallway/primary/central) "bbu" = (/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = 21},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/primary/central) "bbv" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 1},/area/hallway/primary/central) -"bbw" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "neutral"},/area/hallway/primary/central) +"bbw" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/turf/simulated/floor/plasteel{dir = 5; icon_state = "neutral"},/area/hallway/primary/central) "bbx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/centcom{name = "Courtroom"; opacity = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/crew_quarters/courtroom) "bby" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Crew Quarters Access"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "bbz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Crew Quarters Access"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) @@ -2904,7 +2904,7 @@ "bdR" = (/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/turf/simulated/floor/plating,/area/hallway/secondary/entry{name = "Arrivals"}) "bdS" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bdT" = (/turf/simulated/floor/plasteel{dir = 6; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) -"bdU" = (/obj/structure/flora/kirbyplants{icon_state = "plant-05"; layer = 4.1; tag = "icon-plant-05"},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"bdU" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-05"; layer = 4.1; tag = "icon-plant-05"},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bdV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bdW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (NORTH)"; icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry{name = "Arrivals"}) "bdX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -3059,7 +3059,7 @@ "bgQ" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "bgR" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/wall/r_wall,/area/turret_protected/ai) "bgS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"bgT" = (/obj/structure/table,/obj/structure/flora/kirbyplants{icon_state = "plant-09"; name = "Photosynthetic Potted plant"; pixel_y = 10; tag = "icon-plant-09"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) +"bgT" = (/obj/structure/table,/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-09"; name = "Photosynthetic Potted plant"; pixel_y = 10; tag = "icon-plant-09"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "bgU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/space) "bgV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bgW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -3131,12 +3131,12 @@ "bik" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/ai_slipper{icon_state = "motion0"},/obj/machinery/door/window{dir = 8; icon_state = "left"; name = "Tertiary AI Core Access"; pixel_x = 0; req_access_txt = "16"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bil" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/ai) "bim" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 8},/obj/machinery/camera{c_tag = "MiniSat Exterior Starboard-Fore"; dir = 4; network = list("MiniSat")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/construction/hallway{name = "\improper MiniSat Exterior"}) -"bin" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/shuttle/arrival/station) +"bin" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/arrival/station) "bio" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/arrival/station) "bip" = (/obj/machinery/door/airlock/shuttle{name = "Arrivals Shuttle Airlock"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "biq" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/shuttle/arrival/station) "bir" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"; dir = 2},/area/shuttle/arrival/station) -"bis" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/shuttle/arrival/station) +"bis" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/arrival/station) "bit" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) "biu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/security/checkpoint2{name = "Customs"}) "biv" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11},/obj/structure/table/reinforced,/obj/item/weapon/book/manual/security_space_law{pixel_x = -3; pixel_y = 5},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/checkpoint2{name = "Customs"}) @@ -3600,7 +3600,7 @@ "brl" = (/obj/machinery/power/port_gen/pacman,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 31},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "brm" = (/obj/machinery/computer/security/telescreen{dir = 2; name = "MiniSat Camera Monitor"; network = list("MiniSat","tcomm"); pixel_x = 0; pixel_y = 29},/obj/machinery/computer/station_alert,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "brn" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 1; name = "Auxiliary MiniSat Distribution Port"},/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/ai_status_display{pixel_x = 0; pixel_y = 31},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) -"bro" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/shuttle/arrival/station) +"bro" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/arrival/station) "brp" = (/obj/structure/closet/emcloset,/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "brq" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "brr" = (/obj/structure/sign/double/map/left{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; pixel_y = -32},/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) @@ -3699,7 +3699,7 @@ "btg" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "bth" = (/obj/machinery/door/airlock/shuttle{name = "Arrivals Shuttle Airlock"},/turf/simulated/shuttle/plating,/area/shuttle/arrival/station) "bti" = (/turf/simulated/shuttle/wall{tag = "icon-swall13"; icon_state = "swall13"; dir = 2},/area/shuttle/arrival/station) -"btj" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/shuttle/arrival/station) +"btj" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/shuttle/arrival/station) "btk" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/machinery/camera{c_tag = "Arrivals - Station Entrance"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "btl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/hallway/secondary/entry{name = "Arrivals"}) "btm" = (/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -4026,10 +4026,10 @@ "bzv" = (/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bzw" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bzx" = (/turf/simulated/floor/plasteel{dir = 5; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) -"bzy" = (/obj/structure/flora/kirbyplants{icon_state = "plant-18"; layer = 4.1; tag = "icon-plant-18"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"bzy" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-18"; layer = 4.1; tag = "icon-plant-18"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bzz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bzA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry{name = "Arrivals"}) -"bzB" = (/obj/structure/flora/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/primary/port) +"bzB" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/primary/port) "bzC" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 1},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/primary/port) "bzD" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/camera{c_tag = "Port Primary Hallway - Port"; dir = 4; network = list("SS13")},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/hallway/primary/port) "bzE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "neutral"; dir = 8},/area/hallway/primary/port) @@ -4121,7 +4121,7 @@ "bBm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/rack,/obj/item/weapon/crowbar/red,/obj/item/weapon/wrench,/obj/item/clothing/head/welding,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "bBn" = (/obj/structure/rack,/obj/item/weapon/storage/toolbox/electrical{pixel_x = -3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 3; pixel_y = -3},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) "bBo" = (/obj/machinery/recharge_station,/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/tcomeast{name = "\improper MiniSat East Wing"}) -"bBp" = (/obj/structure/flora/kirbyplants{icon_state = "plant-20"; layer = 4.1; tag = "icon-plant-20"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"bBp" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-20"; layer = 4.1; tag = "icon-plant-20"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bBq" = (/obj/structure/stool/bed/chair,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bBr" = (/obj/structure/stool/bed/chair,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bBs" = (/turf/simulated/floor/plasteel{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -4441,7 +4441,7 @@ "bHu" = (/obj/structure/stool/bed/chair/comfy/black,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/wood,/area/library) "bHv" = (/obj/machinery/vending/coffee,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/wood,/area/library) "bHw" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/wood,/area/library) -"bHx" = (/obj/structure/flora/kirbyplants{tag = "icon-plant-22"; icon_state = "plant-22"},/turf/simulated/floor/wood,/area/library) +"bHx" = (/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-22"; icon_state = "plant-22"},/turf/simulated/floor/wood,/area/library) "bHy" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bHz" = (/obj/machinery/door/poddoor/shutters/preopen{id_tag = "hopqueue"; name = "HoP Queue Shutters"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "loadingarea"; tag = "loading"},/area/bridge/meeting_room{name = "\improper Command Hallway"}) "bHA" = (/obj/effect/spawner/window/reinforced{useFull = 1; tag = "fullReinWin"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/bridge/meeting_room{name = "\improper Command Hallway"}) @@ -4496,7 +4496,7 @@ "bIx" = (/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) "bIy" = (/obj/machinery/microwave{pixel_x = 0; pixel_y = 4},/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bIz" = (/obj/machinery/light/small,/obj/item/weapon/storage/box/donkpockets,/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) -"bIA" = (/obj/structure/flora/kirbyplants{tag = "icon-plant-21"; icon_state = "plant-21"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) +"bIA" = (/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-21"; icon_state = "plant-21"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bIB" = (/obj/structure/filingcabinet{pixel_x = 3},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bIC" = (/obj/machinery/light/small,/obj/item/weapon/folder,/obj/item/weapon/folder,/obj/machinery/camera{c_tag = "Telecoms - Control Room"; dir = 1; network = list("SS13","tcomm")},/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) "bID" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Telecoms Admin"; departmentType = 5; name = "Telecoms RC"; pixel_x = 0; pixel_y = -30},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/paper_bin{pixel_x = -1; pixel_y = 6},/obj/structure/table/woodentable,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/tcommsat/computer{name = "\improper Telecoms Control Room"}) @@ -4814,12 +4814,12 @@ "bOD" = (/obj/item/stack/sheet/rglass{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/rods{amount = 50},/obj/item/device/flashlight,/obj/structure/closet/crate,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/teleporter{name = "\improper Teleporter Room"}) "bOE" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/teleporter{name = "\improper Teleporter Room"}) "bOF" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/closet/crate,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/teleporter{name = "\improper Teleporter Room"}) -"bOG" = (/obj/machinery/light{dir = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/blueshield) +"bOG" = (/obj/machinery/light{dir = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/blueshield) "bOH" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/blueshield) "bOI" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/blueshield) "bOJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/wood,/area/blueshield) "bOK" = (/obj/machinery/light{dir = 1},/obj/machinery/power/apc{dir = 4; name = "Blueshield Office APC"; pixel_x = 24; pixel_y = -3},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/blueshield) -"bOL" = (/obj/machinery/light{dir = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/ntrep) +"bOL" = (/obj/machinery/light{dir = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/ntrep) "bOM" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/ntrep) "bON" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/ntrep) "bOO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/wood,/area/ntrep) @@ -4958,7 +4958,7 @@ "bRr" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/telecomms/processor/preset_four,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/server) "bRs" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/telecomms/bus/preset_four,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/server) "bRt" = (/obj/machinery/blackbox_recorder,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/server) -"bRu" = (/obj/structure/flora/kirbyplants{icon_state = "plant-06"; level = 4.1; tag = "icon-plant-06"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) +"bRu" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-06"; level = 4.1; tag = "icon-plant-06"},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bRv" = (/obj/structure/stool/bed/chair,/obj/effect/landmark/start{name = "Civilian"},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bRw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) "bRx" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry{name = "Arrivals"}) @@ -5054,7 +5054,7 @@ "bTj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "bTk" = (/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "bTl" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/item/weapon/book/manual/security_space_law,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) -"bTm" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/sign/double/map/right{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = -32},/obj/structure/flora/kirbyplants{icon_state = "plant-03"; layer = 4.1; tag = "icon-plant-03"},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 6},/area/hallway/secondary/entry{name = "Arrivals"}) +"bTm" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/sign/double/map/right{desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-right-MS"; pixel_y = -32},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-03"; layer = 4.1; tag = "icon-plant-03"},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 6},/area/hallway/secondary/entry{name = "Arrivals"}) "bTn" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/wood,/area/security/vacantoffice) "bTo" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/turf/simulated/floor/wood,/area/security/vacantoffice) "bTp" = (/obj/structure/mirror{pixel_x = -28},/obj/item/weapon/lipstick/black,/obj/item/weapon/lipstick/jade{pixel_x = 2; pixel_y = 2},/obj/item/weapon/lipstick/purple{pixel_x = -2; pixel_y = -2},/obj/structure/table,/turf/simulated/floor/plating,/area/maintenance/fpmaint2{name = "Port Maintenance"}) @@ -5609,7 +5609,7 @@ "cdS" = (/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/maintenance/fpmaint2{name = "Port Maintenance"}) "cdT" = (/turf/simulated/wall,/area/medical/medbay2{name = "Medbay Storage"}) "cdU" = (/turf/simulated/wall,/area/security/checkpoint/medical) -"cdV" = (/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central) +"cdV" = (/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "applebush"; layer = 4.1; tag = "icon-applebush"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central) "cdW" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central) "cdX" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central) "cdY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central) @@ -5622,7 +5622,7 @@ "cef" = (/obj/machinery/camera{c_tag = "Central Primary Hallway - Aft-Starboard"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/central) "ceg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/central) "ceh" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/central) -"cei" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/flora/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/central) +"cei" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "purplecorner"},/area/hallway/primary/central) "cej" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/obj/machinery/newscaster{pixel_y = -29},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/hallway/primary/central) "cek" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;7;35;8;47"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "cel" = (/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/hallway/primary/central) @@ -5971,7 +5971,7 @@ "ckQ" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteblue"},/area/medical/medbay{name = "Medbay Central"}) "ckR" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteyellow"},/area/medical/medbay{name = "Medbay Central"}) "ckS" = (/obj/effect/landmark/start{name = "Paramedic"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteyellow"},/area/medical/medbay{name = "Medbay Central"}) -"ckT" = (/obj/structure/flora/kirbyplants{tag = "icon-plant-11"; icon_state = "plant-11"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteyellow"},/area/medical/medbay{name = "Medbay Central"}) +"ckT" = (/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-11"; icon_state = "plant-11"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whiteyellow"},/area/medical/medbay{name = "Medbay Central"}) "ckU" = (/obj/effect/spawner/window{useFull = 1; tag = "fullWin"},/turf/simulated/floor/plating,/area/medical/medbay{name = "Medbay Central"}) "ckV" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/hallway/primary/aft) "ckW" = (/obj/machinery/autolathe{icon_state = "autolathe"; name = "public autolathe"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) @@ -5980,7 +5980,7 @@ "ckZ" = (/obj/structure/table,/obj/item/weapon/stock_parts/cell/potato,/obj/machinery/light,/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "cla" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "clb" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) -"clc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -30},/obj/structure/flora/kirbyplants{layer = 4.1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) +"clc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -30},/obj/item/weapon/twohanded/required/kirbyplants{layer = 4.1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "cld" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "cle" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "clf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/checkpoint/science{name = "Security Post - Research Division"}) @@ -6016,7 +6016,7 @@ "clJ" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/external{req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "clK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{tag = "icon-warnplate (WEST)"; icon_state = "warnplate"; dir = 8},/area/maintenance/aft{name = "Aft Maintenance"}) "clL" = (/obj/item/trash/pistachios,/obj/structure/closet,/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"clM" = (/obj/structure/flora/kirbyplants{tag = "icon-plant-25"; icon_state = "plant-25"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) +"clM" = (/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-25"; icon_state = "plant-25"},/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "clN" = (/obj/item/weapon/storage/box,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "clO" = (/obj/structure/closet/crate,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "clP" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) @@ -6468,7 +6468,7 @@ "cut" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) "cuu" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurple"},/area/medical/research{name = "Research Division"}) "cuv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) -"cuw" = (/obj/structure/flora/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) +"cuw" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-10"; layer = 4.1; tag = "icon-plant-10"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "whitepurplecorner"},/area/medical/research{name = "Research Division"}) "cux" = (/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitepurplecorner"},/area/toxins/explab) "cuy" = (/obj/structure/stool/bed/chair/office/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) "cuz" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/white,/obj/item/weapon/folder/white,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab) @@ -6904,7 +6904,7 @@ "cCN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Research Division Hallway - Mech Bay"; dir = 4; network = list("SS13","RD")},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "cCO" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "cCP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitebluecorner"},/area/medical/research{name = "Research Division"}) -"cCQ" = (/obj/machinery/power/apc{dir = 2; name = "RD Office APC"; pixel_x = 0; pixel_y = -27},/obj/structure/cable/yellow,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/structure/flora/kirbyplants/dead,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) +"cCQ" = (/obj/machinery/power/apc{dir = 2; name = "RD Office APC"; pixel_x = 0; pixel_y = -27},/obj/structure/cable/yellow,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants/dead,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cCR" = (/obj/machinery/hologram/holopad,/obj/machinery/light,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) "cCS" = (/obj/structure/table,/obj/item/weapon/retractor,/obj/machinery/light{dir = 4},/obj/structure/window/reinforced/polarized{tag = "icon-rwindow (NORTH)"; icon_state = "rwindow"; dir = 1},/obj/item/weapon/hemostat,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) "cCT" = (/obj/structure/closet/secure_closet/RD,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/hor) @@ -7380,7 +7380,7 @@ "cLV" = (/obj/structure/sign/securearea{pixel_x = 0; pixel_y = 32},/obj/machinery/shower{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/medical/virology) "cLW" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/iv_drip{density = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/medbay3{name = "Medbay Aft"}) "cLX" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = 1},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreen"},/area/medical/medbay3{name = "Medbay Aft"}) -"cLY" = (/obj/structure/flora/kirbyplants{icon_state = "plant-21"; layer = 4.1; pixel_x = -3; pixel_y = 3; tag = "icon-plant-21"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreencorner"},/area/medical/medbay3{name = "Medbay Aft"}) +"cLY" = (/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-21"; layer = 4.1; pixel_x = -3; pixel_y = 3; tag = "icon-plant-21"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreencorner"},/area/medical/medbay3{name = "Medbay Aft"}) "cLZ" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) "cMa" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay3{name = "Medbay Aft"}) "cMb" = (/obj/structure/table,/obj/item/clothing/gloves/color/latex,/obj/item/clothing/mask/surgical,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery) @@ -7703,14 +7703,14 @@ "cSg" = (/obj/machinery/door/morgue{name = "Relic Closet"; req_access_txt = "22"},/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) "cSh" = (/obj/structure/table/woodentable,/obj/item/weapon/spellbook/oneuse/smoke{name = "mysterious old book of "},/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{name = "flask of holy water"; pixel_x = -2; pixel_y = 2},/obj/item/weapon/nullrod{pixel_x = 4},/obj/item/organ/internal/heart,/obj/item/device/soulstone,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/chapel/office) "cSi" = (/obj/machinery/door/airlock/maintenance{name = "Chapel Maintenance Access "; req_access_txt = "0"; req_one_access_txt = "12;27"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) -"cSj" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Departure Lounge - Port Fore"; dir = 4; network = list("SS13")},/obj/structure/flora/kirbyplants{icon_state = "plant-24"; layer = 4.1; tag = "icon-plant-24"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cSj" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/camera{c_tag = "Departure Lounge - Port Fore"; dir = 4; network = list("SS13")},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-24"; layer = 4.1; tag = "icon-plant-24"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSl" = (/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 2},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSm" = (/turf/simulated/floor/plasteel{icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSn" = (/turf/simulated/floor/plasteel{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cSq" = (/obj/machinery/light{dir = 4},/obj/machinery/camera{c_tag = "Departure Lounge - Starboard Fore"; dir = 8; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "plant-14"; layer = 4.1; tag = "icon-plant-14"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cSq" = (/obj/machinery/light{dir = 4},/obj/machinery/camera{c_tag = "Departure Lounge - Starboard Fore"; dir = 8; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-14"; layer = 4.1; tag = "icon-plant-14"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cSr" = (/obj/machinery/power/apc{cell_type = 5000; dir = 2; name = "Aft Maintenance APC"; pixel_y = -24},/obj/structure/cable/yellow,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/aft{name = "Aft Maintenance"}) "cSs" = (/obj/machinery/door/poddoor/preopen{id_tag = "xeno_blastdoor"; name = "biohazard containment door"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/research{name = "Research Division"}) "cSt" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/poddoor/preopen{id_tag = "xeno_blastdoor"; name = "biohazard containment door"},/turf/simulated/floor/plasteel{icon_state = "delivery"},/area/medical/research{name = "Research Division"}) @@ -7900,14 +7900,14 @@ "cVV" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 1; icon_state = "chapel"},/area/chapel/main) "cVW" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel{dir = 4; icon_state = "chapel"},/area/chapel/main) "cVX" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/plasteel{dir = 4; icon_state = "chapel"},/area/chapel/main) -"cVY" = (/obj/machinery/camera{c_tag = "Departure Lounge - Port Aft"; dir = 4; network = list("SS13")},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/structure/flora/kirbyplants{icon_state = "plant-04"; layer = 4.1; tag = "icon-plant-04"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cVY" = (/obj/machinery/camera{c_tag = "Departure Lounge - Port Aft"; dir = 4; network = list("SS13")},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-04"; layer = 4.1; tag = "icon-plant-04"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cVZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/device/radio/beacon,/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{id_tag = "escape_dock_north_airlock"; master_tag = "escape_dock"; pixel_y = 30; req_one_access_txt = "13"; tag_airpump = "escape_dock_north_pump"; tag_chamber_sensor = "escape_dock_north_sensor"; tag_exterior_door = "escape_dock_north_outer"; tag_interior_door = "escape_dock_north_inner"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-warningcorner (EAST)"; icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=9.5-Escape2"; location = "9-Escape"},/mob/living/simple_animal/bot/secbot{auto_patrol = 1; health = 35; maxHealth = 35; name = "Inspector Johnson"},/turf/simulated/floor/plasteel,/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) -"cWf" = (/obj/machinery/camera{c_tag = "Departure Lounge - Starboard Aft"; dir = 8; network = list("SS13")},/obj/machinery/light{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/structure/flora/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) +"cWf" = (/obj/machinery/camera{c_tag = "Departure Lounge - Starboard Aft"; dir = 8; network = list("SS13")},/obj/machinery/light{dir = 4},/obj/item/device/radio/intercom{frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/item/weapon/twohanded/required/kirbyplants{icon_state = "plant-16"; layer = 4.1; tag = "icon-plant-16"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit{name = "\improper Departure Lounge"}) "cWg" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -26; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 9; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cWh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTH)"; icon_state = "warnwhite"; dir = 1},/area/toxins/xenobiology{name = "\improper Secure Lab"}) "cWi" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTHEAST)"; icon_state = "warnwhite"; dir = 5},/area/toxins/xenobiology{name = "\improper Secure Lab"}) @@ -8330,7 +8330,7 @@ "dej" = (/obj/structure/closet/secure_closet/psychiatrist,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/medical/psych) "dek" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/carpet,/area/medical/psych) "del" = (/obj/structure/stool/bed/chair/comfy/beige,/obj/machinery/door_control{id = "psychoffice"; name = "Privacy Shutters Control"; pixel_x = -25; pixel_y = 0},/turf/simulated/floor/carpet,/area/medical/psych) -"dem" = (/obj/machinery/power/apc{dir = 4; name = "Psychiatrist APC"; pixel_x = 25},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/flora/kirbyplants{tag = "icon-plant-25"; icon_state = "plant-25"},/turf/simulated/floor/carpet,/area/medical/psych) +"dem" = (/obj/machinery/power/apc{dir = 4; name = "Psychiatrist APC"; pixel_x = 25},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/item/weapon/twohanded/required/kirbyplants{tag = "icon-plant-25"; icon_state = "plant-25"},/turf/simulated/floor/carpet,/area/medical/psych) "den" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"}) "deo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/medical/psych) "dep" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/carpet,/area/medical/psych) diff --git a/_maps/map_files/MetaStation/z2.dmm b/_maps/map_files/MetaStation/z2.dmm index 288ac0f9044..90fdad55ab1 100644 --- a/_maps/map_files/MetaStation/z2.dmm +++ b/_maps/map_files/MetaStation/z2.dmm @@ -401,7 +401,7 @@ "hK" = (/turf/unsimulated/floor/grass,/area/centcom/control) "hL" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) "hM" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control) -"hN" = (/obj/structure/flora/kirbyplants,/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/evac) +"hN" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/evac) "hO" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/evac) "hP" = (/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/evac) "hQ" = (/obj/structure/rack,/turf/unsimulated/floor{dir = 1; icon_state = "green"},/area/centcom/evac) @@ -518,7 +518,7 @@ "lv" = (/turf/unsimulated/floor{icon_state = "neutral"; dir = 8},/area/tdome/tdomeobserve) "lw" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome/tdomeobserve) "lx" = (/turf/unsimulated/floor{icon_state = "neutral"; dir = 4},/area/tdome/tdomeobserve) -"ly" = (/obj/structure/flora/kirbyplants,/turf/unsimulated/floor{icon_state = "red"; dir = 10},/area/centcom/evac) +"ly" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "red"; dir = 10},/area/centcom/evac) "lz" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "red"; dir = 2},/area/centcom/evac) "lA" = (/turf/unsimulated/floor{icon_state = "red"; dir = 2},/area/centcom/evac) "lB" = (/obj/structure/rack,/obj/item/toy/katana,/turf/unsimulated/floor{icon_state = "red"; dir = 2},/area/centcom/evac) diff --git a/_maps/map_files/RandomZLevels/beach.dmm b/_maps/map_files/RandomZLevels/beach.dmm index 0a5cd703fc0..04512b660bf 100644 --- a/_maps/map_files/RandomZLevels/beach.dmm +++ b/_maps/map_files/RandomZLevels/beach.dmm @@ -19,7 +19,7 @@ "as" = (/obj/structure/boulder,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) "at" = (/obj/item/flag/cult,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "au" = (/obj/structure/mineral_door/sandstone,/obj/structure/barricade/wooden,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) -"av" = (/obj/item/weapon/crossbowframe,/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) +"av" = (/turf/unsimulated/beach/water/deep/sand_floor,/area/awaymission/undersea) "aw" = (/obj/item/toy/eight_ball/conch,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "ax" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) "ay" = (/obj/structure/closet/cabinet,/turf/unsimulated/beach/water/deep/wood_floor,/area/awaymission/undersea) diff --git a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm index e68167fea13..5003686f08a 100644 --- a/_maps/map_files/RandomZLevels/blackmarketpackers.dmm +++ b/_maps/map_files/RandomZLevels/blackmarketpackers.dmm @@ -20,7 +20,7 @@ "at" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/engine,/area/awaymission/BMPship/Fore) "au" = (/obj/machinery/light/small,/turf/simulated/floor/engine,/area/awaymission/BMPship/Fore) "av" = (/turf/simulated/shuttle/wall{tag = "icon-swall7"; icon_state = "swall7"},/area/awaymission/BMPship/Fore) -"aw" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/awaymission/BMPship/Aft) +"aw" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/awaymission/BMPship/Fore) "ax" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"},/area/awaymission/BMPship/Aft) "ay" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"},/area/awaymission/BMPship/Aft) "az" = (/turf/simulated/shuttle/wall{tag = "icon-swall13"; icon_state = "swall13"},/area/awaymission/BMPship/Aft) @@ -28,7 +28,7 @@ "aB" = (/obj/machinery/door/airlock/silver{locked = 1},/turf/simulated/floor/plating{tag = "icon-panelscorched"; icon_state = "panelscorched"},/area/awaymission/BMPship/Aft) "aC" = (/turf/simulated/shuttle/wall{tag = "icon-swall4"; icon_state = "swall4"},/area/awaymission/BMPship/Aft) "aD" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/awaymission/BMPship/Aft) -"aE" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/awaymission/BMPship/Aft) +"aE" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/BMPship/Aft) "aF" = (/turf/simulated/shuttle/wall,/area/awaymission/BMPship/Aft) "aG" = (/obj/structure/stool/bed/roller,/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "aH" = (/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) @@ -116,7 +116,7 @@ "cl" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"},/area/awaymission/BMPship/Midship) "cm" = (/turf/simulated/shuttle/wall{tag = "icon-swall13"; icon_state = "swall13"},/area/awaymission/BMPship/Midship) "cn" = (/turf/simulated/shuttle/wall{tag = "icon-swall15"; icon_state = "swall15"},/area/awaymission/BMPship/Aft) -"co" = (/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "packerMed"},/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) +"co" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/awaymission/BMPship/Aft) "cp" = (/obj/machinery/door/poddoor/shutters{dir = 2; id_tag = "packerMed"},/turf/simulated/floor/plating/airless,/area/awaymission/BMPship/Aft) "cq" = (/obj/structure/largecrate,/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHWEST)"; icon_state = "warnplate"; dir = 10},/area/awaymission/BMPship/Aft) "cr" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/awaymission/BMPship/Aft) @@ -128,7 +128,7 @@ "cx" = (/obj/machinery/door_control{id = "packerCargo"; pixel_y = -24},/obj/machinery/light/small,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/awaymission/BMPship/Aft) "cy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/awaymission/BMPship/Aft) "cz" = (/turf/simulated/floor/plating{tag = "icon-warnplate (SOUTHEAST)"; icon_state = "warnplate"; dir = 6},/area/awaymission/BMPship/Aft) -"cA" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/awaymission/BMPship/Fore) +"cA" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/BMPship/Fore) "cB" = (/turf/simulated/floor/plasteel{tag = "icon-carpet"; icon_state = "carpet"},/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/BMPship/Fore) "cC" = (/turf/simulated/floor/plasteel{tag = "icon-carpet"; icon_state = "carpet"},/area/awaymission/BMPship/Fore) "cD" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/apc/noalarm{dir = 1; locked = 0; pixel_y = 24; req_access = ""},/turf/simulated/floor/plasteel{tag = "icon-carpet"; icon_state = "carpet"},/area/awaymission/BMPship/Fore) @@ -277,7 +277,7 @@ "fq" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/awaymission/BMPship/Aft) "fr" = (/obj/structure/rack,/obj/item/weapon/storage/belt/utility/full,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/awaymission/BMPship/Aft) "fs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaymission/BMPship/Aft) -"ft" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/awaymission/BMPship/Aft) +"ft" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/BMPship/Aft) "fu" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plasteel{tag = "icon-carpet15-7 (EAST)"; icon_state = "carpet15-7"; dir = 4},/area/awaymission/BMPship/Fore) "fv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{tag = "icon-carpet15-13 (EAST)"; icon_state = "carpet15-13"; dir = 4},/area/awaymission/BMPship/Fore) "fw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{tag = "icon-carpet15-7 (EAST)"; icon_state = "carpet15-7"; dir = 4},/area/awaymission/BMPship/Fore) @@ -317,7 +317,7 @@ "ge" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/awaymission/BMPship/Aft) "gf" = (/obj/structure/mopbucket,/turf/simulated/shuttle/plating,/area/awaymission/BMPship/Aft) "gg" = (/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/kitchen/knife,/turf/simulated/shuttle/plating,/area/awaymission/BMPship/Aft) -"gh" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/awaymission/BMPship/Fore) +"gh" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/awaymission/BMPship/Fore) "gi" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-carpetside"; icon_state = "carpetside"},/area/awaymission/BMPship/Fore) "gj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{tag = "icon-carpetside"; icon_state = "carpetside"},/area/awaymission/BMPship/Fore) "gk" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"; dir = 2},/area/awaymission/BMPship/Midship) @@ -334,7 +334,7 @@ "gv" = (/obj/item/stack/cable_coil,/turf/simulated/floor/plating,/area/awaymission/BMPship/Aft) "gw" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/awaymission/BMPship/Aft) "gx" = (/obj/item/stack/sheet/mineral/uranium{amount = 50},/turf/simulated/floor/engine,/area/awaymission/BMPship/Aft) -"gy" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/space) +"gy" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/space) "gz" = (/turf/simulated/floor/plating/airless{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/awaymission/BMPship/Fore) "gA" = (/obj/structure/lattice,/turf/space,/area/awaymission/BMPship/Fore) "gB" = (/turf/simulated/floor/plating/airless{tag = "icon-platingdmg3"; icon_state = "platingdmg3"},/area/awaymission/BMPship/Fore) @@ -449,7 +449,7 @@ "iG" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/engine,/area/awaymission/BMPship/Fore) "iH" = (/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/simulated/floor/plating,/area/awaymission/BMPship/Fore) "iI" = (/obj/item/weapon/contraband/poster,/turf/simulated/floor/plating,/area/awaymission/BMPship/Fore) -"iJ" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/awaymission/BMPship/Fore) +"iJ" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/BMPship/Fore) "iK" = (/turf/simulated/floor/plating,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/BMPship/Fore) "iL" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/turf/simulated/floor/engine,/area/awaymission/BMPship/Fore) "iM" = (/turf/simulated/mineral/random/high_chance_clown,/area/awaymission) @@ -503,25 +503,25 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafagagahagaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajakalamanaoaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapalalaqararaoaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaaaaaaaaaaaaaaaaaaatakauamarararavaiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasawaxaxaxaxaxaxaxaxaxayaxaxaxazaAaBaCazazaxaDaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaasaFaGaHaIaJaKaLaMaNaOaPaQaRaSaTaUaVaVaVaVaVaVaWaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafagagahagawaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajakalamanaoawaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapalalaqararaoawaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaaaaaaaaaaaaaaaaaaaaaaaatakauamarararavawaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaEaxaxaxaxaxaxaxaxaxayaxaxaxazaAaBaCazazaxaDcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasaaasaFaGaHaIaJaKaLaMaNaOaPaQaRaSaTaUaVaVaVaVaVaVaWcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafagagahagagagagagagagaiaaaaaaaaaaaaasaXaYaHaHaZaHaHaHbaaHaHbbbcbdbdbebdbdbfbgbhbdbibjaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacababacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkblbmbnbobpbqbpbqbpbrbsaaaaaaaaaaasbtaYaHbuaHaHaHaGaHbvaNaNbwbxbybdbzbdbdbAbBbCbDbdbjaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabEbFbGbnbHararararararbIaaaaaaasawaFaHbuaYaHbuaHaHaHaZaHaHaHbJbcbKbdbdbdbdbLbMbNbdbdbOaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPbQbFbnarbRbRbSbRbRbTbUaaaaaaawbVbtbuaHbWbXaHaHaHbYbZbWbYbZaPbccacbcccccdccccccccbyceaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfcgchcicjckclclclclclcmclclclcmcnaxaxaxaxaAcococpaCaxaxaxaxbVcqcrcsctcrcrcucvcwcxcyczaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCcDcCcEcFcGcHcIcJcKcIcLcGcMcNcOcPcQcRcMcMcMcMcScTcUcScVcWaxaxaxaxaxaxaxaxayaAcXaCcnaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcYcZcYdacCcEcMdbcHdcdcdcdccLcMcMdddedededfcMcMcMcMdgdgcMdgcMdhdididjdkdldmdldnaPdodpdqdrazaxayaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCdsdtdsdudvcEcMcMcHdcdwdcdccLcMcMdxdydzdAdBcMcMcMcMcMcMcMcMcMaPdjdCdjbJdDdEdFdGaPdHdpdododIdJcWazaxaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabEbFbGbnbHararararararbIaaaaaaasaEaFaHbuaYaHbuaHaHaHaZaHaHaHbJbcbKbdbdbdbdbLbMbNbdbdbOaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabPbQbFbnarbRbRbSbRbRbTbUaaaaaaaEbVbtbuaHbWbXaHaHaHbYbZbWbYbZaPbccacbcccccdccccccccbyceaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacfcgchcicjckclclclclclcmclclclcmcnaxaxaxaxaAcpcpcpaCaxaxaxaxbVcqcrcsctcrcrcucvcwcxcyczaPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCcDcCcEcFcGcHcIcJcKcIcLcGcMcNcOcPcQcRcMcMcMcMcScTcUcScVcWaxaxaxaxaxaxaxaxayaAcXaCcncoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcYcZcYdacCcEcMdbcHdcdcdcdccLcMcMdddedededfcMcMcMcMdgdgcMdgcMdhdididjdkdldmdldnaPdodpdqdrazaxaycoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCdsdtdsdudvcEcMcMcHdcdwdcdccLcMcMdxdydzdAdBcMcMcMcMcMcMcMcMcMaPdjdCdjbJdDdEdFdGaPdHdpdododIdJcWazaxcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAcBcCcCdKdLdMdNdOcEcMcMdPdQdQdRdQdScMcMdTcMdUdVdVdVdVdVdVdVdVdVdWcMdhdjdXdjdraxaxaxaxbVdHdYdZeaebecbbedeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaciegegegeheiejekelddemeneoeoeoeoeoeodWcMddcMepcMeqerererererererepcMaPdjesdjdjdjdjdjetaPeuevbdewbdexeyezeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeAeBeCegcYcZcYcZeDeEeoeFererererereGeHcMeIcMepeJeKeLeKeKeKeKeMeNeOePbbdjeseQeReReSdjdjaPeTeUbdeVeWeXbJezeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeYeZfaegfbdtdsdtfcdTcMcMerfdfefdfffgepfhepcMepcMfierererererererepfjfkflfmfnfofpfqdjdjaPfreUbdewbdfscWayaxftaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeYeZfaegcYfufvfwfxddcMcMerfdfdfgfffgfyeofzeofAcMcMcMcMcMfBcMcMcMepcMfCdjesfDfofofEdjdjaPfFevfoewbdfGcWazaxaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeYeZfaegcYfufvfwfxddcMcMerfdfdfgfffgfyeofzeofAcMcMcMcMcMfBcMcMcMepcMfCdjesfDfofofEdjdjaPfFevfoewbdfGcWazaxcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafHfIfJegdsfKdsdtcCfLcMcMerfMfdfgfNfgepcMfOcMepcMcMfPcMcMcMcMcMcMfQdVfRfSfTfDfUfofEdjdjaPfFevfofVeWfWbbfXeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabUegegegegfYegfZgadTemcMerfdfggbffgcepcMdTcMepcMeqerererererererepgdgeflfmfngffoggdjetaPeuevfobdbddJeyezeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaghahagaggigjagagaggkcMcMerfgfgfgglfgepgmddcMepgngogpgqgqgqgqeMeNeOgrbJdjesgsgtgtgudjdjaPdHeUbdgvbdgwbJgxeeefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -584,3 +584,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/RandomZLevels/centcomAway.dmm b/_maps/map_files/RandomZLevels/centcomAway.dmm index fe4583e5be0..11cab2ce739 100644 --- a/_maps/map_files/RandomZLevels/centcomAway.dmm +++ b/_maps/map_files/RandomZLevels/centcomAway.dmm @@ -442,7 +442,7 @@ "iz" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/turf/simulated/floor/wood,/area/awaymission/centcomAway/courtroom) "iA" = (/obj/structure/sign/vacuum,/turf/simulated/wall/r_wall,/area/awaymission/centcomAway/hangar) "iB" = (/obj/machinery/door/airlock/external,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/centcomAway/hangar) -"iC" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/centcomAway/general) +"iC" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-vault (NORTHEAST)"; icon_state = "vault"; dir = 5},/area/awaymission/centcomAway/general) "iD" = (/obj/machinery/door/airlock/centcom,/turf/simulated/floor/plasteel{icon_state = "floor"},/area/awaymission/centcomAway/general) "iE" = (/obj/machinery/door/airlock/centcom{name = "Centcom Security"; opacity = 1; req_access_txt = "101"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/centcomAway/general) "iF" = (/obj/structure/closet/secure_closet/injection,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/centcomAway/courtroom) diff --git a/_maps/map_files/RandomZLevels/moonoutpost19.dmm b/_maps/map_files/RandomZLevels/moonoutpost19.dmm index 71c30499550..57218ff1ad2 100644 --- a/_maps/map_files/RandomZLevels/moonoutpost19.dmm +++ b/_maps/map_files/RandomZLevels/moonoutpost19.dmm @@ -483,7 +483,7 @@ "jo" = (/obj/effect/decal/cleanable/flour,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "jp" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "jq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/effect/decal/cleanable/blood/oil{color = "black"},/turf/simulated/floor/plating{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "MO19 Research"}) -"jr" = (/obj/structure/flora/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"jr" = (/obj/item/weapon/twohanded/required/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "js" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "jt" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "ju" = (/obj/structure/table,/obj/item/weapon/newspaper,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) @@ -728,7 +728,7 @@ "nZ" = (/obj/machinery/light/small{dir = 4},/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; dir = 2; heat_capacity = 1e+006; icon_state = "neutralcorner"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "oa" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_plating = "asteroidplating"; icon_state = "asteroidplating"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "ob" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) -"oc" = (/obj/structure/flora/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "neutral"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) +"oc" = (/obj/item/weapon/twohanded/required/kirbyplants{desc = "A plastic potted plant."; layer = 4.1; pixel_y = 3},/turf/simulated/floor/plasteel{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_state = "neutral"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a1{has_gravity = 1; name = "MO19 Arrivals"}) "od" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plating{carbon_dioxide = 48.7; heat_capacity = 1e+006; icon_plating = "asteroidplating"; icon_state = "asteroidplating"; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "oe" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) "of" = (/obj/item/trash/candy,/turf/simulated/floor/plating/airless/asteroid{carbon_dioxide = 48.7; heat_capacity = 1e+006; nitrogen = 13.2; oxygen = 32.4; temperature = 251},/area/awaycontent/a3{always_unpowered = 1; ambientsounds = list('sound/ambience/ambimine.ogg'); has_gravity = 1; name = "Khonsu 19"; power_environ = 0; power_equip = 0; power_light = 0; poweralm = 0}) diff --git a/_maps/map_files/RandomZLevels/spacebattle.dmm b/_maps/map_files/RandomZLevels/spacebattle.dmm index 9f278c80c36..0baeb1bcaf4 100644 --- a/_maps/map_files/RandomZLevels/spacebattle.dmm +++ b/_maps/map_files/RandomZLevels/spacebattle.dmm @@ -91,11 +91,11 @@ "bM" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{tag = "icon-heater (NORTH)"; icon_state = "heater"; dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/awaymission/spacebattle/cruiser) "bN" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/cruiser) "bO" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/cruiser) -"bP" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/awaymission/spacebattle/cruiser) +"bP" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/spacebattle/cruiser) "bQ" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/awaymission/spacebattle/cruiser) "bR" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"},/area/awaymission/spacebattle/cruiser) "bS" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"},/area/awaymission/spacebattle/cruiser) -"bT" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/awaymission/spacebattle/cruiser) +"bT" = (/turf/space,/turf/simulated/shuttle/wall{dir = 3; icon_state = "swall_f10"; layer = 2; tag = "icon-swall_f10"},/area/awaymission/spacebattle/cruiser) "bU" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_l (EAST)"; icon_state = "burst_l"; dir = 4},/turf/space,/area/awaymission/spacebattle/cruiser) "bV" = (/obj/structure/shuttle/engine/heater{tag = "icon-heater (WEST)"; icon_state = "heater"; dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-engine"; icon_state = "engine"},/area/awaymission/spacebattle/cruiser) "bW" = (/obj/machinery/computer/telecomms/monitor,/turf/simulated/floor/plasteel,/area/awaymission/spacebattle/cruiser) @@ -170,7 +170,7 @@ "dn" = (/turf/simulated/floor/plasteel{tag = "icon-damaged4"; icon_state = "damaged4"},/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/awaymission/spacebattle/cruiser) "do" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "spacebattlepod2"; name = "Front Hull Door"; opacity = 1; tag = "icon-pdoor0"},/turf/simulated/shuttle/plating,/area/awaymission/spacebattle/cruiser) "dp" = (/turf/simulated/floor/plasteel{tag = "icon-damaged1"; icon_state = "damaged1"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/awaymission/spacebattle/cruiser) -"dq" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/awaymission/spacebattle/cruiser) +"dq" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/awaymission/spacebattle/cruiser) "dr" = (/obj/effect/decal/cleanable/blood,/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"},/area/awaymission/spacebattle/cruiser) "ds" = (/turf/simulated/shuttle/wall{tag = "icon-swall15"; icon_state = "swall15"},/area/awaymission/spacebattle/cruiser) "dt" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"},/area/awaymission/spacebattle/cruiser) @@ -266,7 +266,7 @@ "ff" = (/obj/machinery/door/poddoor{id_tag = "spacebattlestorage"; name = "Secure Storage"},/turf/simulated/floor/plasteel,/area/awaymission/spacebattle/cruiser) "fg" = (/mob/living/simple_animal/hostile/syndicate/ranged,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/awaymission/spacebattle/cruiser) "fh" = (/obj/machinery/computer/security/telescreen,/turf/simulated/shuttle/wall,/area/awaymission/spacebattle/cruiser) -"fi" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/awaymission/spacebattle/cruiser) +"fi" = (/turf/space,/area/awaymission/spacebattle/cruiser) "fj" = (/obj/machinery/door/airlock/external,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/awaymission/spacebattle/syndicate4) "fk" = (/obj/structure/closet/crate,/obj/item/clothing/glasses/material,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) "fl" = (/obj/structure/closet/crate,/obj/item/weapon/light/tube,/obj/item/weapon/light/tube,/obj/item/weapon/light/tube,/turf/simulated/floor/plating,/area/awaymission/spacebattle/cruiser) @@ -407,7 +407,7 @@ "hQ" = (/obj/machinery/shower{tag = "icon-shower (WEST)"; icon_state = "shower"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/spacebattle/cruiser) "hR" = (/obj/structure/toilet,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/spacebattle/cruiser) "hS" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/firstaid/fire,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/spacebattle/cruiser) -"hT" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"},/area/awaymission/spacebattle/cruiser) +"hT" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/spacebattle/cruiser) "hU" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission/spacebattle/cruiser) "hV" = (/turf/simulated/shuttle/wall{tag = "icon-swall1"; icon_state = "swall1"},/area/awaymission/spacebattle/cruiser) "hW" = (/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor/plasteel{icon_state = "white"},/area/awaymission/spacebattle/cruiser) @@ -615,13 +615,13 @@ abababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbUbVcdbZbZbZdedededfdfdgdgdhdhdhdididicbhOhPhQcbhRcbhRcbhRcbhRcbhRcbbZbZcbgFgFgFgFgFgFgFhScbbZbZcObSbSbSbSbSeGbSbSbSbScabSbSbSbSeGbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSeHcacacphTabababababababababababababababababababababababababdqdtbZbZbZbZbZbZbZbZbZbZbZbZcGcWcWababababababababababababababababababababababababababababhphehfhfhfhfhfhfhfgXgMabababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcdbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbhPhPhPcbhUhVhUhVhUhVhUhVhUcbbZbZcbgFhvgFgFgFgFhWhXcbbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcYbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbabababababababababababababababababababababababababababcbbZbZbZbZbZbZbZbZbZbZcYbZcVcWdbababababababababababababababababababababababababababababhphehfhfhfhfhfhfhfhghhabababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcdbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbhYhPhZcbhPhPhPhPhPhPiahPhPcabZchcbgFgFgFgFgFibgRgFcbbZcYbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbabababababababababababababababababababababababababababcbbZbZbZbZbZbZbZbZbZbZbZbZdacWcWababababababababababababababababababababababababababababhphehfhfhfhfhfhfhfhghqabababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcsbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbhPhPhPgDichPhPhPhPhPidhPhPcabZbZcbieifgFieifgFieifcbbZbZcrbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbShTabababababababababababababababababababababababababababdqbSbSbSbSbSbSbSbSbSbSbSbSbSbSfiababababababababababababababababababababababababababababiggXgXgXgXgXgXgXgXgXhzabababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcsbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbhPhPhPgDichPhPhPhPhPidhPhPcabZbZcbieifgFieifgFieifcbbZbZcrbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbSbShTabababababababababababababababababababababababababababdqbSbSbSbSbSbSbSbSbSbSbSbSbSbShTababababababababababababababababababababababababababababiggXgXgXgXgXgXgXgXgXhzabababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcsbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbhYhPhQhVhPhPhPhPhPhPiahPihcbbZbZcbgFgFgFgFgFgFgFgFcbbZbZcGcHcHcHcHcHcHcGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgLhzababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcsbZbZbZbZbZbZbZcobZbZbZbZbZbZbZbZcbhPhPhPhUhPhPhPhPhPhPhPhPihcbbZbZcbiiijikiiijikiiijcbbZbZcGcHcHcHcHcHcHcGababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcdbZbZbZbZbZbZbZbZbZilbZimcKcJbZcmcpbQbQbQbQbQbQbQbQbQbQbQbQbQeHbZbZcObSbSbSbSbSbSbSbSeHbZbZcpbQbQbQbQbQbQfiababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcdbZbZbZbZbZbZbZbZbZilbZimcKcJbZcmcpbQbQbQbQbQbQbQbQbQbQbQbQbQeHbZbZcObSbSbSbSbSbSbSbSeHbZbZcpbQbQbQbQbQbQhTababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababccbVcdbZbZbZbZbZbZbZbZbZbZbZbZbZcKincKcabZbZbZbZimbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZcbabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababiobVbWipbZbZbZbZbZbZimbZbZbZcIcIcKcmcKcabZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZchbZbZbZbZbZbZbZbZbZbZbZcbabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab -ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdqbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQeGbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbSbSbSbSbSbSbSbSbSbSbSfiabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab +ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdqbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQeGbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbQbSbSbSbSbSbSbSbSbSbSbShTabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab @@ -730,3 +730,4 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/RandomZLevels/spacehotel.dmm b/_maps/map_files/RandomZLevels/spacehotel.dmm index ce1e5a290e9..e168c1ccb19 100644 --- a/_maps/map_files/RandomZLevels/spacehotel.dmm +++ b/_maps/map_files/RandomZLevels/spacehotel.dmm @@ -145,6 +145,7 @@ "cO" = (/obj/machinery/door_control{id = "Room103"; name = "Room103 Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/awaymission) "cP" = (/turf/simulated/floor/plasteel,/area/awaymission) "cQ" = (/mob/living/simple_animal/hostile/retaliate/goat,/turf/simulated/floor/plasteel,/area/awaymission) +"cR" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission) "cS" = (/obj/structure/stool/bed/nest,/turf/simulated/floor/carpet,/area/awaymission) "cT" = (/obj/structure/stool/bed/alien,/obj/item/xenos_claw,/turf/simulated/floor/carpet,/area/awaymission) "cU" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/yellow,/turf/simulated/floor/carpet,/area/awaymission) @@ -174,7 +175,9 @@ "ds" = (/obj/machinery/door/window/southright,/obj/effect/decal/cleanable/blood/old,/turf/simulated/floor/carpet,/area/awaymission) "dt" = (/obj/machinery/vending/dinnerware,/turf/simulated/floor/plasteel,/area/awaymission) "du" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission) +"dv" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/awaymission) "dw" = (/obj/machinery/door/window/eastleft,/obj/structure/alien/weeds,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/awaymission) +"dx" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/awaymission) "dy" = (/obj/machinery/light,/turf/simulated/floor/plasteel,/area/awaymission) "dz" = (/obj/machinery/processor,/turf/simulated/floor/plasteel,/area/awaymission) "dA" = (/obj/machinery/chem_master/condimaster,/turf/simulated/floor/plasteel,/area/awaymission) @@ -239,12 +242,11 @@ "eH" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/space) "eI" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/space) "eJ" = (/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/turf/simulated/floor/plating,/area/awaymission) -"eK" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/awaymission) +"eK" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission) "eL" = (/obj/effect/decal/cleanable/blood/old,/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/awaymission) "eM" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/space) "eN" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/awaymission) "eO" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/plating,/area/awaymission) -"eP" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/awaymission) "eQ" = (/obj/effect/decal/cleanable/blood/old,/turf/simulated/shuttle/wall{icon_state = "swallc4"; dir = 2},/area/awaymission) "eR" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor,/area/awaymission) "eS" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/awaymission) @@ -254,11 +256,9 @@ "eW" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/old,/turf/simulated/shuttle/floor,/area/awaymission) "eX" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor,/area/awaymission) "eY" = (/obj/structure/window/reinforced{dir = 4},/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood/old,/turf/simulated/shuttle/floor,/area/awaymission) -"eZ" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/awaymission) "fa" = (/turf/simulated/shuttle/wall{icon_state = "swallc1"; dir = 2},/area/awaymission) "fb" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor,/area/awaymission) "fc" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/decal/cleanable/blood/old,/turf/simulated/shuttle/floor,/area/awaymission) -"fd" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/awaymission) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabacacacadacacacacacacacacacacacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -316,9 +316,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboaHaHaHaHbpaHbpaHexaHeEaoabaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboaHaHaHaHaHaHaHbqexeFexaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeGeHeHeIaoeJaoeJaoaoaoaoaoabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeJaoeJababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeKeLeMeHeIeNeOeNeOeNeMeHeIeNePaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeKbReQeReSeSeSbDbDbDbDbDeSeSeSeTeUeVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacReLeMeHeIeNeOeNeOeNeMeHeIeNdvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRbReQeReSeSeSbDbDbDbDbDeSeSeSeTeUeVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabReWeXbDbDbDbDbDeSeSeSbDbDbDbDeYeUeVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZbRfabDeSeWeSbDbDeRbDbDfbfceSeTeUeVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZeNeMeHeIeNeLeLeLeNeMeHeIeNfdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadxbRfabDeSeWeSbDbDeRbDbDfbfceSeTeUeVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadxeNeMeHeIeNeLeLeLeNeMeHeIeNeKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/RandomZLevels/stationCollision.dmm b/_maps/map_files/RandomZLevels/stationCollision.dmm index 4934529dbf1..bf7e67bcd2d 100644 --- a/_maps/map_files/RandomZLevels/stationCollision.dmm +++ b/_maps/map_files/RandomZLevels/stationCollision.dmm @@ -295,7 +295,7 @@ "fI" = (/turf/simulated/wall/cult,/area/awaymission/midblock) "fJ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/midblock) "fK" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/midblock) -"fL" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/awaymission/arrivalblock) +"fL" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/arrivalblock) "fM" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"; dir = 2},/area/awaymission/arrivalblock) "fN" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/awaymission/arrivalblock) "fO" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/awaymission/arrivalblock) @@ -383,6 +383,7 @@ "hs" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "ht" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/decal/remains/human,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/awaymission/arrivalblock) "hu" = (/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) +"hv" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/awaymission/arrivalblock) "hw" = (/obj/structure/window/reinforced,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "hx" = (/obj/machinery/door/window/southleft{name = "Windoor"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/awaymission/arrivalblock) "hy" = (/obj/item/ammo_casing/c10mm{pixel_x = 2; pixel_y = 5},/obj/item/ammo_casing/c10mm{pixel_x = -4; pixel_y = -5},/obj/item/ammo_casing/c10mm,/turf/simulated/floor/plasteel/airless,/area/awaymission/midblock) @@ -404,6 +405,7 @@ "hO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel,/area/awaymission/midblock) "hP" = (/obj/effect/decal/remains/human,/obj/item/weapon/kitchen/knife/butcher,/obj/item/weapon/kitchen/knife,/obj/item/clothing/head/chefhat,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel,/area/awaymission/midblock) "hQ" = (/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel,/area/awaymission/midblock) +"hR" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/arrivalblock) "hS" = (/obj/machinery/light/small,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/awaymission/midblock) "hT" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/midblock) "hU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/midblock) @@ -541,7 +543,6 @@ "kz" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_l"; icon_state = "burst_l"},/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/plating,/area/awaymission/arrivalblock) "kA" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (NORTH)"; icon_state = "propulsion_l"; dir = 1},/obj/structure/window/reinforced,/turf/space,/area/awaymission/arrivalblock) "kB" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_r (NORTH)"; icon_state = "propulsion_r"; dir = 1},/obj/structure/window/reinforced,/turf/space,/area/awaymission/arrivalblock) -"kC" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/awaymission/arrivalblock) "kD" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "kE" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "kF" = (/obj/structure/sink/kitchen{pixel_y = 32},/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) @@ -580,10 +581,8 @@ "lm" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/southblock) "ln" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/southblock) "lo" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/plating,/area/awaymission/southblock) -"lp" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/awaymission/arrivalblock) "lq" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/awaymission/arrivalblock) "lr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/plating,/area/awaymission/arrivalblock) -"ls" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/awaymission/arrivalblock) "lt" = (/obj/structure/closet/crate/hydroponics,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "lu" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) "lv" = (/obj/effect/decal/cleanable/blood/splatter,/obj/effect/decal/cleanable/blood/splatter,/turf/simulated/floor/plasteel,/area/awaymission/arrivalblock) @@ -680,12 +679,13 @@ aafZgbgbgbgbgbfZhEiDilgzgzgzgzgzgzjogzgzgzjpjpiYiYjqiYiYiYiYjriYiYiYjsjtjujujuju aafZgcgcgbgcgcfZhVhuhqjyjzjAiljBhujChuhuhuhuhuiYjDjEjFiYjGjHjHjIjJiYjKjEjujLjMjNjOjPjujQjQjRjRjSjQjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa aafZgbgbgbgbgbfZjUjViDhqhWhujWjyhujXhuhuhuhuhuiYjYjZkaiYkbkckdkekfiYjKkgjujLkhkikjjPjujQjQjQjQjQkkjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa aafZklklklklklfZgzkmknkokmkngzgzgzgzgzjpgzgzgziYiYiYiYiYiYiYkpiYjriYjKjEjukqkrksktkujukvjQkwjQjQjQjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aagakxkykykykzgaaafLkAgRkBkCaagzkDkEkFhukGjzhuiYkfjHkfiYkHjHjHkIkfiYjKjEjukJkKkLkKkMjujQkkjQkNjQjQjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aagakxkykykykzgaaafLkAgRkBfQaagzkDkEkFhukGjzhuiYkfjHkfiYkHjHjHkIkfiYjKjEjukJkKkLkKkMjujQkkjQkNjQjQjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaafZkOkPkQfZaagzhuhujzhuhujzhuiYkRjKkSiYkRjKjKjKkTiYjKjEjukUkVkWkVkXjujQjQjSjQjQkkjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaafZkOgbkQfZaagzhujzhujzhuhuhuiYkfkdkfkpkRjKkYkZlaiYjKjEjulbkVkWkVlcjukkjQjQldkwjQjTaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaafZkOgckQfZaagzlehulfhulghuhuiYiYiYiYiYlhjKlijKljiYjKjEjulkkVkWkVlljujujujujulmlnloaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaalplqlrlqlsaagzlthuluhulvjzhuiYlwlxlyiYkRjKlijKlziYjKlAjujujulBjujujulClDlEjuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaahvlqlrlqhRaagzlthuluhulvjzhuiYlwlxlyiYkRjKlijKlziYjKlAjujujulBjujujulClDlEjuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaagzltlFlGlHhuhuhuiYlIkfkfkpkRjKlJjKlKiYlLlMlNlOlOlPlOlQlRlSlTlUjuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaagzgzgzgzgzgzgzgziYlVlWlXiYkfkdlYlZmaiYjKjKjKmbmbmbmbmcjulCmdmejuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiYiYiYiYiYiYiYiYiYiYiYiYiYiYiYiYiYiYiYjujujujujuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "} + diff --git a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm index 9bae9a8215c..04d8818ad02 100644 --- a/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/map_files/RandomZLevels/undergroundoutpost45.dmm @@ -169,7 +169,7 @@ "dm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dn" = (/obj/machinery/firealarm{dir = 2; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "do" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) -"dp" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 2; heat_capacity = 1e+006; icon_state = "greencorner"; tag = "icon-greencorner"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) +"dp" = (/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 2; heat_capacity = 1e+006; icon_state = "greencorner"; tag = "icon-greencorner"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "dr" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "ds" = (/obj/machinery/vending/hydroseeds{slogan_delay = 700},/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) @@ -304,7 +304,7 @@ "fR" = (/obj/structure/table/woodentable,/obj/machinery/newscaster{pixel_x = 0; pixel_y = -28},/turf/simulated/floor/carpet{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "fS" = (/obj/machinery/light/small,/obj/machinery/alarm/monitor{dir = 1; frequency = 1439; locked = 0; pixel_y = -23; req_access = null},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/dresser,/turf/simulated/floor/carpet{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "fT" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/carpet{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) -"fU" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) +"fU" = (/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "fV" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/camera{c_tag = "Central Hallway"; dir = 1; network = list("UO45")},/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "fW" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -28},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) "fX" = (/obj/machinery/vending/snack,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "dark"},/area/awaycontent/a1{has_gravity = 1; name = "UO45 Central Hall"}) @@ -526,7 +526,7 @@ "kf" = (/obj/machinery/suit_storage_unit/engine,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "vault"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "kg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) "kh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a6{has_gravity = 1; name = "UO45 Gateway"}) -"ki" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"ki" = (/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "white"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "kj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{tag = "icon-whitepurplecorner (EAST)"; icon_state = "whitepurplecorner"; dir = 4; heat_capacity = 1e+006},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "kk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitepurple"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "kl" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "whitepurplecorner"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) @@ -665,7 +665,7 @@ "mO" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "mP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "mQ" = (/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) -"mR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/flora/kirbyplants{layer = 5},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) +"mR" = (/obj/effect/decal/cleanable/dirt,/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "mS" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/machinery/newscaster{pixel_x = -30},/turf/simulated/floor/plasteel{dir = 9; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "mT" = (/obj/structure/table,/obj/item/weapon/book/manual/security_space_law,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "mU" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) @@ -790,7 +790,7 @@ "pj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door_control{desc = "A remote control-switch whichs locks the research division down in the event of a biohazard leak or contamination."; id = "UO45_biohazard"; name = "Biohazard Door Control"; pixel_x = 0; pixel_y = -24; req_access_txt = "201"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pk" = (/obj/structure/closet/secure_closet{icon_broken = "secbroken"; icon_closed = "sec"; icon_locked = "sec1"; icon_off = "secoff"; icon_opened = "secopen"; icon_state = "sec1"; locked = 1; name = "security officer's locker"; req_access_txt = "201"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 2; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/item/weapon/restraints/handcuffs,/obj/item/device/flash,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor/plasteel{dir = 6; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) "pl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{broken = 1; heat_capacity = 1e+006; icon_state = "platingdmg3"; tag = "icon-platingdmg3"},/area/awaycontent/a5{has_gravity = 1; name = "UO45 Research"}) -"pm" = (/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; heat_capacity = 1e+006; icon_state = "neutral"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) +"pm" = (/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 10; heat_capacity = 1e+006; icon_state = "neutral"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "pn" = (/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "neutralcorner"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "po" = (/obj/machinery/light/small{dir = 4},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plasteel{dir = 4; heat_capacity = 1e+006; icon_state = "neutral"},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) "pp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock{id_tag = "awaydorm4"; name = "Dorm 4"},/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a2{has_gravity = 1; name = "UO45 Crew Quarters"}) @@ -893,7 +893,7 @@ "ri" = (/obj/machinery/light/small{dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "rj" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "rk" = (/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) -"rl" = (/obj/structure/flora/kirbyplants{layer = 5},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "yellow"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) +"rl" = (/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "yellow"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "rm" = (/obj/machinery/firealarm{dir = 2; pixel_x = 0; pixel_y = 24},/obj/structure/dispenser{pixel_x = -1},/turf/simulated/floor/plasteel{dir = 9; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "rn" = (/obj/machinery/light/small{dir = 1},/obj/structure/table,/obj/item/weapon/tank/emergency_oxygen{pixel_x = -8; pixel_y = 0},/obj/item/weapon/tank/emergency_oxygen{pixel_x = -8; pixel_y = 0},/obj/item/clothing/mask/breath{pixel_x = 4; pixel_y = 0},/obj/item/clothing/mask/breath{pixel_x = 4; pixel_y = 0},/obj/machinery/newscaster{pixel_y = 32},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 1; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) "ro" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/table,/obj/item/weapon/storage/box,/obj/item/weapon/storage/box,/obj/structure/reagent_dispensers/peppertank{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel{dir = 5; heat_capacity = 1e+006; icon_state = "red"},/area/awaycontent/a3{has_gravity = 1; name = "UO45 Engineering"}) @@ -1149,7 +1149,7 @@ "we" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/carpet{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "wf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "wg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{burnt = 1; dir = 8; heat_capacity = 1e+006; icon_state = "floorscorched1"; tag = "icon-floorscorched1 (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) -"wh" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/flora/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) +"wh" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/twohanded/required/kirbyplants{layer = 5},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "wi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 8; heat_capacity = 1e+006; icon_state = "floorgrime"; tag = "icon-floorgrime (WEST)"},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "wj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; tag = "icon-manifold-r-f (EAST)"},/turf/simulated/floor/plasteel{heat_capacity = 1e+006},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) "wk" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid{carbon_dioxide = 173.4; heat_capacity = 1e+006; name = "Cave Floor"; nitrogen = 135.1; oxygen = 0; temperature = 363.9; toxins = 229.8},/area/awaycontent/a4{has_gravity = 1; name = "UO45 Mining"}) diff --git a/_maps/map_files/RandomZLevels/wildwest.dmm b/_maps/map_files/RandomZLevels/wildwest.dmm index 4cc4825b777..c716ee68a6c 100644 --- a/_maps/map_files/RandomZLevels/wildwest.dmm +++ b/_maps/map_files/RandomZLevels/wildwest.dmm @@ -311,6 +311,8 @@ "fY" = (/obj/machinery/washing_machine,/turf/simulated/floor/wood,/area/awaymission/wwmines) "fZ" = (/obj/effect/decal/cleanable/blood/gibs/body{tag = "icon-gibup1"; icon_state = "gibup1"},/obj/structure/stool/bed/chair/wood/normal,/turf/simulated/floor/plasteel{dir = 8; icon_state = "barber"},/area/awaymission/wwmines) "ga" = (/obj/item/weapon/hatchet,/turf/simulated/floor/wood,/area/awaymission/wwmines) +"gb" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/awaymission/wwrefine) +"gc" = (/turf/space,/turf/simulated/shuttle/wall{dir = 3; icon_state = "swall_f10"; layer = 2; tag = "icon-swall_f10"},/area/awaymission/wwrefine) "gd" = (/obj/effect/landmark/corpse/syndicatecommando{mobname = "Syndicate Commando"},/turf/simulated/floor/grass,/area/awaymission/wwgov) "ge" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) "gf" = (/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/window/reinforced{tag = "icon-fwindow (NORTH)"; icon_state = "fwindow"; dir = 1},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) @@ -321,19 +323,17 @@ "gk" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/grass,/area/awaymission/wwgov) "gl" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{tag = "icon-fwindow (EAST)"; icon_state = "fwindow"; dir = 4},/obj/structure/window/reinforced{tag = "icon-fwindow (WEST)"; icon_state = "fwindow"; dir = 8},/obj/structure/grille,/turf/simulated/floor/plasteel,/area/awaymission/wwrefine) "gm" = (/obj/effect/decal/cleanable/blood,/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/mineral,/area/awaymission/wwmines) -"gn" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"},/area/awaymission/wwrefine) +"gn" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/awaymission/wwrefine) "go" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"},/area/awaymission/wwrefine) "gp" = (/turf/simulated/shuttle/wall{tag = "icon-swall8"; icon_state = "swall8"},/area/awaymission/wwrefine) "gq" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle{tag = "icon-floor2"; icon_state = "floor2"},/area/awaymission/wwrefine) "gr" = (/turf/simulated/shuttle/wall{tag = "icon-swall4"; icon_state = "swall4"},/area/awaymission/wwrefine) -"gs" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"},/area/awaymission/wwrefine) +"gs" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/awaymission/wwrefine) "gt" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"},/area/awaymission/wwrefine) "gu" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle{tag = "icon-floor2"; icon_state = "floor2"},/area/awaymission/wwrefine) "gv" = (/turf/simulated/shuttle{tag = "icon-floor2"; icon_state = "floor2"},/area/awaymission/wwrefine) -"gw" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"},/area/awaymission/wwrefine) "gx" = (/turf/simulated/shuttle/wall{tag = "icon-swallc1"; icon_state = "swallc1"},/area/awaymission/wwrefine) "gy" = (/turf/simulated/shuttle/wall{tag = "icon-swallc2"; icon_state = "swallc2"},/area/awaymission/wwrefine) -"gz" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"},/area/awaymission/wwrefine) "gA" = (/obj/effect/landmark{name = "awaystart"},/turf/simulated/floor/plating/ironsand{tag = "icon-ironsand1"; icon_state = "ironsand1"},/area/awaymission/wwmines) "gB" = (/obj/structure/table/reinforced,/obj/item/clothing/suit/space/syndicate/black/orange,/obj/item/clothing/head/helmet/space/syndicate/black/orange,/obj/item/clothing/mask/gas/syndicate,/obj/item/weapon/tank/oxygen,/turf/simulated/shuttle{tag = "icon-floor2"; icon_state = "floor2"},/area/awaymission/wwrefine) "gC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{tag = "icon-fwindow"; icon_state = "fwindow"},/turf/simulated/shuttle{tag = "icon-floor2"; icon_state = "floor2"},/area/awaymission/wwrefine) @@ -626,15 +626,15 @@ aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftgdftftftftftftftftftfBbQaaaa aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftftftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekeZaaaaaaaaaaaGaGaGaGaNaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaLaRaRaRaRaRfUaLaLaRaRaRaRaRaRfcbsbsaRaRaRaRaRaRaRaRheaRaRheaRaRaRaRaRaRaRaRaRaRaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaabTfAftftftftftftftfSftftftftftftftftftftftftftftfBbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeZekeZaaaaaaaaaGaGaGaGaGaNaLaRaRaRaRaRaRaRaRaRaRaRaRaRaRfUaLaLaLaRaRaReaaRaRaLaRaReaaRaLaLaLaLaLaLaLaLaRaRaLaLaLaLaLaRaRaLaLaRaRaLaRaRaRaRaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaaaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaabTgigjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgjgkbQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagleRglaaaaaaaaaGaGaGaGaNaNaLaLaLaLaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaRaRaRaRgmaRaWaRaRfUaNaNaNaNaNaNaLaLaLaLaNaNaNaLaLaLaLaLaLaLaLaRaLaLaLaLaLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaadUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagngogpgqgrgogsaaaaaaaGaGaGaNaNaNaLaLaLaLaLaLfUaLaLaRaRaRaRaRaRaRaRaLaLaLaLaRaRaWeaaRaRaRaRaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaNaLaLaLaGaGaGaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaadUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUdUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagbgogpgqgrgogcaaaaaaaGaGaGaNaNaNaLaLaLaLaLaLfUaLaLaRaRaRaRaRaRaRaRaLaLaLaLaRaRaWeaaRaRaRaRaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaNaNaNaNaLaLaLaGaGaGaNaNaNaNaNaNaNaNaNaNaNaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgugugvgugugtaaaaaaaGaGaGaNaNaLaLaRaRaRaRaLaLaNaLaLaRaRaRaRaRaRaRaRaLaNaLaLaRaRaReaaRgmaLaLaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaGaGaGaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgugugvgugugtaaaaaaaaaGaGaGaLaLaRaRaRaRaRaRaLaLaNaLaLaLaRaRaRaRaRaRaLaLaLaLaLaRaWaRaRaLaGaaaaaaaaaGaGaGaGaGaaaGaaaaaaaGaGaGaGaaaGaGaGaGaGaGaGaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaGaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgugugvgugugtaaaaaaaaaGaGaGaLaRaRaRaRaRaRaRaRaLaLaLaNaLaLaRaRaRaRaRaRaRaRaLaLaLgmaRaRaLaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaGaGaaaaaaaGaGaGaaaaaaaaaaaaaGaGaGaGaGaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaaaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwgxgvgvgvgygzaaaaaaaGaGaGaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaRaRaRaRaRaRaRaRaRaLaLaRaRaLaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagngxgvgvgvgygsaaaaaaaGaGaGaLaLaRaRaRaRaRaRaRaRaRaRaLaLaLaLaLaRaRaRaRaRaRaRaRaRaLaLaRaRaLaGaaaaaaaaaaaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgvgvgvgtaaaaaaaaaGaGaGaLaRaRaRaRaRaRaRaRaRaRaRaLfUaRaRaLaLaLaLaLaLfUaLaRaRaLaLaLaLaLaGaaaaaaaaaaaaaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgvgugvgtaaaaaaaaaGaGaGaLaRaRaRaRaRaRaRgAgAaRaRaRaLaRaRaRaLaLaLaLaLaLaLaLaRaRaLaNaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagtgBgBgBgtaaaaaaaaaGaGaGaLaRaLaLaRaRaRaRgAgAaRaRaRaRaRaRaRaRaRaRaRaRaRaLaLaRaRfUaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagwgogCgogzaaaaaaaaaGaGaGaLaLaLaRaRaRaRaRgAgAaRaRaRaRaRgDaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagngogCgogsaaaaaaaaaGaGaGaLaLaLaRaRaRaRaRgAgAaRaRaRaRaRgDaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaNaNaNaLaLaLaLaLaLaLaLaLaLfUaLaLaLaRaRaRaRaRaRaRaRaRaRaRaRaLaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaNaNaNaNaNaGaGaGaGaGaLaLaLaLaLfUaLaLaLaLaLaLaLaLaNaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index 16a7687f9a1..1467548e94e 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -140,7 +140,7 @@ "acJ" = (/obj/machinery/computer/secure_data,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "acK" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/obj/item/weapon/cartridge/detective,/obj/item/device/megaphone,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "acL" = (/obj/machinery/photocopier,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) -"acM" = (/obj/structure/flora/kirbyplants,/obj/machinery/newscaster/security_unit{pixel_y = 33},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) +"acM" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/newscaster/security_unit{pixel_y = 33},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/hos) "acN" = (/obj/machinery/light/small,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/closet/secure_closet/injection,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acO" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) "acP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/stool/bed,/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/execution{name = "\improper Prisoner Transfer Center"}) @@ -225,7 +225,7 @@ "aeq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/security/interrogationobs) "aer" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/camera{c_tag = "Brig Prison Hallway"; dir = 4; network = list("Prison","SS13")},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/permabrig) "aes" = (/obj/structure/lattice,/obj/machinery/camera{c_tag = "Brig Secure Armory Exterior South"; dir = 8; network = list("SS13")},/turf/space,/area/security/permabrig) -"aet" = (/obj/structure/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/item/weapon/gun/energy/advtaser{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/advtaser{pixel_x = 0; pixel_y = 0},/obj/item/weapon/gun/energy/advtaser{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) +"aet" = (/obj/structure/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/item/weapon/gun/energy/gun/advtaser{pixel_x = -3; pixel_y = 3},/obj/item/weapon/gun/energy/gun/advtaser{pixel_x = 0; pixel_y = 0},/obj/item/weapon/gun/energy/gun/advtaser{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) "aeu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/decal/warning_stripes/southeast,/obj/vehicle/secway,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/securearmoury) "aev" = (/obj/structure/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shield/riot,/obj/item/weapon/shield/riot,/obj/item/weapon/shield/riot,/turf/simulated/floor/plasteel{dir = 8; icon_state = "vault"; tag = "icon-vault (WEST)"},/area/security/securearmoury) "aew" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/carpet,/area/security/hos) @@ -384,7 +384,7 @@ "aht" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/securehallway) "ahu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 6},/area/security/securehallway) "ahv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/security/podbay) -"ahw" = (/obj/structure/flora/kirbyplants,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) +"ahw" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "ahx" = (/obj/structure/table/reinforced,/obj/item/device/flashlight,/obj/item/device/radio{pixel_y = 6},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "ahy" = (/obj/machinery/light,/obj/structure/table/reinforced,/obj/item/weapon/folder/red,/obj/item/weapon/pen,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{level = 1},/obj/item/device/radio/intercom/department/security{pixel_x = 0; pixel_y = -28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) "ahz" = (/obj/structure/table/reinforced,/obj/item/weapon/book/manual/security_space_law,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/podbay) @@ -796,7 +796,7 @@ "app" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/shuttle/pod_1) "apq" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "security_airlock"; name = "exterior access button"; pixel_x = -20; pixel_y = -20; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/space) "apr" = (/obj/effect/decal/warning_stripes/east,/turf/simulated/floor/engine/vacuum,/area/escapepodbay) -"aps" = (/turf/space,/area/shuttle/syndicate_elite/station) +"aps" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite) "apt" = (/obj/machinery/door/airlock/shuttle{id_tag = "s_docking_airlock"; name = "Labor Shuttle Airlock"; req_access_txt = "2"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 5; id = "laborcamp"; name = "labor camp shuttle"; rebuildable = 1; width = 9},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 5; id = "laborcamp_home"; name = "fore bay 1"; width = 9},/turf/simulated/shuttle/floor,/area/shuttle/siberia) "apu" = (/obj/machinery/light,/turf/simulated/floor/plating,/area/security/prisonershuttle) "apv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prisonershuttle) @@ -882,9 +882,9 @@ "aqX" = (/obj/effect/decal/cleanable/cobweb2,/obj/machinery/atmospherics/unary/portables_connector{layer = 2},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aqY" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "security_airlock"; pixel_x = -25; req_access_txt = "13"; tag_airpump = "security_pump"; tag_chamber_sensor = "security_sensor"; tag_exterior_door = "security_outer"; tag_interior_door = "security_inner"},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "aqZ" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) -"ara" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/shuttle/abandoned) +"ara" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/abandoned) "arb" = (/turf/simulated/shuttle/wall{tag = "icon-swall14"; icon_state = "swall14"; dir = 2},/area/shuttle/abandoned) -"arc" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/shuttle/abandoned) +"arc" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/abandoned) "ard" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) "are" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/turf/simulated/shuttle/wall/interior{tag = "icon-swall_f9"; icon_state = "swall_f9"},/area/shuttle/abandoned) "arf" = (/obj/machinery/sleeper{dir = 8},/obj/machinery/light{dir = 1},/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) @@ -1283,7 +1283,7 @@ "ayI" = (/turf/simulated/floor/plating{icon_state = "panelscorched"},/area/maintenance/fsmaint2) "ayJ" = (/turf/simulated/wall/rust,/area/maintenance/fsmaint2) "ayK" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) -"ayL" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"ayL" = (/obj/structure/stool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "ayM" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "ayN" = (/obj/machinery/power/terminal,/obj/machinery/light/small{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "ayO" = (/obj/structure/stool/bed,/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor/plating,/area/maintenance/fpmaint2) @@ -1316,7 +1316,7 @@ "azp" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (NORTH)"; icon_state = "wooden_chair_wings"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "azq" = (/obj/structure/stool/bed/chair/wood/wings{tag = "icon-wooden_chair_wings (NORTH)"; icon_state = "wooden_chair_wings"; dir = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/wood,/area/crew_quarters/mrchangs) "azr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/civilian/barber) -"azs" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"azs" = (/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "azt" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "azu" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/terminal,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "azv" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -1638,7 +1638,7 @@ "aFz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/crew_quarters/sleep) "aFA" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = -28},/obj/effect/landmark{name = "JoinLateCryo"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/sleep) "aFB" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) -"aFC" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aFC" = (/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aFD" = (/obj/structure/window/reinforced{dir = 8},/obj/effect/landmark/start{name = "Civilian"},/obj/machinery/door/window/westright{dir = 1; name = "Boxing Ring"},/turf/simulated/floor/wood,/area/crew_quarters/fitness) "aFE" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/fitness) "aFF" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/fitness) @@ -1759,7 +1759,7 @@ "aHQ" = (/obj/structure/table/woodentable,/obj/machinery/media/receiver/boombox,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aHR" = (/obj/structure/table/woodentable,/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aHS" = (/obj/structure/table/woodentable,/obj/item/toy/cards/deck,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) -"aHT" = (/obj/structure/disposalpipe/segment,/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aHT" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aHU" = (/obj/structure/table,/obj/item/weapon/paper/holodeck,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aHV" = (/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aHW" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/closet/crate,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/fsmaint2) @@ -1877,8 +1877,8 @@ "aKe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/wall,/area/crew_quarters/sleep) "aKf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutral"},/area/crew_quarters/fitness) "aKg" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) -"aKh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) -"aKi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aKh" = (/obj/structure/disposalpipe/segment,/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) +"aKi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aKj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aKk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aKl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) @@ -2033,13 +2033,13 @@ "aNe" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "maint1"; name = "Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/maintenance/fsmaint2) "aNf" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/fsmaint2) "aNg" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/maintenance/fsmaint2) -"aNh" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/arrival/station) +"aNh" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/shuttle/abandoned) "aNi" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/arrival/station) "aNj" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aNk" = (/obj/structure/window/full/shuttle{icon_state = "window4"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/arrival/station) "aNl" = (/obj/structure/window/full/shuttle{icon_state = "window8"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/arrival/station) "aNm" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/arrival/station) -"aNn" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/arrival/station) +"aNn" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/abandoned) "aNo" = (/obj/machinery/camera{c_tag = "Arrivals East"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry) "aNp" = (/obj/structure/closet/secure_closet/security,/obj/machinery/light{dir = 1},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/checkpoint2) "aNq" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/checkpoint2) @@ -2304,7 +2304,7 @@ "aSp" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor/plasteel,/area/storage/primary) "aSq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plasteel,/area/storage/primary) "aSr" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plasteel,/area/storage/primary) -"aSs" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel,/area/storage/primary) +"aSs" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/fitness) "aSt" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel,/area/storage/primary) "aSu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel,/area/storage/primary) "aSv" = (/obj/structure/table,/obj/item/weapon/weldingtool,/obj/item/weapon/crowbar,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/turf/simulated/floor/plasteel,/area/storage/primary) @@ -2416,7 +2416,7 @@ "aUx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/camera{c_tag = "EVA Southeast"; dir = 1; network = list("SS13")},/turf/simulated/floor/plasteel,/area/ai_monitored/storage/eva) "aUy" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aUz" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/light_switch{pixel_y = -25},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/ai_monitored/storage/eva) -"aUA" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/hallway/primary/central/north) +"aUA" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/hallway/primary/central/north) "aUB" = (/obj/machinery/light{dir = 1},/obj/machinery/camera{c_tag = "Central Hallway North"; dir = 2; network = list("SS13")},/obj/machinery/alarm{pixel_y = 23},/obj/item/flag/nt,/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/hallway/primary/central/north) "aUC" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "bluecorner"},/area/hallway/primary/central/north) "aUD" = (/turf/simulated/floor/plasteel,/area/hallway/primary/central/north) @@ -2466,7 +2466,7 @@ "aVv" = (/obj/structure/closet/coffin,/obj/machinery/door/window/eastleft{dir = 8; name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office) "aVw" = (/obj/item/weapon/storage/bible,/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 4; icon_state = "chapel"},/area/chapel/main) "aVx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor/plasteel,/area/escapepodbay) -"aVy" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/arrival/station) +"aVy" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/trade/sol) "aVz" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/arrival/station) "aVA" = (/obj/machinery/light,/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aVB" = (/obj/item/device/radio/intercom{name = "station intercom (General)"; pixel_y = -28},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) @@ -2553,7 +2553,7 @@ "aXe" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/engine,/area/escapepodbay) "aXf" = (/obj/machinery/light,/turf/simulated/floor/engine,/area/escapepodbay) "aXg" = (/obj/structure/spacepoddoor{luminosity = 3},/obj/machinery/door/poddoor/multi_tile/four_tile_ver{id_tag = "escapepodbay"; layer = 3.1; req_one_access_txt = "13"},/turf/simulated/floor/engine,/area/escapepodbay) -"aXh" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/arrival/station) +"aXh" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/trade/sol) "aXi" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry) "aXj" = (/obj/structure/stool/bed/chair/comfy/beige,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry) "aXk" = (/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry) @@ -2695,9 +2695,9 @@ "aZQ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/central/ne) "aZR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/hallway/primary/central/ne) "aZS" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=EVA2"; location = "Dorm"},/turf/simulated/floor/plasteel,/area/hallway/primary/central/ne) -"aZT" = (/obj/machinery/camera{c_tag = "Bar East"; network = list("SS13")},/obj/machinery/newscaster{pixel_y = 32},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aZT" = (/obj/machinery/camera{c_tag = "Bar East"; network = list("SS13")},/obj/machinery/newscaster{pixel_y = 32},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aZU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/bar) -"aZV" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Bartender"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/bar) +"aZV" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Civilian"},/turf/simulated/floor/plasteel,/area/storage/primary) "aZW" = (/obj/machinery/door/window{dir = 4; name = "Bar Door"; req_access_txt = "25"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/bar) "aZX" = (/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aZY" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/obj/structure/table/woodentable,/obj/item/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/simulated/floor/carpet,/area/crew_quarters/bar) @@ -2844,10 +2844,10 @@ "bcJ" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/effect/spawner/window/reinforced,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plating,/area/bridge) "bcK" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central/ne) "bcL" = (/turf/simulated/floor/plasteel{tag = "icon-stage_stairs"; icon_state = "stage_stairs"},/area/hallway/primary/central/ne) -"bcM" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bcN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bcO" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bcP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bcM" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Bartender"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/crew_quarters/bar) +"bcN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/stool,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bcO" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32},/obj/structure/stool,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bcP" = (/obj/structure/stool,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/obj/structure/table,/obj/item/weapon/kitchen/knife,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/kitchen) @@ -3007,7 +3007,7 @@ "bfQ" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "yellowcorner"},/area/bridge) "bfR" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plasteel,/area/bridge) "bfS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel{dir = 4; icon_state = "yellowcorner"},/area/bridge) -"bfT" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/device/multitool,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/bridge) +"bfT" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/bookcase,/obj/item/weapon/book/manual/sop_engineering,/obj/item/weapon/book/manual/sop_medical,/obj/item/weapon/book/manual/sop_science,/obj/item/weapon/book/manual/sop_security,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/book/manual/sop_legal,/obj/item/weapon/book/manual/sop_command,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) "bfU" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Blast Door Control"; pixel_x = 28; pixel_y = -2; req_access_txt = "19"},/obj/machinery/keycard_auth{pixel_x = 29; pixel_y = 8},/turf/simulated/floor/plasteel,/area/bridge) "bfV" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 4},/area/bridge) "bfW" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "greencorner"},/area/bridge) @@ -3057,7 +3057,7 @@ "bgO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall,/area/security/vacantoffice) "bgP" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/port) "bgQ" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/closet/wardrobe/white,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) -"bgR" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) +"bgR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/stool,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bgS" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "bgT" = (/obj/structure/table,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "bgU" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) @@ -3432,7 +3432,7 @@ "bnZ" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/wood,/area/library) "boa" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/wood,/area/library) "bob" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/machinery/light/small,/turf/simulated/floor/wood,/area/library) -"boc" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/library) +"boc" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/library) "bod" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) "boe" = (/turf/simulated/floor/carpet{icon_state = "carpetsymbol"},/area/chapel/main) "bof" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main) @@ -3461,7 +3461,7 @@ "boC" = (/obj/machinery/conveyor{dir = 1; id = "packageSort1"},/turf/simulated/floor/plating,/area/quartermaster/office) "boD" = (/obj/structure/stool,/turf/simulated/floor/plasteel{dir = 9; icon_state = "warning"},/area/quartermaster/office) "boE" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/quartermaster/office) -"boF" = (/obj/machinery/conveyor_switch/oneway{id = "packageSort2"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/quartermaster/office) +"boF" = (/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"; tag = "icon-pipe-j1 (WEST)"},/turf/simulated/wall,/area/storage/tools) "boG" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) "boH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/floor/plasteel,/area/hallway/primary/central/west) "boI" = (/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/hallway/primary/central/west) @@ -3485,13 +3485,13 @@ "bpa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bpb" = (/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bpc" = (/obj/machinery/power/apc{cell_type = 5000; dir = 1; name = "Captain's Office APC"; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bpd" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bpd" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bpe" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central/ne) "bpf" = (/obj/machinery/door/firedoor,/turf/simulated/floor/plasteel,/area/hallway/primary/central/ne) "bpg" = (/obj/structure/sign/directions/evac{dir = 4},/obj/structure/sign/directions/medical{dir = 4; pixel_y = 7},/obj/structure/sign/directions/science{dir = 4},/turf/simulated/wall,/area/crew_quarters/bar) "bph" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass{name = "Diner"},/turf/simulated/floor/plasteel,/area/crew_quarters/bar) "bpi" = (/obj/structure/sign/barsign,/turf/simulated/wall,/area/crew_quarters/bar) -"bpj" = (/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bpj" = (/obj/machinery/atm{pixel_x = 32; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bpk" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bpl" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bpm" = (/obj/machinery/camera{c_tag = "Starboard Primary Hallway 2"; dir = 2; network = list("SS13")},/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) @@ -3517,7 +3517,7 @@ "bpG" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/quartermaster/office) "bpH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bpI" = (/turf/simulated/floor/plasteel,/area/quartermaster/office) -"bpJ" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) +"bpJ" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west) "bpK" = (/obj/structure/table,/obj/machinery/requests_console{department = "Cargo Bay"; name = "Cargo Requests Console"; departmentType = 2; pixel_y = 30},/obj/item/stack/tape_roll,/obj/item/device/destTagger{pixel_x = 4; pixel_y = 3},/obj/item/device/destTagger{pixel_x = 4; pixel_y = 3},/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 1},/area/quartermaster/office) "bpL" = (/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/stack/packageWrap,/obj/item/weapon/rcs,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 5},/area/quartermaster/office) "bpM" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) @@ -3656,7 +3656,7 @@ "bsp" = (/obj/machinery/camera{c_tag = "Cargo Delivery Office"; dir = 4; network = list("SS13")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/telepad_cargo,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bsq" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "bsr" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) -"bss" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/bookcase,/obj/item/weapon/book/manual/sop_engineering,/obj/item/weapon/book/manual/sop_medical,/obj/item/weapon/book/manual/sop_science,/obj/item/weapon/book/manual/sop_security,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/book/manual/sop_legal,/turf/simulated/floor/plasteel{tag = "icon-cult"; icon_state = "cult"; dir = 2},/area/lawoffice) +"bss" = (/obj/structure/table/reinforced,/obj/item/weapon/book/manual/sop_command,/obj/item/device/aicard,/obj/item/device/multitool,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/bridge) "bst" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bsu" = (/obj/item/weapon/folder/blue,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bsv" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/bridge/meeting_room) @@ -3755,7 +3755,7 @@ "buk" = (/turf/simulated/wall/r_wall,/area/medical/morgue) "bul" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/ward) "bum" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/hallway/primary/starboard/east) -"bun" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) +"bun" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/hallway/primary/starboard/east) "buo" = (/turf/simulated/floor/plasteel{dir = 1; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/starboard/east) "bup" = (/turf/simulated/wall/r_wall,/area/assembly/robotics) "buq" = (/turf/simulated/floor/plasteel{dir = 10; icon_state = "purple"},/area/hallway/primary/starboard/east) @@ -3790,7 +3790,7 @@ "buT" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/quartermaster/storage) "buU" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/quartermaster/storage) "buV" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall,/area/quartermaster/office) -"buW" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office) +"buW" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/quartermaster/office) "buX" = (/obj/structure/stool/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Cargo Technician"},/turf/simulated/floor/plasteel,/area/quartermaster/office) "buY" = (/obj/structure/table/reinforced,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "buZ" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Mailing Room"; req_access_txt = "50"},/turf/simulated/floor/plasteel{icon_state = "bot"},/area/quartermaster/office) @@ -3830,7 +3830,7 @@ "bvH" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/reception) "bvI" = (/obj/machinery/camera{c_tag = "Medbay Lobby East"; network = list("SS13")},/obj/structure/stool,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) "bvJ" = (/obj/structure/stool,/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) -"bvK" = (/obj/machinery/newscaster{pixel_x = 30},/obj/machinery/alarm{pixel_y = 26},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/reception) +"bvK" = (/obj/machinery/newscaster{pixel_x = 30},/obj/machinery/alarm{pixel_y = 26},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/reception) "bvL" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/obj/machinery/bodyscanner,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "bvM" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/item/device/radio/intercom{broadcasting = 0; name = "station intercom (General)"; pixel_y = 25},/obj/machinery/body_scanconsole,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) "bvN" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/camera{c_tag = "Medbay Examination Room"; network = list("SS13")},/obj/structure/stool,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/medical/exam_room) @@ -4760,7 +4760,7 @@ "bNB" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 4},/area/hallway/primary/central/sw) "bNC" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id_tag = "hopqueue"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plasteel{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central/sw) "bND" = (/obj/structure/filingcabinet/chestdrawer,/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/crew_quarters/heads) -"bNE" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel Requests Console"; pixel_y = -30},/obj/machinery/camera{c_tag = "Head of Personnel's Office"; dir = 1; network = list("SS13")},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) +"bNE" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Head of Personnel's Desk"; departmentType = 5; name = "Head of Personnel Requests Console"; pixel_y = -30},/obj/machinery/camera{c_tag = "Head of Personnel's Office"; dir = 1; network = list("SS13")},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bNF" = (/obj/structure/table,/obj/machinery/photocopier/faxmachine{department = "Head of Personnel's Office"},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bNG" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bNH" = (/obj/machinery/blackbox_recorder,/turf/simulated/floor/bluegrid,/area/server) @@ -4839,7 +4839,7 @@ "bPc" = (/turf/simulated/wall,/area/hallway/primary/central/sw) "bPd" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = null; req_access_txt = "57"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bPe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/server) -"bPf" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; hackProof = 1; id_tag = "emergency_home"; name = "Escape Airlock"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bPf" = (/obj/machinery/door/airlock/external{aiControlDisabled = 0; hackProof = 1; id_tag = "emergency_home"; name = "Escape Airlock"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "bPg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/engine/gravitygenerator) "bPh" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/engineering{name = "Gravity Generator"; req_access_txt = "0"; req_one_access_txt = "10;30"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/engine/gravitygenerator) "bPi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/hallway/primary/central/se) @@ -5037,7 +5037,7 @@ "bSS" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) "bST" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/warning_stripes/yellow,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/storage) "bSU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) -"bSV" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/wrapsortjunction{dir = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) +"bSV" = (/obj/machinery/conveyor_switch/oneway{id = "packageSort2"},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 1; icon_state = "warning"},/area/quartermaster/office) "bSW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bSX" = (/obj/machinery/door/airlock/glass_command{name = "Research Director"; req_access_txt = "30"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bSY" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) @@ -5094,7 +5094,7 @@ "bTX" = (/obj/effect/spawner/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "cmooffice"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cmo) "bTY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/medbay2) "bTZ" = (/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay2) -"bUa" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/medical/cryo) +"bUa" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor/shutters{density = 0; dir = 2; icon_state = "shutter0"; id_tag = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cryo) "bUb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/wall,/area/medical/genetics) "bUc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/turf/simulated/wall,/area/medical/genetics) "bUd" = (/obj/machinery/computer/scan_consolenew,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{tag = "icon-whitepurple (WEST)"; icon_state = "whitepurple"; dir = 8},/area/medical/genetics) @@ -5114,7 +5114,7 @@ "bUr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) "bUs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"}) "bUt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall/r_wall,/area/crew_quarters/hor) -"bUu" = (/obj/machinery/power/apc{dir = 8; name = "RD Office APC"; pixel_x = -25},/obj/structure/cable,/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) +"bUu" = (/obj/machinery/power/apc{dir = 8; name = "RD Office APC"; pixel_x = -25},/obj/structure/cable,/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bUv" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/photocopier/faxmachine{department = "Research Director's Office"},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bUw" = (/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/item/weapon/cartridge/signal/toxins{pixel_x = 4; pixel_y = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera{c_tag = "Research Director's Office"; dir = 1; network = list("Research","SS13")},/obj/item/clothing/glasses/welding/superior,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/table/glass,/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) "bUx" = (/obj/structure/closet/secure_closet/RD,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/plasteel{dir = 2; icon_state = "cafeteria"; tag = "icon-cafeteria (NORTHEAST)"},/area/crew_quarters/hor) @@ -5222,12 +5222,12 @@ "bWv" = (/obj/structure/table,/obj/item/weapon/coin/silver,/turf/simulated/floor/plasteel,/area/quartermaster/qm) "bWw" = (/obj/structure/table,/obj/item/weapon/cartridge/quartermaster{pixel_x = 6; pixel_y = 5},/obj/item/weapon/cartridge/quartermaster,/obj/item/weapon/cartridge/quartermaster{pixel_x = -4; pixel_y = 7},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel,/area/quartermaster/qm) "bWx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/apmaint) -"bWy" = (/obj/machinery/light{dir = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/blueshield) +"bWy" = (/obj/machinery/light{dir = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/blueshield) "bWz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/blueshield) "bWA" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/blueshield) "bWB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/wood,/area/blueshield) "bWC" = (/obj/machinery/light{dir = 1},/obj/machinery/power/apc{dir = 4; name = "Blueshield Office APC"; pixel_x = 24; pixel_y = -3},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/blueshield) -"bWD" = (/obj/structure/table,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/item/device/eftpos,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) +"bWD" = (/obj/structure/table,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/storage/fancy/donut_box,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bWE" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/wood,/area/ntrep) "bWF" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/ntrep) "bWG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/wood,/area/ntrep) @@ -5544,7 +5544,7 @@ "ccF" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/apmaint) "ccG" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/door/window{dir = 1; name = "Desk Door"; req_access_txt = "67"},/turf/simulated/floor/wood,/area/blueshield) "ccH" = (/obj/structure/table/woodentable,/obj/item/ashtray/glass{pixel_x = -4; pixel_y = -4},/obj/item/weapon/lighter/zippo/blue{pixel_x = 7; pixel_y = 4},/turf/simulated/floor/plasteel{icon_state = "bcarpet05"},/area/blueshield) -"ccI" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue,/obj/item/weapon/folder/blue{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper/blueshield,/turf/simulated/floor/plasteel{icon_state = "bcarpet05"},/area/blueshield) +"ccI" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/coin/plasma,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/book/manual/sop_command,/obj/item/device/megaphone,/turf/simulated/floor/wood,/area/crew_quarters/captain) "ccJ" = (/obj/structure/sign/poster/legit{pixel_x = 32},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/blueshield) "ccK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/wall,/area/ntrep) "ccL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/ntrep) @@ -5582,7 +5582,7 @@ "cdr" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/medical/medbreak) "cds" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall,/area/medical/medbreak) "cdt" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/wall,/area/medical/medbreak) -"cdu" = (/obj/structure/flora/kirbyplants,/obj/machinery/door_control{id = "psychoffice"; name = "Privacy Shutters Control"; pixel_x = -25; pixel_y = 0},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/wood,/area/medical/psych) +"cdu" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/door_control{id = "psychoffice"; name = "Privacy Shutters Control"; pixel_x = -25; pixel_y = 0},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor/wood,/area/medical/psych) "cdv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/wood,/area/medical/psych) "cdw" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/wood,/area/medical/psych) "cdx" = (/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/turf/simulated/floor/wood,/area/medical/psych) @@ -6531,7 +6531,7 @@ "cvE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cvF" = (/obj/structure/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/toolbox/electrical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/device/radio{pixel_y = 6},/turf/simulated/floor/plasteel,/area/engine/mechanic_workshop) "cvG" = (/turf/simulated/floor/plasteel,/area/engine/mechanic_workshop) -"cvH" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) +"cvH" = (/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "cvI" = (/obj/structure/table/woodentable,/obj/structure/disposalpipe/segment,/obj/item/weapon/book/manual/sop_general,/turf/simulated/floor/wood,/area/library) "cvJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/aft) "cvK" = (/turf/simulated/wall,/area/assembly/assembly_line) @@ -6783,9 +6783,9 @@ "cAw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall,/area/engine/break_room) "cAx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor/plasteel,/area/engine/break_room) "cAy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/break_room) -"cAz" = (/obj/machinery/power/apc{dir = 4; name = "Centcomm Rep APC"; pixel_x = 24; pixel_y = -3},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/flora/kirbyplants,/turf/simulated/floor/wood,/area/ntrep) +"cAz" = (/obj/machinery/power/apc{dir = 4; name = "Centcomm Rep APC"; pixel_x = 24; pixel_y = -3},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/light{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/wood,/area/ntrep) "cAA" = (/obj/effect/landmark/start{name = "Station Engineer"},/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/plasteel,/area/engine/break_room) -"cAB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel,/area/engine/break_room) +"cAB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/engine/break_room) "cAC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/atmos/control) "cAD" = (/obj/machinery/door/airlock/atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/atmos/control) "cAE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1; initialize_directions = 11; level = 1},/turf/simulated/wall/r_wall,/area/atmos/control) @@ -6828,7 +6828,7 @@ "cBp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cBq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cBr" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cBs" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) +"cBs" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{level = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "cBt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/engine/break_room) "cBu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1; level = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/device/t_scanner,/turf/simulated/floor/plasteel,/area/engine/break_room) "cBv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/engine/break_room) @@ -6855,8 +6855,8 @@ "cBQ" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/asmaint) "cBR" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cBS" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) -"cBT" = (/obj/structure/flora/kirbyplants,/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/medical/patients_rooms) -"cBU" = (/obj/structure/flora/kirbyplants,/obj/effect/decal/warning_stripes/southwestcorner,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 6},/area/medical/patients_rooms) +"cBT" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/effect/decal/warning_stripes/southeastcorner,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/medical/patients_rooms) +"cBU" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/effect/decal/warning_stripes/southwestcorner,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 6},/area/medical/patients_rooms) "cBV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cBW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plasteel{tag = "icon-warnwhite (NORTH)"; icon_state = "warnwhite"; dir = 1},/area/medical/virology) "cBX" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/medical/virology) @@ -6962,11 +6962,11 @@ "cDT" = (/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) "cDU" = (/mob/living/carbon/human/monkey,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (EAST)"; icon_state = "whitegreen"; dir = 4},/area/medical/virology) "cDV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTH)"},/area/medical/virology) -"cDW" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHWEST)"; icon_state = "whitegreen"; dir = 10},/area/medical/virology) +"cDW" = (/obj/machinery/atmospherics/unary/vent_scrubber{on = 1},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHWEST)"; icon_state = "whitegreen"; dir = 10},/area/medical/virology) "cDX" = (/obj/structure/stool/bed/chair/office/light{dir = 4},/obj/effect/landmark/start{name = "Virologist"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cDY" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/mob/living/carbon/human/monkey,/turf/simulated/floor/plasteel{dir = 8; icon_state = "whitegreencorner"},/area/medical/virology) "cDZ" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8; initialize_directions = 11; level = 1},/turf/simulated/floor/plating,/area/medical/virology) -"cEa" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHEAST)"; icon_state = "whitegreen"; dir = 6},/area/medical/virology) +"cEa" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{tag = "icon-whitegreen (SOUTHEAST)"; icon_state = "whitegreen"; dir = 6},/area/medical/virology) "cEb" = (/mob/living/carbon/human/monkey,/turf/simulated/floor/plasteel{dir = 5; icon_state = "whitegreencorner"},/area/medical/virology) "cEc" = (/obj/machinery/light_switch{pixel_x = -4; pixel_y = 24},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4; initialize_directions = 11; level = 1},/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "viro_lab_airlock_control"; name = "Virology Lab Access Console"; pixel_x = 6; pixel_y = 24; req_one_access_txt = "39"; tag_exterior_door = "viro_lab_airlock_exterior"; tag_interior_door = "viro_lab_airlock_interior"},/obj/effect/decal/warning_stripes/northeastcorner,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreencorner"},/area/medical/virology) "cEd" = (/obj/structure/rack{dir = 1},/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/asmaint2) @@ -7209,7 +7209,7 @@ "cIG" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/AMinus,/obj/item/weapon/reagent_containers/blood/APlus,/obj/item/weapon/reagent_containers/blood/BMinus,/obj/item/weapon/reagent_containers/blood/BPlus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OPlus,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/item/weapon/reagent_containers/blood/random,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cIH" = (/obj/machinery/alarm{pixel_y = 25},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cII" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"; tag = "icon-warnwhite (NORTHEAST)"},/area/medical/virology) -"cIJ" = (/obj/structure/flora/kirbyplants,/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) +"cIJ" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology) "cIK" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/toxins/test_chamber) "cIL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/binary/valve/digital{color = ""; dir = 4; name = "Gas Mix Outlet Valve"},/turf/simulated/floor/plasteel,/area/atmos/distribution) "cIM" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor/plasteel{dir = 5; icon_state = "green"},/area/atmos/distribution) @@ -7452,7 +7452,7 @@ "cNp" = (/obj/machinery/floodlight,/turf/simulated/floor/plating,/area/storage/secure) "cNq" = (/obj/machinery/floodlight,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/storage/secure) "cNr" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/rig/engineering,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/rig/engineering,/obj/machinery/alarm{pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/storage/secure) -"cNs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/civilian/barber) +"cNs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 2; icon_state = "barber"},/area/civilian/barber) "cNt" = (/obj/machinery/portable_atmospherics/canister/toxins,/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/storage/secure) "cNu" = (/obj/machinery/camera{c_tag = "Engineering West"; dir = 4; network = list("SS13")},/obj/structure/dispenser,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel,/area/engine/engineering) "cNv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plasteel,/area/engine/engineering) @@ -8191,7 +8191,7 @@ "dbA" = (/turf/simulated/wall,/area/medical/patient_b) "dbB" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 101.325; on = 1; pressure_checks = 1},/turf/simulated/floor/plasteel{dir = 4; icon_state = "bluecorner"},/area/medical/patients_rooms) "dbC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/medical/patients_rooms) -"dbD" = (/obj/structure/flora/kirbyplants,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{dir = 5; icon_state = "blue"},/area/medical/patients_rooms) +"dbD" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{dir = 5; icon_state = "blue"},/area/medical/patients_rooms) "dbE" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/medical/patients_rooms) "dbF" = (/turf/simulated/wall/r_wall,/area/medical/patient_c) "dbG" = (/obj/structure/stool/bed,/obj/machinery/alarm{pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitered"},/area/medical/patient_c) @@ -8216,7 +8216,7 @@ "dbZ" = (/obj/machinery/iv_drip,/obj/machinery/light,/obj/item/device/radio/intercom{dir = 8; name = "station intercom (General)"; pixel_x = -28},/turf/simulated/floor/plasteel{dir = 10; icon_state = "whitered"},/area/medical/patient_c) "dca" = (/obj/structure/table/glass,/obj/machinery/computer/med_data/laptop,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1},/obj/machinery/door_control{id = "medprivacyc"; name = "Privacy Shutters"; pixel_y = -30},/turf/simulated/floor/plasteel{dir = 6; icon_state = "whitered"},/area/medical/patient_c) "dcb" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel{dir = 8; icon_state = "bluecorner"},/area/medical/patients_rooms) -"dcc" = (/obj/machinery/light,/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 10; icon_state = "blue"},/area/medical/patients_rooms) +"dcc" = (/obj/machinery/light,/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 10; icon_state = "blue"},/area/medical/patients_rooms) "dcd" = (/obj/machinery/atmospherics/unary/outlet_injector/on{dir = 1},/turf/simulated/floor/plating/airless,/area/maintenance/turbine) "dce" = (/obj/machinery/light_switch{pixel_x = -24; pixel_y = 4},/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 8},/area/medical/patients_rooms) "dcf" = (/obj/machinery/power/apc{dir = 4; cell_type = 15000; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "blue"},/area/medical/patients_rooms) @@ -8337,8 +8337,8 @@ "deq" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/weapon/crowbar/red,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "der" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/shuttle/escape) "des" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/shuttle/supply) -"det" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/shuttle/supply) -"deu" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/shuttle/supply) +"det" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/arrival/station) +"deu" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/arrival/station) "dev" = (/turf/simulated/shuttle/floor,/area/shuttle/supply) "dew" = (/turf/simulated/shuttle/wall{tag = "icon-swall3"; icon_state = "swall3"; dir = 2},/area/shuttle/supply) "dex" = (/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/supply) @@ -8358,9 +8358,9 @@ "deL" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall/interior{tag = "icon-swall_f6"; icon_state = "swall_f6"},/area/shuttle/supply) "deM" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"; dir = 2},/area/shuttle/supply) "deN" = (/turf/simulated/shuttle/wall{tag = "icon-swall15"; icon_state = "swall15"; dir = 2},/area/shuttle/supply) -"deO" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/shuttle/supply) +"deO" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/arrival/station) "deP" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plating/airless,/area/shuttle/supply) -"deQ" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/shuttle/supply) +"deQ" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/shuttle/arrival/station) "deR" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_l"; icon_state = "burst_l"},/turf/space,/area/shuttle/supply) "deS" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/shuttle/supply) "deT" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-burst_r"; icon_state = "burst_r"},/turf/space,/area/shuttle/supply) @@ -8408,8 +8408,8 @@ "dfJ" = (/obj/machinery/door/unpowered/shuttle,/obj/docking_port/mobile{dir = 8; dwidth = 10; height = 35; id = "whiteship"; name = "NT Medical Ship"; roundstart_move = "whiteship_away"; width = 21},/obj/docking_port/stationary{dir = 8; dwidth = 10; height = 35; id = "whiteship_home"; name = "north of SS13"; width = 21},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) "dfK" = (/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) "dfL" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) -"dfM" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/shuttle/abandoned) -"dfN" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/shuttle/abandoned) +"dfM" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f6"; icon_state = "swall_f6"; dir = 2},/area/shuttle/supply) +"dfN" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/shuttle/supply) "dfO" = (/obj/structure/window/full/shuttle{icon_state = "15"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/abandoned) "dfP" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/light{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) "dfQ" = (/obj/item/weapon/shard,/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/abandoned) @@ -8498,7 +8498,7 @@ "dhv" = (/obj/structure/rack,/obj/item/weapon/pneumatic_cannon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhw" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l"; icon_state = "propulsion_l"},/turf/space,/area/shuttle/vox) "dhx" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) -"dhy" = (/obj/structure/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) +"dhy" = (/obj/structure/rack,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhz" = (/obj/structure/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox) "dhA" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end (NORTH)"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 1},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) "dhB" = (/obj/structure/grille,/obj/structure/shuttle/window{tag = "icon-window5_end"; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5_end"; dir = 2},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox) @@ -8520,7 +8520,7 @@ "dhR" = (/obj/structure/closet/syndicate/suits,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "dhS" = (/obj/effect/landmark{name = "Syndicate-Uplink"; tag = ""},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "dhT" = (/obj/structure/table,/obj/item/device/aicard,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) -"dhU" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) +"dhU" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/crew_quarters/locker) "dhV" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate) "dhW" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_locked"; id_tag = "synd_outer"; locked = 0; name = "Ship External Access"; req_access = null; req_access_txt = "150"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "smindicate"; name = "Outer Airlock"; opacity = 0},/obj/machinery/door_control{id = "smindicate"; name = "External Door Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "150"},/obj/docking_port/mobile{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate"; name = "syndicate infiltrator"; roundstart_move = "syndicate_away"; width = 18},/obj/docking_port/stationary{dheight = 9; dir = 2; dwidth = 5; height = 22; id = "syndicate_nw"; name = "northwest of station"; width = 18},/turf/simulated/shuttle/plating,/area/shuttle/syndicate) "dhX" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate) @@ -8565,6 +8565,7 @@ "diK" = (/obj/structure/table,/obj/item/weapon/gun/syringe,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "diL" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "diM" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) +"diN" = (/obj/structure/table,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/item/device/eftpos,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/obj/item/weapon/book/manual/sop_command,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "diO" = (/obj/structure/table,/obj/item/weapon/grenade/syndieminibomb{pixel_x = 4; pixel_y = 2; pixel_z = 0},/obj/item/weapon/grenade/syndieminibomb{pixel_x = -1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "diP" = (/obj/structure/mirror{pixel_x = 28},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) "diQ" = (/obj/machinery/telecomms/allinone{intercept = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate) @@ -8734,13 +8735,67 @@ "dlY" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/book/manual/sop_engineering,/turf/simulated/floor/plasteel,/area/engine/break_room) "dlZ" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/book/manual/sop_science,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/xenobiology) "dma" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/ce,/obj/item/weapon/book/manual/sop_engineering,/turf/simulated/floor/plasteel{dir = 8; icon_state = "neutralfull"},/area/engine/chiefs_office) -"dmb" = (/obj/item/weapon/storage/fancy/donut_box,/obj/structure/table,/obj/item/weapon/book/manual/sop_general,/turf/simulated/floor/wood,/area/bridge/meeting_room) -"dmc" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/obj/item/weapon/coin/plasma,/obj/item/device/megaphone,/obj/item/weapon/book/manual/sop_general,/turf/simulated/floor/wood,/area/crew_quarters/captain) -"dmd" = (/obj/machinery/light{dir = 1},/obj/structure/bookcase,/obj/item/weapon/book/manual/sop_engineering,/obj/item/weapon/book/manual/sop_medical,/obj/item/weapon/book/manual/sop_science,/obj/item/weapon/book/manual/sop_security,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/book/manual/sop_legal,/turf/simulated/floor/wood,/area/ntrep) +"dmb" = (/obj/machinery/light{dir = 1},/obj/structure/bookcase,/obj/item/weapon/book/manual/sop_engineering,/obj/item/weapon/book/manual/sop_medical,/obj/item/weapon/book/manual/sop_science,/obj/item/weapon/book/manual/sop_security,/obj/item/weapon/book/manual/sop_service,/obj/item/weapon/book/manual/sop_supply,/obj/item/weapon/book/manual/sop_general,/obj/item/weapon/book/manual/sop_legal,/obj/item/weapon/book/manual/sop_command,/turf/simulated/floor/wood,/area/ntrep) +"dmc" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue,/obj/item/weapon/folder/blue{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper/blueshield,/obj/item/weapon/book/manual/sop_command,/turf/simulated/floor/plasteel{icon_state = "bcarpet05"},/area/blueshield) +"dmd" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/trade/sol) "dme" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "dmf" = (/obj/machinery/door/firedoor{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_engineering{name = "Mechanic Workshop"; req_access_txt = "70"; req_one_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/mechanic_workshop) "dmg" = (/obj/item/device/radio/intercom{pixel_y = -30},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/small,/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) "dmh" = (/obj/machinery/camera{c_tag = "Bar South"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/obj/machinery/gameboard,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"dmi" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f5"; icon_state = "swall_f5"; dir = 2},/area/shuttle/supply) +"dmj" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/trade/sol) +"dmk" = (/obj/machinery/door/airlock/external{frequency = 1450; icon_state = "door_locked"; id_tag = "trade_sol_outer"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "160"},/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dml" = (/obj/structure/window/full/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dmm" = (/obj/structure/grille,/obj/structure/shuttle/window,/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dmn" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/shuttle/trade/sol) +"dmo" = (/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/shuttle/trade/sol) +"dmp" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/space,/area/shuttle/trade/sol) +"dmq" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/trade/sol) +"dmr" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1450; id_tag = "trade_sol_pump"; req_access_txt = "160"; req_one_access_txt = "0"},/obj/machinery/airlock_sensor{frequency = 1450; id_tag = "trade_sol_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1450; id_tag = "trade_sol"; pixel_x = 25; req_access_txt = "160"; tag_airpump = "trade_sol_pump"; tag_chamber_sensor = "trade_sol_sensor"; tag_exterior_door = "trade_sol_outer"; tag_interior_door = "trade_sol_inner"},/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dms" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmt" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmu" = (/obj/machinery/light/spot{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/computer/shuttle/trade/sol,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmv" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmw" = (/obj/structure/shuttle/window,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dmx" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 4},/turf/space,/area/shuttle/trade/sol) +"dmy" = (/turf/simulated/shuttle/wall{icon_state = "swallc4"},/area/shuttle/trade/sol) +"dmz" = (/obj/machinery/door/airlock/external{frequency = 1450; icon_state = "door_locked"; id_tag = "trade_sol_inner"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "160"},/turf/simulated/shuttle/plating,/area/shuttle/trade/sol) +"dmA" = (/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmB" = (/obj/machinery/door/airlock/shuttle{id_tag = "s_docking_airlock"; req_access_txt = "160"},/obj/docking_port/mobile{dir = 8; dwidth = 2; height = 11; id = "trade_sol"; name = "sol trade shuttle"; roundstart_move = "trade_sol_base"; width = 5},/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "trade_sol_offstation"; lock_shuttle_doors = 1; name = "northwest of Cyberiad"; width = 5},/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmC" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/space,/area/shuttle/trade/sol) +"dmD" = (/obj/machinery/light/spot,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmE" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1450; master_tag = "trade_sol"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "160"},/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmF" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light/spot,/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmG" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/trade/sol) +"dmH" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/shuttle/supply) +"dmI" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/trade/sol) +"dmJ" = (/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "trade_dock"; name = "port bay 4 at Cyberiad"; width = 5},/turf/space,/area/space) +"dmK" = (/obj/machinery/door/airlock/external{id_tag = "trade_dock"},/turf/simulated/floor/plating,/area/hallway/secondary/entry) +"dmL" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (NORTH)"; icon_state = "propulsion"; dir = 1},/turf/space,/area/shuttle/syndicate_elite) +"dmM" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_r (NORTH)"; icon_state = "propulsion_r"; dir = 1},/turf/space,/area/shuttle/syndicate_elite) +"dmN" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite) +"dmO" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (NORTH)"; icon_state = "propulsion_l"; dir = 1},/turf/space,/area/shuttle/syndicate_elite) +"dmP" = (/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate_elite) +"dmQ" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{tag = "icon-heater (NORTH)"; icon_state = "heater"; dir = 1},/turf/simulated/floor/plating/airless,/area/shuttle/syndicate_elite) +"dmR" = (/obj/effect/landmark{name = "Syndicate-Commando-Bomb"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmS" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmT" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmU" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmV" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmW" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmX" = (/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmY" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "syndicate_elite"; name = "Side Hull Door"; opacity = 0; req_access_txt = "150"},/obj/docking_port/mobile{dir = 8; dwidth = 3; height = 5; id = "sst"; name = "SST shuttle"; roundstart_move = "sst_away"; width = 11},/obj/docking_port/stationary{dir = 8; dwidth = 3; height = 5; id = "sst_home"; name = "northwest of station"; width = 11},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dmZ" = (/obj/machinery/computer/pod{id_tags = list("syndicate_elite"); name = "Hull Door Control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dna" = (/obj/machinery/computer/shuttle/sst,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite) +"dnb" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite) +"dnc" = (/obj/machinery/door/airlock/external{id_tag = "s_docking_airlock"; name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{icon_state = "pdoor1"; id_tag = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite) +"dnd" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate_elite) +"dne" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite) +"dnf" = (/turf/simulated/floor/plating/airless,/area/shuttle/syndicate_elite) +"dng" = (/obj/structure/disposalpipe/sortjunction{dir = 4; icon_state = "pipe-j2s"; sortType = 0},/turf/simulated/wall,/area/quartermaster/office) +"dnh" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plasteel,/area/quartermaster/office) +"dni" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "brown"},/area/quartermaster/office) +"dnj" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/sortjunction{dir = 1; icon_state = "pipe-j1s"; sortType = 13},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"}) (1,1,1) = {" bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8774,15 +8829,15 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfvdfydfaardardarddfzardarddfhdfAdfBdftdfhardarddfCardardardardargcUKaaecUKareardardarddfDardardardargasRbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfvdfFdfEardardarddfrardarddfhardardarddfhardarddfGardardardardarddfHdfIdfHardardardardardardardardarddfJbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfvdfidfiardardarddfzardarddfhdfKdfwarddfhardarddfCardardardarddfscUKaaecUKdeWardardardardardarddfLdfsasRbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfvardardardardarddfhardardargaaeaaedfrareardarddfhdfxardarddfscUKdfMbikdfNasOaaeaaeaaeaaeaaeaaeaaeasOdfMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfOardardardarddfPdeYdeWardardardardardardardarddfharddfsarbasOdfMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfhdfRdfQdfSarddfscUKasOaaeaaearbdeWardardardarddeYaaecUKdfMdfobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfvardardardardarddfhardardargaaeaaedfrareardarddfhdfxardarddfscUKaNhbikaNnasOaaeaaeaaeaaeaaeaaeaaeasOaNhbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfOardardardarddfPdeYdeWardardardardardardardarddfharddfsarbasOaNhbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfhdfRdfQdfSarddfscUKasOaaeaaearbdeWardardardarddeYaaecUKaNhdfobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdeYdeWdfadfTdfscUKaredfVdfUdfWargasRardarddfkdfXdfldeZdfYaaeasPbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfNasOaaedfZasOareardardardardarddfhardarddfsarbasRdffdgadeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgbardardardardardardarddgcdfKdfscUKdfMdfNdgedgddeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgfarddggardardardardarddeYarbcUKdfMbikbikdfNdgedeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaagaafaajaaiaaiaaiaakaafaaJbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfNaaearbdeWarddghdgidfscUKasOdfMbikbikbikbikdfNarbdfnbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlbmOcaVbZycaXcaWccwccwbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdfNasOaaeaaeaaeasOdfMbikbikbikbikbikbikbikdfNdfMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNnasOaaedfZasOareardardardardarddfhardarddfsarbasRdffdgadeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgbardardardardardardarddgcdfKdfscUKaNhaNndgedgddeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgfarddggardardardardarddeYarbcUKaNhbikbikaNndgedeVdeUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaagaafaajaaiaaiaaiaakaafaaJbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNnaaearbdeWarddghdgidfscUKasOaNhbikbikbikbikaNnarbdfnbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlbmOcaVbZycaXcaWccwccwbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNnasOaaeaaeaaeasOaNhbikbikbikbikbikbikbikaNnaNhbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlccxcaVcaVccycaVcaVcczbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlcyacSKcaVcaVcTOcaVcTWbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcVGaafaafaafddwaafaafaafdelbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8790,13 +8845,13 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhNcaVdhObFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdhPaafaafaafaafbFldhNcaVdhOdhQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikaalaalaalaalaalaalaalaamaanaaoaapaalaalaalaalbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhRcaVcaVdhSbFldhNcaVdhObFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaaqaaraasaataauaaybnHbnIaavaayaazaaAaaBaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhRcaVdhUdhTbFldhNcaVdhObFlaafdhWdhVdhXbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaaCaaDaaEaaFaayaayaawaaGaaHaayaazaazaaIaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhRcaVayLdhTbFldhNcaVdhObFlaafdhWdhVdhXbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaaCaaDaaEaaFaayaayaawaaGaaHaayaazaazaaIaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhYcaVcaVdhZbFldiacaVcczdicdibdibdibbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaaqaayaaKaaLaaMaayaaNaaOaavaaPaataataalaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhRcaVcaVcaVdidcaVcaVdiedigdifdifdihbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdiibikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaataataataaQaaRaaSaawaaGaaHaaxaaTaaUaaVaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldhRcaVcaVcaVdijcaVcaVcaVaVUdikdikdimbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalaaWaaXaaYaaZabaabbabcabdabeabfabgabhabhaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdhPaafaafaafaafaafaafdincaVcaVaafaafaafaafaafaafdhXbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabiabjabkablabmabnaboabpabqabraatabsabtaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdiobikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldipdipdiqdisdirbFlditcaVcaVbFldiudiwdivdiydixbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikaalabuaalabvabwabxabxaalaalabyaaoaalaalabzaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlcaVcaVcaVdhUcaVdizcaVcaVcaVdiAcaVdhUcaVdhUdiBbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabBaatabCabDabEabFbikbikbikbikbikaalabGaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikabAcQScJadgjbikbikbikabAbikbikbikdgjbikbikbikabAdiCdgldgjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlcaVcaVcaVayLcaVdizcaVcaVcaVdiAcaVayLcaVayLdiBbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabBaatabCabDabEabFbikbikbikbikbikaalabGaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikabAcQScJadgjbikbikbikabAbikbikbikdgjbikbikbikabAdiCdgldgjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldiDdiEcaVcaVcaVdiFcaVcaVcaVdiGcaVcaVcaVcaVdiHbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabBaatabCabHaalbikbikbikbikbikbikaalaalaalbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgmdgodgndgmbikbikabAdgmdgpdgrdgqdgmdgjbikbikdgmdgsdgtdgmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFldiIdiEcaVdiKdiJbFldiLdiMdiLbFlaWldiOcaVcaVcaVbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikaalaalaalaalabuaatabIabJaalaalaalaalbikbikbikabKabLabLabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgmdgvdgudgmbikabAdgwdgydgxdgAdgzdgydgwdgjbikdgmdgBdgCdgmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbFlcaVcaVdiPbFlaafbFlcaVdiRdiQbFlaafbFlcaVcaVcaVbFlbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaalabMabNabOabPabQabRabSabTabUabVaalbikbikbikbikabKabLabWabKbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdgmdgEdgDdgFbikdgHdgGdgydgydgIdgydgydgGdgJbikdgLdgKdgMdgmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik @@ -8817,83 +8872,83 @@ bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbi bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaeAafyafAafyaeAafyafAafyaeAbikagSahCahDahEahFahGahHahIahJahKahLahMahNagvahOahRahQairahSahTahUahVahWahXahYahZahUaiaaibaicaidahYahZahUahUahAadaadaadaadaadaaieaieaieahAbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikagQaabaabaabahBaabaabaabagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGafxacGacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaeAafyafyafAaeAafyafyafAaeAbikagSaifaigaihagSaiiaijaikailaimainaioaipagvaiqaisahhamuaitaiuahUaivaiwaixaiyaizaiAaiBaiCaiDaiEaiFaiGbOIaiHahAaieaieaieaieaieaieaieaieahAbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikagQbikbikbikaiIbikbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikaabbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaeAafAafyaiJaeAafAafyaiKaeAbikagSaiLaiMaiNagSaiOaiOaiOaiOaiPaiQaiRaiSagvaiTaiUaiVaiWaiXaiYahUaiZajaajbajcajdajeajfajgaiDaiEajhaiGajhajiahAaieaieaieaieaieaieaieaieahAagQagQajjaabagQagQagQagQagQagQagQagQagQagQagQagQagQagQaabaabajkajlajmaabaabagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikafxaabajnaabafxbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikaeAajoajpajqajrajoajpajqajsajtajuajuajuajuajuajuajuajuajvajwajxajyajzajAajBajCajDajEajFajGahUajHajIajJajKajdajeajKajgajLaiEaiCaiCajMajNajOaieaieaieaieaieaieaieaieahAaabaabaabaabaabaabbikaabbikaabaabaabaabaabaabaabaabbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGacGacGafxafxaabaabbikajQbikaabaabafxafxacGacGacGbikbikbikbikbikbikbikbikbikbikbikbikaeAajRajSajTafyajUajVajWakcajtajYajZakaakbaknakdakdajuakeakfakgakhakiajBakjakkaklakmalJajFakoakpamwakqajKakraksaktakuakvakwakxakxakzaiCakAaieaieaieaieaieaieaieaieahAaabakBakCakCakCakDakCakCakCakCakDakCakCakCakCakEaabbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikbikaabbikaabbikbikajQbikbikaabbikaabbikbikacGbikbikbikbikbikbikbikbikbikbikbikbikaeAakFafyakGakHakIakJakKakLajtakMakNakOakOakPakQakRajuakSakTakUakVakiakWakXakYakZalaalbalcaldaleaAEalfalgalhalialjalkallalmaiCaiCaiCalnajOaieaieaieaieaieaieaieaieahAaabaloaabaabaabaloaabbikbikaabaloaabaabbikbikaloaabbikaabaabajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabalpalpalpalpalpbikalqbikalpalpalpalpalpaabacGbikbikbikbikbikbikbikbikbikbikbikbikaeAalralsakGafyaltakJalualvajtalwalxalyalzakQakQakRajualAalBalCalDalEajBalFalGaklalHalIajFajXalKalLalLalMajdalNalOalPalQaiCaiFaiGaiCalRahAahAahAahAahAahAahAahAahAahAaabaloaabbikajkajlajmbikbikajkajlajmbikbikajkajlajmaabaabbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamaalZaowanxambbikbikbikamcaeAaeAaeAamdamdameamfamgamdajuamhamiamjamkamlammamnajuamoampamqakVamrajGamsamtaXNamvaYjajGamxamyamzamAamBamCamDamEamFamGaiCajhamHamIamJahAamKamKamKamKamKbikbikbikbikaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaVydmddmkdmjdmldmddmddmmdmddmddmnbikbikbikbikbikbikbikbikbikafxaabajnaabafxbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikaeAajoajpajqajrajoajpajqajsajtajuajuajuajuajuajuajuajuajvajwajxajyajzajAajBajCajDajEajFajGahUajHajIajJajKajdajeajKajgajLaiEaiCaiCajMajNajOaieaieaieaieaieaieaieaieahAaabaabaabaabaabaabbikaabbikaabaabaabaabaabaabaabaabbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmpdmodmrdmqdmtdmsdmsdmsdmvdmudmwbikbikbikacGacGacGafxafxaabaabbikajQbikaabaabafxafxacGacGacGbikbikbikbikbikbikbikbikbikbikbikbikaeAajRajSajTafyajUajVajWakcajtajYajZakaakbaknakdakdajuakeakfakgakhakiajBakjakkaklakmalJajFakoakpamwakqajKakraksaktakuakvakwakxakxakzaiCakAaieaieaieaieaieaieaieaieahAaabakBakCakCakCakDakCakCakCakCakDakCakCakCakCakEaabbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmxdmodmzdmydmsdmAdmAdmAdmAdmAdmBbikbikbikacGbikbikaabbikaabbikbikajQbikbikaabbikaabbikbikacGbikbikbikbikbikbikbikbikbikbikbikbikaeAakFafyakGakHakIakJakKakLajtakMakNakOakOakPakQakRajuakSakTakUakVakiakWakXakYakZalaalbalcaldaleaAEalfalgalhalialjalkallalmaiCaiCaiCalnajOaieaieaieaieaieaieaieaieahAaabaloaabaabaabaloaabbikbikaabaloaabaabbikbikaloaabbikaabaabajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmCdmodmEdmDdmAdmAdmAdmAdmGdmFdmwbikbikbikacGaabalpalpalpalpalpbikalqbikalpalpalpalpalpaabacGbikbikbikbikbikbikbikbikbikbikbikbikaeAalralsakGafyaltakJalualvajtalwalxalyalzakQakQakRajualAalBalCalDalEajBalFalGaklalHalIajFajXalKalLalLalMajdalNalOalPalQaiCaiFaiGaiCalRahAahAahAahAahAahAahAahAahAahAaabaloaabbikajkajlajmbikbikajkajlajmbikbikajkajlajmaabaabbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaXhdmddmddmddmldmddmddmmdmddmddmIbikbikbikacGbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamaalZaowanxambbikbikbikamcaeAaeAaeAamdamdameamfamgamdajuamhamiamjamkamlammamnajuamoampamqakVamrajGamsamtaXNamvaYjajGamxamyamzamAamBamCamDamEamFamGaiCajhamHamIamJahAamKamKamKamKamKbikbikbikbikaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikamOamNamQamPamOamRamSamSamTamUamVamWamXamYamZanaanbancajuajuandaneajuajuajuajuajuanfanganhanianfajGajBajCanjajEajFajGankanlanmannahUahUahUahUannanoanpanmahUahAayjahAanrantansansanubikbikbikbikbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGbikbikbikaabbikbikbikanvbikbikbikaabbikbikbikaabbikbikbikaEEanwanzanyanBanAanDanCanAanGanGanHanIanJanKanLanManNanOanPanQanRanSanTanSanSanUanVanWanXanYanSanZaoaaobaocaodaoeaofaogaohanSaoiaojaokaolaomaonaooaopaoqaoraosaplaotaovaEHaouaoyaoxbikbikbikbikbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikajkajPajmbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikacGaabalpalpalpalpalpbikamMbikalpalpalpalpalpaabacGbikbikbikamOanEaoAanFamOamRamSamSamSaoBaoHaoIaoJaoKaoLaoMaoNaoOaoPaoQaoRaoSaoTaoUaoVaoWaoXaoYaoWaoZapaaoTapbapcapdaoTaoTapdaoXapcapeaoTaoTapbapcaoVapfapgaphapiapjapkaplapmapnaovaozansansapobikaacapqaacbikaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikaabaabajkajPajmaabaabagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikajjbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamOaoCaoCaoDamObikbikbikapwapwapxapyapzapAapAapAapBapBapBapBapCapDapEapEapEapFapGapHapFapEapEapEapIapJapKapLapMapKapNapJapOapOapOapPapQapOapRapSapTapUapVapWapXapmapnapYapYamKapZapZapZamKaqaamKaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmaabaabbikaabaiIaabbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGaqbamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikaEEaoEaoCaoFamOamRamSamSamSaqgaqhaqiaqjaqkaqlaqmapBaqnaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaqAaqsaqBaqCaqDaqEaqFaqGaqHaqCapOaqIaqJaqKaqLapOaqMaqNaqOaqPaqQaqRapXapmaqSaqTaqUaqVaqWaqWaqXamKaqYamKaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikaabaloaabbikbikaqZbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGbikbikbikaabbikbikbikanvbikbikbikaabbikbikbikacGbikbikbikamOaoGaoCaoCaptanAapuanCanAapvanLarharianGanGarjapBarkarlarmarnaroarparqarrarsartaruarvarrarwarxaryarzarAarBarCarDarEarFarGarHarIarJarKapOarLarMarMarNarMarOapXapmaovaovaovaovarPaovarQarRarSamKakBarTakEbikbikaiIaabaabaabaabaiIaabaabaabaabaiIaabaabaabaabarUarVakEaabbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGaabalpalpalpalpalpbikamMbikalpalpalpalpalpaabacGbikbikbikamOaqcaqcaqcamOamRamSamSamSarXarYaoMarZasaanGasbapBascasdaseasfasgashasiasjaskaslasmasnasoaspashasqarFasrassastasrarEasuapOarGaswasxasyapOaszasAarMarNarMasBapXasCasDasEasFasEasGasHamKamKapnamKaloasIasJakCakCarTakCakCakCakCarTakCakCakCakCarTakCakCakCasKasLasIaloaabbikagQaabbikbikbikbikbikbikbikbikbikbikaabbikaabbikasMasMasNasNasNasNasNasNasMasMaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikaqeaqdaqdaqdaqfbikbikbikapwapwapwapwapwasSanGasTasUapBatRapBasVasWapEapEatSapEasXasYapEatSapEasZataatbatcatdateatfatgathapOatiatjatkatlatmatnatoatpatqarMatrapXatsattatuatvatwatxatyatzatAatBamKatCarTatDaabaabbikaabbikbikbikbikbikbikbikbikaabaabaabaabaabatEatFatDaabaabaabaabaabbikbikbikbikbikbikbikbikbikaabbikaabasMasMatGatHatIatJatKatLatMatIasMasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikaabatNamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapwatOanGasTasUatPatUatTauyatVaqsatQauJauEavxauTavEavBatWaqsatXatYatZauaaubaubaucaudapOaueaufaugauhapOauiaujaukarNarMaulapXatsarPattattattaumaovaunauoaupamKbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikaabaabaabaabauqaabaabbikbikaabaabaabbikbikbikbikbikbikbikbikasMasMasMasMauratJausatJausautatJatJatJauuasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGbikbikaabbikaabbikbikauvbikbikaabbikaabbikbikacGbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikapwauwanGauxasUarkavJauzauAauBauCauDdlLauFauGauHauIdlMauKauLauMauNauNauOauNauNauPauQauRauSdlNapOauUapOauVauWauXauYauZavaapXatsavbavcavcavcavdaveavfavgavhamKbikbikbikbikbikaahbikbikbikbikbikbikbikaabaabbikbikbikaabaabaabaviaabaabbikbikaabbikaabaabbikbikbikbikbikbikbikasMavjavkavlavmavnavoavpatJatJavqavratJavsasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikacGacGacGaabaabaabaabavtavuavtaabaabaabaabacGacGacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapwavvanGavwasUdlPdlQavyavzavAashdlRdlSashavCavDashdlTdlUashavFavGavHavGavGavHavGavIapOatidlVapOavKapOavLavMavNavOavPavQavRavSavTavUavUavUavVavWavXavYavYavYbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikaabaabavZawaavZaabaabbikaabbikbikaabaabbikbikbikbikbikbikasMawbawcawdaweawfawgatJatJatJawhawiatJawjasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikaahbikbikbikbikaabbikaabbikbikaabbikavtawkawlbikbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmawmawmawmawmawmapwapwawnapwasUasUasUawoawpawqawrawrawsawrawsawrawrawtasZasZasvawvawwawuawvawwawuawyawzawzawzawzawzapOawAawBawCawCawDawCawEawFavUawGawHawIavVawJawKawLawMavWbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikaabbikavZawNavZbikaabbikaabbikbikbikaabaabbikbikbikbikbikasMawOawPavlawQawRawSawTatJawUawVawWawXasMawYaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsapsapsbikbikbikbikbikbikaabbikaabbikbikaabavtavtawZaxaavtbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxbaxcaxdaxeaxfaxgaxhaxiaxhaxjaxhaxhaxkaxlaxlaxlaxlaxlaxmaxnaxoaxlaxlaxlaxlaxpaxlaxlaxlaxlaxqaxraxsaxtaxuaxvaxwaxxapWaxyaxzaxAaxBaxCaxDaxEaxFavUaxGaxHaxIavVaxKaxLaxJaAZavWbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikaabavZavZaxMavZavZaabbikaabbikbikbikbikaabaabbikbikbikbikasMaxNaxOavlasMavlavlaxPaxQasMasMasMasMasMasMaabaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsapsapsbikbikbikbikbikbikaabaabbikaabbikbikaabaxRaxSaxTaxUaxRaxVaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqaSWaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikaabayCayDayEayFayCaabbikaabbikbikaabbikbikaabaabbikbikayGasMavlasMavlayHayIayHayJayHayHayHayKayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaxVaxVaxVaxVaxVaabaabaxRayLayMayNaxRayOaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmayPayQayRaySayTawmayUayVayWayXayYayZazaazbazcayXayXayXazdayXayXayXayXayXayXazeazfazgazgazgazhaziazjaziazkazlazmaznapWazoazoazoazoazoazoaxEaxFavUazpaxHazqavVcscazraxJcvYavWbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikbikaabayCazsaztazuayCaabbikaabbikbikaabbikbikayGazvayGazvayGayKayHayHayHayHayHayHayHayHayHazwazxayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapsdmMdmLdmOdmNbikbikbikbikbikbikajjbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikamOaoCaoCaoDamObikbikbikapwapwapxapyapzapAapAapAapBapBapBapBapCapDapEapEapEapFapGapHapFapEapEapEapIapJapKapLapMapKapNapJapOapOapOapPapQapOapRapSapTapUapVapWapXapmapnapYapYamKapZapZapZamKaqaamKaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmaabaabbikaabaiIaabbikbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmQdmQdmQdmPbikbikbikbikbikbikacGaqbamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikaEEaoEaoCaoFamOamRamSamSamSaqgaqhaqiaqjaqkaqlaqmapBaqnaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaqAaqsaqBaqCaqDaqEaqFaqGaqHaqCapOaqIaqJaqKaqLapOaqMaqNaqOaqPaqQaqRapXapmaqSaqTaqUaqVaqWaqWaqXamKaqYamKaabaloaabbikajkajPajmbikbikajkajPajmbikbikajkajPajmbikbikbikaabaloaabbikbikaqZbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmRdmRdmRdmPbikbikbikbikbikbikacGbikbikbikaabbikbikbikanvbikbikbikaabbikbikbikacGbikbikbikamOaoGaoCaoCaptanAapuanCanAapvanLarharianGanGarjapBarkarlarmarnaroarparqarrarsartaruarvarrarwarxaryarzarAarBarCarDarEarFarGarHarIarJarKapOarLarMarMarNarMarOapXapmaovaovaovaovarPaovarQarRarSamKakBarTakEbikbikaiIaabaabaabaabaiIaabaabaabaabaiIaabaabaabaabarUarVakEaabbikagQbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmTdmSdmUdmPbikbikbikbikbikbikacGaabalpalpalpalpalpbikamMbikalpalpalpalpalpaabacGbikbikbikamOaqcaqcaqcamOamRamSamSamSarXarYaoMarZasaanGasbapBascasdaseasfasgashasiasjaskaslasmasnasoaspashasqarFasrassastasrarEasuapOarGaswasxasyapOaszasAarMarNarMasBapXasCasDasEasFasEasGasHamKamKapnamKaloasIasJakCakCarTakCakCakCakCarTakCakCakCakCarTakCakCakCasKasLasIaloaabbikagQaabbikbikbikbikbikbikbikbikbikbikaabbikaabbikasMasMasNasNasNasNasNasNasMasMaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmVdmSdmUdmPbikbikbikbikbikbikacGbikalSalTalTalTalTalUalValWalXalXalXalXalYbikacGbikbikbikaqeaqdaqdaqdaqfbikbikbikapwapwapwapwapwasSanGasTasUapBatRapBasVasWapEapEatSapEasXasYapEatSapEasZataatbatcatdateatfatgathapOatiatjatkatlatmatnatoatpatqarMatrapXatsattatuatvatwatxatyatzatAatBamKatCarTatDaabaabbikaabbikbikbikbikbikbikbikbikaabaabaabaabaabatEatFatDaabaabaabaabaabbikbikbikbikbikbikbikbikbikaabbikaabasMasMatGatHatIatJatKatLatMatIasMasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmVdmSdmUdmPbikbikbikbikbikbikaabatNamLamLamLamLamLbikamMbikamLamLamLamLamLaabacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapwatOanGasTasUatPatUatTauyatVaqsatQauJauEavxauTavEavBatWaqsatXatYatZauaaubaubaucaudapOaueaufaugauhapOauiaujaukarNarMaulapXatsarPattattattaumaovaunauoaupamKbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikaabaabaabaabauqaabaabbikbikaabaabaabbikbikbikbikbikbikbikbikasMasMasMasMauratJausatJausautatJatJatJauuasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmSdmSdmSdmWbikbikbikbikbikbikacGbikbikaabbikaabbikbikauvbikbikaabbikaabbikbikacGbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikapwauwanGauxasUarkavJauzauAauBauCauDdlLauFauGauHauIdlMauKauLauMauNauNauOauNauNauPauQauRauSdlNapOauUapOauVauWauXauYauZavaapXatsavbavcavcavcavdaveavfavgavhamKbikbikbikbikbikaahbikbikbikbikbikbikbikaabaabbikbikbikaabaabaabaviaabaabbikbikaabbikaabaabbikbikbikbikbikbikbikasMavjavkavlavmavnavoavpatJatJavqavratJavsasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmXdmSdmSdmYbikbikbikbikbikbikacGacGacGaabaabaabaabavtavuavtaabaabaabaabacGacGacGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikapwavvanGavwasUdlPdlQavyavzavAashdlRdlSashavCavDashdlTdlUashavFavGavHavGavGavHavGavIapOatidlVapOavKapOavLavMavNavOavPavQavRavSavTavUavUavUavVavWavXavYavYavYbikbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikaabaabavZawaavZaabaabbikaabbikbikaabaabbikbikbikbikbikbikasMawbawcawdaweawfawgatJatJatJawhawiatJawjasMbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmPdmZdmSdnadmPbikaahbikbikbikbikaabbikaabbikbikaabbikavtawkawlbikbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmawmawmawmawmawmapwapwawnapwasUasUasUawoawpawqawrawrawsawrawsawrawrawtasZasZasvawvawwawuawvawwawuawyawzawzawzawzawzapOawAawBawCawCawDawCawEawFavUawGawHawIavVawJawKawLawMavWbikbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikaabbikavZawNavZbikaabbikaabbikbikbikaabaabbikbikbikbikbikasMawOawPavlawQawRawSawTatJawUawVawWawXasMawYaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdnbdnddncdnddnebikbikbikbikbikbikaabbikaabbikbikaabavtavtawZaxaavtbikaabbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxbaxcaxdaxeaxfaxgaxhaxiaxhaxjaxhaxhaxkaxlaxlaxlaxlaxlaxmaxnaxoaxlaxlaxlaxlaxpaxlaxlaxlaxlaxqaxraxsaxtaxuaxvaxwaxxapWaxyaxzaxAaxBaxCaxDaxEaxFavUaxGaxHaxIavVaxKaxLaxJaAZavWbikbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikaabavZavZaxMavZavZaabbikaabbikbikbikbikaabaabbikbikbikbikasMaxNaxOavlasMavlavlaxPaxQasMasMasMasMasMasMaabaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdnbdnfdnebikbikbikbikbikbikaabaabbikaabbikbikaabaxRaxSaxTaxUaxRaxVaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqaSWaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWbikbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikaabayCayDayEayFayCaabbikaabbikbikaabbikbikaabaabbikbikayGasMavlasMavlayHayIayHayJayHayHayHayKayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikaxVaxVaxVaxVaxVaabaabaxRazsayMayNaxRayOaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmayPayQayRaySayTawmayUayVayWayXayYayZazaazbazcayXayXayXazdayXayXayXayXayXayXazeazfazgazgazgazhaziazjaziazkazlazmaznapWazoazoazoazoazoazoaxEaxFavUazpaxHazqavVcscazraxJcvYavWbikbikbikbikbikbikbikbikaabaabbikbikbikbikbikbikbikbikaabayCaFCaztazuayCaabbikaabbikbikaabbikbikayGazvayGazvayGayKayHayHayHayHayHayHayHayHayHazwazxayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikazyazzazybikbikbikaxVaxVaxVaxVazAazBazCaxVbikbikaxRazDazEazFazGazHaxVbikbikaabbikbikbikbikbikbikbikbikbikbikawmawmawmawmawmawmawmazIazIazJazKazKazLazMazNazOazPazPazOazQazOazRazRazRazRazRazRazSazRazRazTazUazVazWazIazXazIazYazIazIaqVazZaovaovaovaovaAaaxFavUaAbaxHaAcavVaAdayAayBawMavWbikbikbikbikbikbikbikbikaabaabbikbikbikbikazyaAeazybikaabayCaAfaAgaAhayCaAiaAiaAiaAiaAiazvazvazvayGaAjayHazwazxayJayHayJayJayJayGaAkayGayGayGayGayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikaAlaAmaAlbikbikaabaxVaAnaAoaApazHaAqazHaxVaAlaAlaxRaxRaAraAsazGazHaxVaxVaAlaAlaAlaxVaxVbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikazJaAtaAuaAvazMaAwazOaAxaAyaAzaAAaABaACaADbssaAFaAGaAHaAIaAJaAKaALaxqaxraAMaANaAOaAPaAQaAPaAPaAPaARaAPaAPaAPaAPaASaATaAUaAVaAWaAXaAYcNsaBaaUadcuavWaabaBbaBcaBcaBcaBcaBcaBdaabaabbikbikbikbikazvaBeazvbikaAiayCayCaBfaBgayCaBhayHayHayHayJaBiayHaBjayGayHayHayHaBkayJayHayGaBlaBmayGayHaBnayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabbikaAlaAmaAlbikbikaabaxVaAnaAoaApazHaAqazHaxVaAlaAlaxRaxRaAraAsazGazHaxVaxVaAlaAlaAlaxVaxVbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikazJaAtaAuaAvazMaAwazOaAxaAyaAzaAAaABaACaADbfTaAFaAGaAHaAIaAJaAKaALaxqaxraAMaANaAOaAPaAQaAPaAPaAPaARaAPaAPaAPaAPaASaATaAUaAVaAWaAXaAYcNsaBaaUadcuavWaabaBbaBcaBcaBcaBcaBcaBdaabaabbikbikbikbikazvaBeazvbikaAiayCayCaBfaBgayCaBhayHayHayHayJaBiayHaBjayGayHayHayHaBkayJayHayGaBlaBmayGayHaBnayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikappaBpaBobikaBqaBsaBraabaabaAlazHaAlbikbikaabaxVaBuaBvaBwaBxaByaBzaxVaBAazHaBBaBCaBDaBEaBEaBEaBEaBEaBEaBEaBEaBFaxVbikaBGbikbikbikbikbikbikbikbikbikbikbikbikbikbikaBHaBIaBJaBKazMaAwazOaBLafvaBNaAAaABaBOaBPaBPaBPaBPaBPaAIbjlaAKaxlaxqaxrazIaBQaBRaBSaBTaBSaBSaBUaBVaBWaBWaBWaBWaBWaBWaBXaBYaBZaCaaCbaCcaCdaCeavWavWaCfaCgaChaChaChaChaChaCgaCfaabbikbikbikbikazvaCiaCjbikaAiaCkaClaCmaCnayHayHayHayJayHayJaCoayHayHayGayHaCpaCqaCoaAkayHayGaCraCsayGayHaCtayGbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaCuaBtaCvaBtaCuaCwaCxaCwaCuaabaAlaCzaCAbikbikaxVaxVaxVaxVaxVaCBaCCaCDaCEaCFaCGaCGaCHaCIaCIaCJaCKaxVazHaxVaxVaxVaCLaxVbikaabbikbikbikbikbikbikaabaabaabaabaabaabaabaabaCMaCNaCOaBKazMaAwazOaCPaCQaCRaAAaCSaCTaBPaCUaBPaCVaCVaAIaBPaAKaxlaxqaCWazIaCXaBRaCYaCZaDaaDbaDcaDdaDeaDfaDgaDhaDiaDjaDkaDlaDmaDnaDoaDpaDqaDraDsaDtaCfaCgaChaChaChaChaChaCgaCfaabaabaabaabazvazvaDuaDvazvaAiaDwayHaDxayHayKayHayGayGaDyayGayGaDzayJayJaCoaDAaDBayHayGayHaDCaDCaDCaDCaDCaDCaDCaDCaDCaDDaDDaDDaDDaacaDDaDDaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaBtaCyaBtaDEaCwaDFaCwaDEaxVaAlaDHaDIaAlaAlaxVazHazHazHazHazHazHazHaCBaCLaxVaxVaxVaxVaxVaDJaxVaxVazHaDKaxVaDLaCLaxVaxVaxVbikbikbikbikbikaDMaDMaDMaDMaDMaDMaDMaDMaabaCMaDNaDOaDPaDQaDRaDSaDTaDUaDVaDWaABaDXaBPaDYaDZaEaaEbaEcaEdaAKaxlaxqaxrazIatsaEeaEfaCZaDaaDbaEgaEhaEhaEhaEhaEhaEhaEhaEhaEhaEhaEiaEjaEkaElaEmaEnaEoaEpaCgaChaChaChaChaChaCgaCfaCfaCfbikbikazvayHaEqaEraBhaEsaDAaCoaDxayHaEtayIaEuaAkayHayHayHayHaEvayHayHaDAaEwayHaDzayHaDCaExaEyaEzaDCaEAaEBaECaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaDGcUCaEDaDEaEFddzaEGaEJaEKazHaELaEMaENaDKaEOazHaxVaxVaxVaxVaxVaxVaxVaCLaxVaEPaEQaERaxVaESaETaEUazHaEOaxVaENaEVaBEaBFaEWbikbikbikbikbikaEXaEYaEZaFaaFbaFcaFdaDMaabaCMaFeaFfaFgaCMaFhazOaFiaFjaFkaFlaABaFnaBPaFoaFpaFqaFraFsaFtaFuaFvaydaFwaFxaFyaFzaFAaCZaDaaDbaFBaEhaFCaFCaFCaEhaEhaFDaFEaFEaFFaEiaFGaFHaFIaFIaFJaFKaFLaFMaChaChaChaChaChaFNaFOaFPaFQbikbikazvayHayHaFRayHaEsaFSayHaFTaFUaFUaFUaFUaFVaFUaFWayHayHayHayHayHayHayHayHayJayIaDCaFXaFYaFYaDCaFZaGaaGbaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaGcaGdaGeaDEaGcaGdaGeaEJaBzazHaGfazHazHazHazHazHaxVaGgaGhaGiaGjaGkaxVaCLaxVaEQaGlaEPaGmaGnaGoaxVaGpaxVaxVaxVaxVaGpaCLaEWbikazyazyazyazyaGqaEYaGraGsaGtaGuaGvaGwaDMaCMaBHaGxaGxaGxaGyaGzaGAaGzaGzaGzaGBaGCaGDaGEaGFaGFaGFaGFaGGaGHaGIaxqaGJazIatsaGKaGLaCZaDaaDbaEgaFCaGMaGMaGNaFCaEhaGOaGPaGPaGQaGRaFGaGSaGTaGUaGVaEhaGWaFQaChaChaChaChaChaFQaGXaGYaFQaabaabayGayHayHayJayJaEsaGZaGZaAiaAiaAiaEsaEsaEsayGaHaaHbayGayJayJayGayJayJayGayGaHcaHdaHeaHfaHgaHhaHiaFXaHjaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaCuaDEaEIaHlaCuaDEaEIaHlaCuaxVaCBaxVaxVaxVaxVaxVazHaxVazHaHnaHoazHazHaxVaCLaxVaHpaabaHpaxVaBvaGoaxVaHqaHraxVaENaBzaxVaAwaDMaDMaHsaHsaHsaHsaHsaHsaHsaHsaHsaGvaGvaGwaHtaHuaHvaHwaHxaHyaHzaHAaHBaHBaHBaHBaHCaHDaHEaHFaHGaHBaHBaHHaHHaHIaHJaHKaHLaHMaHNaGKaHOaHPaHPaDbaEgaFCaHQaHRaHSaFCaEhaGOaGPaGPaGQaHTaFGaGSaGUaGUaGVaEhaGWaFQaChaChaChaChaChaFQaHUaGYaFQbikbikayGaHVayHayHaHWayJaHXazwaHYaHZayKayGaFSayKayGaIaayHayGaIbayHayGaIcaIdaIeaFUaIfaFUaIgaIhaIiaIjaIkaIlaImaDCaDDaDDaacaacaDDaDDaDDaDDaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaIoaIoaIoaIqaIoaIoaIoaIsaItaIuaIuaIuaIuaIvaxVazHaxVaIwaIxaIyazHaIzaGpaCLaxVaxVaxVaxVaxVaxVaGpaxVazHaIyaCBazHazHaGvaIAaIBaICaIDaIDaIDaIDaIEaIDaIDaIFaIGaICaIHaIIaIIaIIaIIaIIaIIaIIaIJaIKaIKaIKaIKaILaIMaIKaINaIKaIOaILaIKaIKaIKaIKaIPaIQaIRaISaITaFzaIUaIVaHPaIWaEgaFCaIXaIYbvsaFCaEhaIZaJaaJaaJbaEiaFGaJcaJdaJdaJeaEhaJfaJgaChaChaChaChaChaJhaJiaJjaFQbikbikayGayHayHayHayHayHayHaIeaFUaFUaFUaFUaFUaFUaFUaCmayHayHayHayHaDzayHayHaDxayHaJkaJlaJmaJnaJoaFYaFYaFYaJpaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaJqaJraJsaJtaJuaJvaJwaJxaJvaJyaJzaJvaJvaJAaxVazHaxVaJBazHazHaJCaJDaxVaEVaBFazHazHazHazHazHazHaGpaJEazHaxVaEKaEKaDMaJFaDMaJGaJHaJIaJIaJIaJJaJIaJIaJIaJKaJGaJLaJMaJMaJMaJMaJMaJMaJMaGvaIKaJNaJOaJPaJQaJRawxaJTaJUaJVaJWaJXaJOaJYaIKaJZaxqaKaazIaKbaGKaKcaKdaKdaKeaKfaKgaKhaKiaKiaKjaKkaKlaKjaKkaKkaKmaKnaKoaEhaEhaKpaEhaKqaKraChaChaChaChaChaKraCfaCfaCfayGayGayGayKayJayJaAkayGayGaDxayJayGaKsayJayGaAkayGaDxaHVayJayGaAkayGayHaHVaDxayHaKtaDCaKuaIhaKvaKwaKxaIhaKyaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaDGcUCaEDaDEaEFddzaEGaEJaEKazHaELaEMaENaDKaEOazHaxVaxVaxVaxVaxVaxVaxVaCLaxVaEPaEQaERaxVaESaETaEUazHaEOaxVaENaEVaBEaBFaEWbikbikbikbikbikaEXaEYaEZaFaaFbaFcaFdaDMaabaCMaFeaFfaFgaCMaFhazOaFiaFjaFkaFlaABaFnaBPaFoaFpaFqaFraFsaFtaFuaFvaydaFwaFxaFyaFzaFAaCZaDaaDbaFBaEhaHTaHTaHTaEhaEhaFDaFEaFEaFFaEiaFGaFHaFIaFIaFJaFKaFLaFMaChaChaChaChaChaFNaFOaFPaFQbikbikazvayHayHaFRayHaEsaFSayHaFTaFUaFUaFUaFUaFVaFUaFWayHayHayHayHayHayHayHayHayJayIaDCaFXaFYaFYaDCaFZaGaaGbaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaDEaGcaGdaGeaDEaGcaGdaGeaEJaBzazHaGfazHazHazHazHazHaxVaGgaGhaGiaGjaGkaxVaCLaxVaEQaGlaEPaGmaGnaGoaxVaGpaxVaxVaxVaxVaGpaCLaEWbikazyazyazyazyaGqaEYaGraGsaGtaGuaGvaGwaDMaCMaBHaGxaGxaGxaGyaGzaGAaGzaGzaGzaGBaGCaGDaGEaGFaGFaGFaGFaGGaGHaGIaxqaGJazIatsaGKaGLaCZaDaaDbaEgaHTaGMaGMaGNaHTaEhaGOaGPaGPaGQaGRaFGaGSaGTaGUaGVaEhaGWaFQaChaChaChaChaChaFQaGXaGYaFQaabaabayGayHayHayJayJaEsaGZaGZaAiaAiaAiaEsaEsaEsayGaHaaHbayGayJayJayGayJayJayGayGaHcaHdaHeaHfaHgaHhaHiaFXaHjaDCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbjNaInaCuaDEaEIaHlaCuaDEaEIaHlaCuaxVaCBaxVaxVaxVaxVaxVazHaxVazHaHnaHoazHazHaxVaCLaxVaHpaabaHpaxVaBvaGoaxVaHqaHraxVaENaBzaxVaAwaDMaDMaHsaHsaHsaHsaHsaHsaHsaHsaHsaGvaGvaGwaHtaHuaHvaHwaHxaHyaHzaHAaHBaHBaHBaHBaHCaHDaHEaHFaHGaHBaHBaHHaHHaHIaHJaHKaHLaHMaHNaGKaHOaHPaHPaDbaEgaHTaHQaHRaHSaHTaEhaGOaGPaGPaGQaKhaFGaGSaGUaGUaGVaEhaGWaFQaChaChaChaChaChaFQaHUaGYaFQbikbikayGaHVayHayHaHWayJaHXazwaHYaHZayKayGaFSayKayGaIaayHayGaIbayHayGaIcaIdaIeaFUaIfaFUaIgaIhaIiaIjaIkaIlaImaDCaDDaDDaacaacaDDaDDaDDaDDaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdmJdmKaGddmKaIoaIoaIoaIqaIoaIoaIoaIsaItaIuaIuaIuaIuaIvaxVazHaxVaIwaIxaIyazHaIzaGpaCLaxVaxVaxVaxVaxVaxVaGpaxVazHaIyaCBazHazHaGvaIAaIBaICaIDaIDaIDaIDaIEaIDaIDaIFaIGaICaIHaIIaIIaIIaIIaIIaIIaIIaIJaIKaIKaIKaIKaILaIMaIKaINaIKaIOaILaIKaIKaIKaIKaIPaIQaIRaISaITaFzaIUaIVaHPaIWaEgaHTaIXaIYbvsaHTaEhaIZaJaaJaaJbaEiaFGaJcaJdaJdaJeaEhaJfaJgaChaChaChaChaChaJhaJiaJjaFQbikbikayGayHayHayHayHayHayHaIeaFUaFUaFUaFUaFUaFUaFUaCmayHayHayHayHaDzayHayHaDxayHaJkaJlaJmaJnaJoaFYaFYaFYaJpaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaInaKzaJqaJraJsaJtaJuaJvaJwaJxaJvaJyaJzaJvaJvaJAaxVazHaxVaJBazHazHaJCaJDaxVaEVaBFazHazHazHazHazHazHaGpaJEazHaxVaEKaEKaDMaJFaDMaJGaJHaJIaJIaJIaJJaJIaJIaJIaJKaJGaJLaJMaJMaJMaJMaJMaJMaJMaGvaIKaJNaJOaJPaJQaJRawxaJTaJUaJVaJWaJXaJOaJYaIKaJZaxqaKaazIaKbaGKaKcaKdaKdaKeaKfaKgaSsaKiaKiaKjaKkaKlaKjaKkaKkaKmaKnaKoaEhaEhaKpaEhaKqaKraChaChaChaChaChaKraCfaCfaCfayGayGayGayKayJayJaAkayGayGaDxayJayGaKsayJayGaAkayGaDxaHVayJayGaAkayGayHaHVaDxayHaKtaDCaKuaIhaKvaKwaKxaIhaKyaDCaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaDEaKzaKAaKzaKBaJraJraKCaKzaKAaKzaKDaKEaKFaKGaxVazHaGpaGpaxVaxVaxVaKHaKHaKHazNaKHaKHaKHaKHaKHaGvaDMaDMaDMaDMaDMaDMaDMaJFaKIaJGbikaabbikaabbikaabbikaabbikaJGaJLaJMaKJaKKaKLaKMaKNaJMaGvaIKaKOaKOaKPaKQaKRaKSaKTaKSaKUaKVaKWaKOaKOaIKaJZaxqaKXazIaKbaGKaGLaCZaDaaDbaEgaKYaKZaLaaLbaLcaLcaLdaLeaLcaLeaLfaLgaLhaLiaLjaLkaLlaCfaKraChaChaChaChaChaKrayGaCtayHaLmaLnayJayGayJaCtayHayGaCtaDxayGaLoayHayGaLpayHayJaLqaLrayGaLsayHayJaAkaAkaDxaAkaLtaDCaLuaIhaLvaLwaLvaIhaLxaDCaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaLyaCuaLzaGdaKzaLAaLBaLCaLDaKzaGdaLEaInaCuaLFaLGaxVazHazHazHazHazHazHaKHaLHaLIaLJaLKaLLaLMaLHaKHaLNaLOaIDaIDaIDaIDaIDaIDaLPaLQaJGaabaLRaLRaLRaLRaLRaLRaLRaabaJGaJLaJMaLSaLTaLUaLVaLSaJMaGvaIKaIKaIKaIKaLWaLXaJOaLYaJOaLXaLZaIKaIKaIKaIKaJZaxqaMaazIaKbaGKaFAaCZaDaaDbaFBaMbaMcaMcaMcaMcaMcaMcaMcaMdaMcaMeaMeaMeaMeaMeaMfayGaCfaKraChaChaChaChaChaKrayGayGayHaMgaLnayJaMhayGayHayHayGayHaDxayJayHayHayGayHayHayJaDxayIayGayHayHayJaMiayHaDxayHaMjaMkaMkaDCaDCaDCaDCaDCaDCaDCaDDaDDaDDaDDaDDaabbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaKAaKzaKzaKzaKzaKzaKzaKAaInaMlaCuaMmaMnaMoaMoaMoaMoaMoaMoaMpaKHaLHaMqaLJaMraMqaMqaLHaKHaMsaMtaMuaMuaMuaMuaMuaMuaMuaMuaMvbikaLRaMwaMxaMyaMzaMAaLRbikaJGaJLaJMaMBaMCaMDaMEaLSaJMaGvaIKaMFaMFaKPaMGaMHaKSaKTaKSaMHaMIaMJaKOaKOaIKaJZaxqaKaazIaMKaBRaMLaCZaDaaDbaEgaMbaMcaMMaMNaMOaMOaMcaMPaMQaMRaMeaMSaMTaMUaMeaMVayGbikaMWaMXaMXaMXaMXaMXaMYbikayGayHaMZaNaayJayJayGayGayJayJaNbaNcayJayGazxayGayGayJayJaNdaNeayGayGayGaHYaMiayHaDxayHaMjazwayKaFSayGaNfaNgaNfayGayGayGaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNhaNiaNjaNiaNiaNkaNlaNiaNiaNjaNmaNnaCuaKBaNoaMoaNpaNqaNraNsaNtaNuaKHaLHaMqaLJaNvaMqaMqaLHaKHaNwaNxaNyaNzaNAaNBaNCaNDaNEaNFaMvaabaLRaNGaNHaNIaNJaNKaLRaabaJGaJLaJMaNLaNMaNNaNOaNPaJMaGvaIKaJNaJOaNQaNRaLXaJOaNSaJOaLXaNTaNUaJOaJYaIKaJZaxqaNVazIaKbaEeaEfaCZaDaaDbaNWaNXaMcaNYaMQaMQaMQaNZaOaaObaOcaMeaOdaOeaOfaOgaOhazxbikbikbikbikbikbikbikbikbikayGaOiaOjaOkaOlaOmayGaEtayHaHVaDxayHayGbikayGayHayHayHayHaDxaOnaOoaOpaOpaOpaOpaOqaOraOsaOtaOuaOvaOuaOwaOxaOxaOyaOzaOAaOBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaNhaNmaNiaODaOEaOFaOGaOHaOIaOJaOKaOLaOMaONaOOaKzaKBaOPaMoaOQaORaOSaOTaOSaOUaKHaOVaMqaOWaOXaOYaOXaOZaPaaPbaPcaPdaPdaPdaPdaPdaPdaPeaPfaMvbikaLRaPgaNHaPhaNJaPiaLRbikaJGaJLaJMaPjaPkaPlaPmaPnaJMaGvaIKaPoaPoaKPaPpaMHaKSaPqaKSaMHaPraKWaPsaPsaIKaPtazUaPuazIaKbaEeaPvaPvaPvaPvaPwaPxaPyaPzaPAaPBaPBaPBaPCaPBaPDaPEaPFaPGaPHaPEaPIaPJazxayGayGayGayGayGayGayGayGayGayGayGayGaBMayGayGayGayGayHaDxaOiazvaabazvayHaPLaPMaPNaPOaPPaPQaPRaPRaPRaPRaPSaPTaPUaPVaPWaPXaPWaPYaPWaPWaPZaQabpqaQbaQcaQdaQeaQeaQeaQeaQeaQeaQeaQeaQeabLadbbikbikbikbikbikbikbikaaabdBaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdetaNiaNjaNiaNiaNkaNlaNiaNiaNjaNmdeuaCuaKBaNoaMoaNpaNqaNraNsaNtaNuaKHaLHaMqaLJaNvaMqaMqaLHaKHaNwaNxaNyaNzaNAaNBaNCaNDaNEaNFaMvaabaLRaNGaNHaNIaNJaNKaLRaabaJGaJLaJMaNLaNMaNNaNOaNPaJMaGvaIKaJNaJOaNQaNRaLXaJOaNSaJOaLXaNTaNUaJOaJYaIKaJZaxqaNVazIaKbaEeaEfaCZaDaaDbaNWaNXaMcaNYaMQaMQaMQaNZaOaaObaOcaMeaOdaOeaOfaOgaOhazxbikbikbikbikbikbikbikbikbikayGaOiaOjaOkaOlaOmayGaEtayHaHVaDxayHayGbikayGayHayHayHayHaDxaOnaOoaOpaOpaOpaOpaOqaOraOsaOtaOuaOvaOuaOwaOxaOxaOyaOzaOAaOBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdetaNmaNiaODaOEaOFaOGaOHaOIaOJaOKaOLaOMaONaOOaKzaKBaOPaMoaOQaORaOSaOTaOSaOUaKHaOVaMqaOWaOXaOYaOXaOZaPaaPbaPcaPdaPdaPdaPdaPdaPdaPeaPfaMvbikaLRaPgaNHaPhaNJaPiaLRbikaJGaJLaJMaPjaPkaPlaPmaPnaJMaGvaIKaPoaPoaKPaPpaMHaKSaPqaKSaMHaPraKWaPsaPsaIKaPtazUaPuazIaKbaEeaPvaPvaPvaPvaPwaPxaPyaPzaPAaPBaPBaPBaPCaPBaPDaPEaPFaPGaPHaPEaPIaPJazxayGayGayGayGayGayGayGayGayGayGayGayGaBMayGayGayGayGayHaDxaOiazvaabazvayHaPLaPMaPNaPOaPPaPQaPRaPRaPRaPRaPSaPTaPUaPVaPWaPXaPWaPYaPWaPWaPZaQabpqaQbaQcaQdaQeaQeaQeaQeaQeaQeaQeaQeaQeabLadbbikbikbikbikbikbikbikaaabdBaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaONaQgaQhaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaQmaMoaQnaQoaQpaQqaQraQsaKHaQtaMqaQuaQvaQwaQxaQyaKHaQzaPdaPdaPdaPdaPdaPdaPdaPeaQAaMvaabaLRaQBaQCaQDaQEaQFaLRaabaJGaJLaJMaQGaQHaQIaQJaQKaJMaGvaIKaIKaIKaIKaQLaLXaJOaLYaJOaLXaQMaIKaIKaIKaIKaQNaQOaQPazIaMKaQQaQRaQRaQRaQSaQTaQUaQVaQWaQXaQVaQYaQZaRaaQVaRbaRcaRdaReaRfaMeaRgaRhaRiaRjaRjaRhaRkaRlaRlaRlaRlaRlaRmaRnaRlaRoaRpaRqaRraRsaRvaRuaTkaRwaRxaRwaRyaRzayHayGaRAaRBaRCaRDaREaRFaRGaRHaRIaRJaRIaRKaRLaRMaRNaROaRPaOCbbVaTCaRTaRUaQdaRVaRWaRXaRYaRZaSaaSbaScaSdaprbikbikbikbikbikbikbikaaabfmbifbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaSfaOFaOFaNjaOMaQjaOFaQjaSgaQjaOFaQjaOMaQkaQlaKzaKBaShaMoaMoaSiaSjaSkaSjaMoaKHaKHaKHaKHaSlaSmaSnaSoaKHaSpaSqaSraPdaPdaSsaPdaStaSuaSvaMvbikaLRaLRaSwaSxaSwaLRaLRbikaJGaJLaJMaSyaSzaSAaQJaSBaJMaGvaIKaJNaJOaSCaNRaLXaJOaLYaJOaLXaNTaSDaIKaIKaIKaSEaSFaSGaSHaSIaSJamKamKaSKaSLaSMaSNaMcaSOaMQaMcaSPaMcaSQaMcaSRaSSaSTaSUaSVaTeaSXaSYaSZaTaaTbaTcaTdaTbaTbaUjaTbaSYaTfaSYaOvaTgaSYaThaTiaTjaTmaTlaToaTnaTqaTpaWIaTraOuaTsaTtaTuaTvaTwaTxaTyaTzaRHaTAaTBaRIcLhaTDaTEaTFaROaTGaRQaRRaRSaTHaTIaQdaTJaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikaaabfmbigbijbihbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaSfaOFaOFaNjaOMaQjaOFaQjaSgaQjaOFaQjaOMaQkaQlaKzaKBaShaMoaMoaSiaSjaSkaSjaMoaKHaKHaKHaKHaSlaSmaSnaSoaKHaSpaSqaSraPdaPdaZVaPdaStaSuaSvaMvbikaLRaLRaSwaSxaSwaLRaLRbikaJGaJLaJMaSyaSzaSAaQJaSBaJMaGvaIKaJNaJOaSCaNRaLXaJOaLYaJOaLXaNTaSDaIKaIKaIKaSEaSFaSGaSHaSIaSJamKamKaSKaSLaSMaSNaMcaSOaMQaMcaSPaMcaSQaMcaSRaSSaSTaSUaSVaTeaSXaSYaSZaTaaTbaTcaTdaTbaTbaUjaTbaSYaTfaSYaOvaTgaSYaThaTiaTjaTmaTlaToaTnaTqaTpaWIaTraOuaTsaTtaTuaTvaTwaTxaTyaTzaRHaTAaTBaRIcLhaTDaTEaTFaROaTGaRQaRRaRSaTHaTIaQdaTJaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikaaabfmbigbijbihbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaONaTMaTNaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaTOaTPaTQaTRaTSaTSaJraTTaTUaTVaTWaTXaTYaTZaMqcoCaKHaUbaUcaUdaUeaUfaUgaUhaUiaUZaUkaMvbikaabbikaUlaUmaUlbikaabbikaJGaJLaJMaUnaUoaUpaUqaUraJMaGvaIKaUsaUtaKPaUuaUvaKSaUwaKSaUxaUyaUzaIKaUAaUBaUCaUDaUEaUFaUGaUHbikbikaSKaUIaUJaUKaMcaULaUMaMQaMQaUNaMQaMQaMQaUOaMeaUPaMeaUQaURaMeaUSaMeaUTaUUaUVaUWaUXaUYaUTbwNaVaaVbaVcaVbaVbaVbaVbaVdaWLaVbaVeaVfaWFaWBaVbaVhayHaRDaViaTvaVjaVkaVlaVmaVnaVoaVpaVqaRIaVraVsaVtaVuaVvaTGaRQaRRaRSaRTaVwaQdaVxaTKaTKaTLaScaScaScaScaSdaprbikbikbikbikbikbikbdBblqbjMbmKbjMbqQbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaVyaVzaNiaODaOMaOFaVAaVBaOFaOFaVCaVAaOMaONaVDaKzaKBaVEaVFaVGaVHaVGaVGaVGaVGaVGaVIaJraKHaVJaVKaVJaKHaKHaVLaVMaVLaMuaMuaMuaMuaVLaVNaVOaMvaVPaVQaVQaVRaVSaVRaVQaVQaVTaJGaVVaJMaVWaJMaVXaVYaVZaJMaWaaIKaIKaIKaIKaWbaWcaWdaWeaWdaWcaWbaIKaIKaWfaUDaUDaUDaUDaWgaWhaWiaWjaWkaSKbKgaUJaWmaMcaMcaMcaMcaMcaMcaMcaMeaMeaUOaWnaWoaWpaWqaWraWsaWuaWtaUTaWvaWwaWxaWyaWzaUTaWAaWGaWCaWDaWCaWEaWHaYDaWNaYFaWJaWKaYGaWMaYEaVbaWOaRtaWPaWQaWRaVjbtTcvIaVmaWTaRIaWUaWVaWWaWXaWYaTFaTFaRIaRIaRQaRRaRSaTHaWZaQdaXaaXbaXcaXdaXeaXfaScaScaXgaprbikbikbikbikbikaaabfmbqRbmKbmKbmKbqSbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaVyaNiaNjaNiaNiaNkaNlaNiaNiaNjaVzaXhaCuaXiaVEaInaXjaXjaXkaXjaXlaDEaXmaXnaJraXoaXpaXqaXqaXraXsaXqaXtaXqaXqaXqaXuaXqaXqaXvaXwaXxaXyaXzaXAaXyaXBaXyaXyaXyaXyaXCaXDaXEaXqaXqaXFaXGaXHaXIaXJaXKaXLaXMaXRaXPaXPaXPaXPaXPaXPaXPaXQaXWaXXaXSaXTaXUaXVaXYaZHaXZaUDaUDaYaaYbaYcaYbaYcaYdaYeaYfaYgaYhaYiaMeaYkbBvaYmaYlaYnaYnaYoaYpaYqaYraUTaYsaYtaYuaYuaYvaUTaYwaYxaYyaYzaYAaYAaYBaYCaYHbbFbalbbHbbGbbJaVgaVbaVhaKsaRDaYIaYJaYJaYKaYLaYJaYMaRIaYNaYOaRIaYPaYQaTFaYRaRIaYSaYTaYUaRSaQbaQbaQdaYVaQeaYWaYXaQeaQeaQeaQeaQeabLadbbikbikbikbikbqUbqTbqVbmKbmKbrUbthbmKbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaYYaKzaKzaKzaKzaKzaKzaYYaInaMlaCuaYZaZaaInaZbaZcaZdaZdaZeaDEaZfaXnaZgaZhaXpaZiaZjaZkaZlaZlaZmaZnaZnaZnaZoaZpaZpaZqaZraZsaZlaZlaZtaZpaZvaZwaZxaZxaZyaZzaZAaZuaZuaZuaZBaXGaXHaXIaXJaXJaXJaXJaZCaXJaXJaXJaXJaXJaXJaZDaZEaZNaZFaZGaZJaZIaZLaZKaZMaZNaZNaZNaZOaZPaZPaZPaZQaYiaYiaYiaZRaZSaYiaMebbsaZUaYnaYnaZVaYnaZWaZXaYqaZYaUTaZZbaababbacbadaUTbaebafbagbahbaibajaVbaVbbbKbbLaVbaVbbakbbMbakaVbaVhayHaRDbamaTvaTvaTvbanaTvbaoaRIaRIaRIaRIaRIaRIaRIbapaRIaRSaRSaRRaRSbaqbaraQbbasbatbaubavbawbaxbaybazbaAbikbikbikbikaaabtibtjbtibtibtibtkbtibtlbtibtjbtiaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdeOaVzaNiaODaOMaOFaVAaVBaOFaOFaVCaVAaOMaONaVDaKzaKBaVEaVFaVGaVHaVGaVGaVGaVGaVGaVIaJraKHaVJaVKaVJaKHaKHaVLaVMaVLaMuaMuaMuaMuaVLaVNaVOaMvaVPaVQaVQaVRaVSaVRaVQaVQaVTaJGaVVaJMaVWaJMaVXaVYaVZaJMaWaaIKaIKaIKaIKaWbaWcaWdaWeaWdaWcaWbaIKaIKaWfaUDaUDaUDaUDaWgaWhaWiaWjaWkaSKbKgaUJaWmaMcaMcaMcaMcaMcaMcaMcaMeaMeaUOaWnaWoaWpaWqaWraWsaWuaWtaUTaWvaWwaWxaWyaWzaUTaWAaWGaWCaWDaWCaWEaWHaYDaWNaYFaWJaWKaYGaWMaYEaVbaWOaRtaWPaWQaWRaVjbtTcvIaVmaWTaRIaWUaWVaWWaWXaWYaTFaTFaRIaRIaRQaRRaRSaTHaWZaQdaXaaXbaXcaXdaXeaXfaScaScaXgaprbikbikbikbikbikaaabfmbqRbmKbmKbmKbqSbieaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdeOaNiaNjaNiaNiaNkaNlaNiaNiaNjaVzdeQaCuaXiaVEaInaXjaXjaXkaXjaXlaDEaXmaXnaJraXoaXpaXqaXqaXraXsaXqaXtaXqaXqaXqaXuaXqaXqaXvaXwaXxaXyaXzaXAaXyaXBaXyaXyaXyaXyaXCaXDaXEaXqaXqaXFaXGaXHaXIaXJaXKaXLaXMaXRaXPaXPaXPaXPaXPaXPaXPaXQaXWaXXaXSaXTaXUaXVaXYaZHaXZaUDaUDaYaaYbaYcaYbaYcaYdaYeaYfaYgaYhaYiaMeaYkbBvaYmaYlaYnaYnaYoaYpaYqaYraUTaYsaYtaYuaYuaYvaUTaYwaYxaYyaYzaYAaYAaYBaYCaYHbbFbalbbHbbGbbJaVgaVbaVhaKsaRDaYIaYJaYJaYKaYLaYJaYMaRIaYNaYOaRIaYPaYQaTFaYRaRIaYSaYTaYUaRSaQbaQbaQdaYVaQeaYWaYXaQeaQeaQeaQeaQeabLadbbikbikbikbikbqUbqTbqVbmKbmKbrUbthbmKbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaInaYYaKzaKzaKzaKzaKzaKzaYYaInaMlaCuaYZaZaaInaZbaZcaZdaZdaZeaDEaZfaXnaZgaZhaXpaZiaZjaZkaZlaZlaZmaZnaZnaZnaZoaZpaZpaZqaZraZsaZlaZlaZtaZpaZvaZwaZxaZxaZyaZzaZAaZuaZuaZuaZBaXGaXHaXIaXJaXJaXJaXJaZCaXJaXJaXJaXJaXJaXJaZDaZEaZNaZFaZGaZJaZIaZLaZKaZMaZNaZNaZNaZOaZPaZPaZPaZQaYiaYiaYiaZRaZSaYiaMebbsaZUaYnaYnbcMaYnaZWaZXaYqaZYaUTaZZbaababbacbadaUTbaebafbagbahbaibajaVbaVbbbKbbLaVbaVbbakbbMbakaVbaVhayHaRDbamaTvaTvaTvbanaTvbaoaRIaRIaRIaRIaRIaRIaRIbapaRIaRSaRSaRRaRSbaqbaraQbbasbatbaubavbawbaxbaybazbaAbikbikbikbikaaabtibtjbtibtibtibtkbtibtlbtibtjbtiaQfbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaLyaCuaInaGdaKzbaBbaCbaDbaEaKzaGdaInaInaCubaFaVEaInbaGbaHaZdaZdaZeaDEbaIaXnaJraZhaXpaXqbaJbaKbaLbaLbaMbaNbaObaLbaPbaLbaQbaLbaRbaSbaLbaLbaWbaLbaLbaUbaVbaLbaWbaXbaYbaZaXqaXqbbabbbbbcbbdbbebbfbbebbgbbhbbgbbgbbgbbgbbgbbgbbibbjbbkbbkbbkbbkbblbbkbbmbbnbbkbbkbbobbpbbqbbqbbqbbqbbqbbqbbqbbraYiaYiaMebcTbbtbbubbvbbvbbwbbxaZXaYqbbyaUTaUTaUTaUTaUTbbzaUTbbAbbBbbCbbDaWCbbEaVbbdfbdcbdgbbIbkZbjrcSNcIgaVbaVhaHYaRDbbNbbOaTvbbPbbQaTvbbRbbRaRDbbSbbTbbUaQbdilbbWbbXaRSaRSbbYbbZaQbbcaaQbbcbbatbccbcdbcebatbatbcfbaAbikbikbikbikbqUbtmbwlbutbwmbtmbmKbutbwmbtmbwlbutbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaDEaInaYYaKzaKBaJraJraKCaKzaYYaKzbcgbchbcibcjaInbckbckaXkbckaXlaDEbclaXnaJraDEbcmbcmbcnbcobcobcobcobcobcobcpbcqbcobcobcobcobcobcobcrbcsbctbctbcubctbcvbcwbcxbcvbcvbcybczbcAbcmbcBbcBbcCbcCbcCbcDbcDbcDbcDbcDbcDbcDbcDbcEbcFbcFbcGbcFbcHbcHbcHbcHbcIbcJbcHbcEbcKbcKbcKbcKbcKbcKbcKbcKbcLbcLbcLaMebcMbcNbcObcObcObcObcPbcQbcRbmwbcUaZTbcVbcWbcXbcYaUTaUTbcZbdabdbbdabdaaVbcYtbdddcnbdebdebdecZrcZqaVbbdhbdiaRDbdjaTvbbPbbPbbQbbPaTvbdkaRDbdlbdmbdnaQbaRSbdobdpbdqbdqbdrbdsbdtbdubdvbdwbdxbdybdzbavbatbatbdAbaAbikbikbikbikbqUbwnbmKbutbBQbtmbmKbutbBQbtmbmKbFmbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaDEaInaYYaKzaKBaJraJraKCaKzaYYaKzbcgbchbcibcjaInbckbckaXkbckaXlaDEbclaXnaJraDEbcmbcmbcnbcobcobcobcobcobcobcpbcqbcobcobcobcobcobcobcrbcsbctbctbcubctbcvbcwbcxbcvbcvbcybczbcAbcmbcBbcBbcCbcCbcCbcDbcDbcDbcDbcDbcDbcDbcDbcEbcFbcFbcGbcFbcHbcHbcHbcHbcIbcJbcHbcEbcKbcKbcKbcKbcKbcKbcKbcKbcLbcLbcLaMebcObcNbcPbcPbcPbcPbgRbcQbcRbmwbcUaZTbcVbcWbcXbcYaUTaUTbcZbdabdbbdabdaaVbcYtbdddcnbdebdebdecZrcZqaVbbdhbdiaRDbdjaTvbbPbbPbbQbbPaTvbdkaRDbdlbdmbdnaQbaRSbdobdpbdqbdqbdrbdsbdtbdubdvbdwbdxbdybdzbavbatbatbdAbaAbikbikbikbikbqUbwnbmKbutbBQbtmbmKbutbBQbtmbmKbFmbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbdCbdDaJrbdEbdFbdGbdHbdIbdJbdHbdKbdLbdHbdHbdMbdNbdObdPbdQbdQbdQbdRbdQbdSbdTaDEbdUbdVbdWbcobdXbdYbdZbeabebbecbedbeebefbegbehbeibcobejbekbctbelbembenbcvbeobepbeqbcvberbesbetberberberbeuaXJaXObcDbikbikbikbikbikbikbikbcEbevbewbexbeybezbeAbeBbeCbeDbeEbeFbcEbikbikbikbikbikbikbikbcKbeGaYibeHaMebeIbcNbmwbmwbmwbmwbmwbeJbeKbmwbmwbmwbnMbeMbeMbeNbeObePbeQbeRbeSbeTbeUaVbbeVbeWdlHbeYbeYbeXbeZbfaaVbaVhayHaRDbfbbfcaTvbbPbbQaTvbfdbfdaRDaRDbfeaRDaQbbffbbWbbZbfgbfgbfhbbZaQbaQbaQbbfibatbfjbfjbfkbfjbatbflbaAaabbikbikaabbdBbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbdCbfnbfobfnbfnbfnbfnbfnbfnbfobfnbfnbfpaJrbfqbfrbfsaJrbftaJrbfubfvbfwbfxbfyaDEbdVbdVbfzbcobfAbecbecbecbecbecbedbfBbecbecbecbfCbcobejbfDbctbfEbfFbfGbcvbfHbfIbfJbcvbfKbfLbfMbfNbfObesbeuaXJaXObcDbikbikbikbikbcEbcEbcEbcEbfPbfQbfRbfSbfTbfUbfVbfWbfXbfYbfZbcEbcEbcEbcEbikbikbikbikbcKbeGaYibgabgbbgcbgdbgebgfbgcbggbghbgibgjbgkbglbmwbeLbgmbeMbgnbgobeMbgpbgqbgrbgsbeMbgtbgubgvdlHbeYbeYbeXbgwbgxaVbaVhaKsaRDbdjaTvbbPbbPbbQbbPaTvaTvbgybgzaTvbgAaQbbgBbgCbgDbfgbfgbgEbgDbgFaQbbgGbgHbatbgIbgIbgJbgIbatbdAbaAbgKbaAbaAbaAbqUbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaCuaCuaInaInaInaInaInaInaInaInaInaCuaDEbgLbgMbgNbgNbgNbgNbgNbgNbgObgNbgNbgNaDEbdVbejbgPbcobgQbecbecbgRbgSbgTbgUbgRbecbecbecbgVbcobejbekbctbgWbgXbgYbcvbgZbhabhbbcvbhcbhdbhebhfbhgbesbhhbhiaXObcDbcDbhjbcEbcEbcEbhkbhlbhmbhnbhobhobhpbhqbhobhrbhobhsbhtbhubhvbhwbhxbcEbcEbcEbhjbcKbcKbeGaYiaYiaMebhybhzbgkbhAbmwbhBbhCbmwbhDbhEbglbmwbnMbeMbeMbhFbcSbhHbhIbhJbhKbhLbeMbhMbgubhNdlHbeYbeYbhObhPbhQaVbaVhayHaRDbhRbhSbhTbbPbbQbhUaTvaTvbhVaTvbhWbhXaQbbhYbhZbiabfgbfgbibbiabicaQbbidbgHbatbatbatbavbatbatbKnbIzbPfbNjbiibPfddJbmKbmKbmKbmKbmKbmKbmKbmKbmKbmKbutbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikblsbltbltblubltbltbltblvbltbltbmPaabaInaLAaJtbilbgNbimbinbiobipbiqbirbisbitbgNbiubivbiwbixbcobiybecbecbgRbgTbizbiAbgRbecbecbiBbiCbcobejbekbctbctbiDbctbcvbiEbiFbiGbcvbiHbhfbiIbhfbiJbesbeubiKaXOaXPaXPbiLbiMbiNbcEbiObfRbiPbhobhobiQbiRbiSakybiSbiUbiVbiWbiXbiYbiZbjabcEbjbbiMbjcbjdbjebeGaYiaYibjfbmwbjgbmwbmwbmwbjhbjibmwbhDbjjbglbmwbeLbeMbeMbjkbBDbjmbjnbjobjpbhLbjqaVbdlJdlIdlKbeYbeYbeXbhPbjsaVbbjtbjuaRDbjvaRDaRDbjwbbQbjxbjyaTvbjzbjAaWSbjBbdvbjCbjDbjEbjFbjFbjGbjHbjIbdvbjJbjKbatbjLbatbavbatbatddAbaAbaAbaAbaAbgKbqUddBbmKbutbwmbtmbmKbutbwmbtmbmKddCbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbdCbfnbfobfnbfnbfnbfnbfnbfnbfobfnbfnbfpaJrbfqbfrbfsaJrbftaJrbfubfvbfwbfxbfyaDEbdVbdVbfzbcobfAbecbecbecbecbecbedbfBbecbecbecbfCbcobejbfDbctbfEbfFbfGbcvbfHbfIbfJbcvbfKbfLbfMbfNbfObesbeuaXJaXObcDbikbikbikbikbcEbcEbcEbcEbfPbfQbfRbfSbssbfUbfVbfWbfXbfYbfZbcEbcEbcEbcEbikbikbikbikbcKbeGaYibgabgbbgcbgdbgebgfbgcbggbghbgibgjbgkbglbmwbeLbgmbeMbgnbgobeMbgpbgqbgrbgsbeMbgtbgubgvdlHbeYbeYbeXbgwbgxaVbaVhaKsaRDbdjaTvbbPbbPbbQbbPaTvaTvbgybgzaTvbgAaQbbgBbgCbgDbfgbfgbgEbgDbgFaQbbgGbgHbatbgIbgIbgJbgIbatbdAbaAbgKbaAbaAbaAbqUbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaCuaCuaInaInaInaInaInaInaInaInaInaCuaDEbgLbgMbgNbgNbgNbgNbgNbgNbgObgNbgNbgNaDEbdVbejbgPbcobgQbecbecdhUbgSbgTbgUdhUbecbecbecbgVbcobejbekbctbgWbgXbgYbcvbgZbhabhbbcvbhcbhdbhebhfbhgbesbhhbhiaXObcDbcDbhjbcEbcEbcEbhkbhlbhmbhnbhobhobhpbhqbhobhrbhobhsbhtbhubhvbhwbhxbcEbcEbcEbhjbcKbcKbeGaYiaYiaMebhybhzbgkbhAbmwbhBbhCbmwbhDbhEbglbmwbnMbeMbeMbhFbcSbhHbhIbhJbhKbhLbeMbhMbgubhNdlHbeYbeYbhObhPbhQaVbaVhayHaRDbhRbhSbhTbbPbbQbhUaTvaTvbhVaTvbhWbhXaQbbhYbhZbiabfgbfgbibbiabicaQbbidbgHbatbatbatbavbatbatbKnbIzbPfbNjbiibPfddJbmKbmKbmKbmKbmKbmKbmKbmKbmKbmKbutbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikblsbltbltblubltbltbltblvbltbltbmPaabaInaLAaJtbilbgNbimbinbiobipbiqbirbisbitbgNbiubivbiwbixbcobiybecbecdhUbgTbizbiAdhUbecbecbiBbiCbcobejbekbctbctbiDbctbcvbiEbiFbiGbcvbiHbhfbiIbhfbiJbesbeubiKaXOaXPaXPbiLbiMbiNbcEbiObfRbiPbhobhobiQbiRbiSakybiSbiUbiVbiWbiXbiYbiZbjabcEbjbbiMbjcbjdbjebeGaYiaYibjfbmwbjgbmwbmwbmwbjhbjibmwbhDbjjbglbmwbeLbeMbeMbjkbBDbjmbjnbjobjpbhLbjqaVbdlJdlIdlKbeYbeYbeXbhPbjsaVbbjtbjuaRDbjvaRDaRDbjwbbQbjxbjyaTvbjzbjAaWSbjBbdvbjCbjDbjEbjFbjFbjGbjHbjIbdvbjJbjKbatbjLbatbavbatbatddAbaAbaAbaAbaAbgKbqUddBbmKbutbwmbtmbmKbutbwmbtmbmKddCbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikblsbohbptbojbpwbpwbqWbpwbpwbpwbqWblubjNaInaKzaKBbfqbgNbimbjObjPbimbjQbjRbjSbjTbgNbjUaFmbjWbcsbcobjXbjYbjZbkabkbbkcbkdbkebkebkebkfbkgbcobejbivbkhbkibkjbkkbcvbcvbcvbcvbcvbklbkmbknbkobkpbesbeubiKaXJaXJaXJbkqbkrbksbktbkubkvbhobkwbkxbkybkzbkAbkBbkCbkDbkEbkFbkGbkubkHbkIbkJbkKbkMbkLbkObkObkPaYibkQaMebmwbkRbkSbglbmwbkTbkUbmwbkVbkWbglbmwbnMbeMbeMbeMbeNbeMbkXbeMbjpbhLbkYaVbdlObhNbeXbeYbeYbeXbhPblaaVbblbblcbldbleblfblgblhblibljbljbljbljbljbljblkbllblmbfgbfgbfgbfgbfgbfgblnbloblpbgHbatbatbatbavbatbatddDbgKblrblrblrbaAbwmbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbwmbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbqYbqXbqXbqXbqXbqXbqXbqXbqXbqXbqXbqZbraaGdbraaJrbfqbgNblwbimblxblxblxblybimblzbgNblAblBbjWblCblCblCblCblDblCblEbecblFblGblHblHblIblJbcoblKblLblMblNblOblPblQblRblSblRblTblTblTblTblTblUberbeublVblWblXblYblZbmabmbbmcbmdbkBbmebmfbmgbmgbmgbmgbmhbmgbmibmjbmkbmlbmebmmbmnbcEbmobmpbmqbkNbmsbmtaYiaYibjfbmwbnCbmwbmwbmwaRebmwbmwbmvbmvbmwbmwbmxbeMbeMbmybmzbeMbeMbeMbmAbmBbmCaVbbgxbhNbeXbeXbeXbeXbhPbmDaVbbmEbmFbmFbmGbmFbmHbbPbbPbbPbbPbmIbbPbbPbbPbmJblobfgbfgbfgbfgbfgbfgbfgblnbloblpbgHbatbfjbfjbfkbfjbatddEbaAbmLbmMbmNbaAbBQbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbBQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbrbbrebrdbrfbrfbrgbrfbrfbrfbrgbluaInaInaKzbrVbcjbmQbimbmRblxblxblxblybmRbimbgNbmSbmTbjWblCbmUbmVbmWbmXblCbmYbmZbnabcobnbbncbndbnebcobejbnfbngbngbnhbngbngbngbngbnibnjbnjbnjbnkbnjbnlbnmbnnbnobnpbnqbnqbnqbnqbnqbnqbnrbnsbnrbmgbmgbntbnubnvbnwbnxbnybntbnzbmgbnAbnBbnAbnAbnAbnAbnAbnAbnAbmtaYiaYiaMebnEbnDcakbnGbmwbnFbmwbnJdmhdmgbmwbpjaUTbnKbnLaUTaUTczObnNddybnNaUTaUTaVbbnObnPbnQbnQbnQbnQbnPbnRaVbbnSbmFbmFbmGbnTaRDbnUbnVbnWbnXbnYbnZboabobbocaQbbodaRSboebfgbfgboeaRSbofaQbbogbgHbatbgIbgIbgJbgIbatddDbgKblrblrblrbaAbGVbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbGVbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbltbltblubltbltbltblvbltbltbtnaabaInboibdFbokbgNbjObjObjObimbolbombonboobgNbopboqbjWblCborblCbosbotblCboubovbowbcobnbbncbndbiCbcobejbnfbngboxboybozboAboBbngboCboDboEboFbnmbnmbnmbnmboGboHboIbnqboJboKboLboMboNboOboPboQbmgboRbnvboSboTboUboTboSbnvboVbmgboWboXboYboZbpabpbbpcbpdbnAbpebpfbpfbpgaMeaMeaMeaMebphbjfbphbpiaMeaURaMeaMeaUTaUTaUTaUTbplbpkbpkbpkbpkbpmbpJaVbbakbpnbakbpobpobakbpnbakaVbbnSbmFbmFbppbnTaRDaRDaRDaRDaRDbjvaRDaRDaRDaRDaQbbpqaQcaQcaQcaQcaQcaQcaQbaQbbprbpsbatbatbatbavbatbatddAbaAbaAbaAbaAbgKbqUddFbmKbmKbmKbmKbmKbmKbmKbmKbmKddGbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaKzaDEaDEaDEaDEaDEaDEbtobpubgNbgNbgNbgNbgNbgNbpvbgNbgNbgNbejbejbpxblCbpybpzbosbpAblCdlEbpCbpBbcobnbbncbndbecbcobejbnfbngbpDbpEbpFboAbpFbngboCbpGbpHbpIbmubpKbpLbnmbpMbpNboIbpObpPbpQbpRbpSbpSbpRbpTbpUbmgbpVbnvbnvbpWbpXboTboSbnvbpYbmkbpZbqabqbbqcbqdbqebqbbqfbnAbqgbqhbqibqjbqkbqlbqmbqnbqnbqnbqnbqnbqnbqobqpbqqbqnbqnbqsbqnbqnbqnbqnbqnbqnbqnbqndcZbqubqvbqvbqvbqvbqvbqvbqwbqlbqxbqybqyaHkbqAbqBbqAbqCbqAbqDbqEbqFbqAbqGbqHbqIbqJbqKbqKbqKbqKbqKbqKbqKbqLbqMbqNbqNbqNbqNbqObqNbqPbKnddHbPfddIbiibPfdlbbmKbmKbmKbmKddKbmKddKbmKbmKbmKddGbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbtpbtqbtqbtqbtqbwpbwpbtqbtqbxZbikaabaInaLAaJtbzPbzObzRbzQbzQbzQbzQbzSbzUbzTbcsbdVbBFbrhblCblCblCbribotblCbcobcobcobcobnbbrjbrkbrlbcobrmbrnbngbrobrpboAbpFbrqbngboCbrrbpHbpIbpIbrsbrtbnmbrubpNboIbpObrvbrwbrxbrybrzbrAbpTbrBbmgbrCbpWbnvbrDbrEbrDbnvbpWbrFbnzbrGbqbbqbbqcbrHbqebqbbrIbnAbrJbqibqibqjbqkbqlbqnbqnbqnbqnbqnbqnbqnbrKbqnbqnbqnbqnbqnbqnbrLbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrNbrObrPbqKbqKbrQbmFbmFbmFbmFbmFbmGbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbrRbmFbrSbrTbatbatbatbatbatbatbatddLbaAbgKbaAbaAbaAbqUddMddOddNbdBddPbdBddPbdBddQddMddObqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCbBHdjhbDDdjidjidjkdjjbtqbxZbjNaInaInaKBbrWbrXbrYbrXbrXbrXbrXbrZbsabsbbcsbcsbscbsdblCbmUbsebsfbpAblCbsgbshbsgbcobcobcobcobsibcobsjbskbngbslbsmbpFbsnbsobngboCbnmbspbpIbpIbpIbsqbnmbsrbpNboIbpOdmbbrwbrxbstbsubrAbpTbsvbmgbswbsxbnvbsybszbsAboSbsBbsCbsDbsEbsFbsGbsHbsIbsJbqbbsKbnAbsLbsMbqibqjbqkbqlbqnbsNbqnbqnbqnbqnbsObsPbsPbsPbsPbsQbqnbqnbqnbqnbsRbqnbsNbsSbqnbsTbsUbsVbqnbsWbsXbsXbsYbsZbtabtbbmFbmFbmFbmFbmFbmFbmFbtcbtdbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbtebtfbtfbtgddSddRddUddTddTddTddTddVddWbaAaabbikbikaabbqUddXddZddYdeabqUbikbqUdecdebdecdecbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbpIbpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbqrbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUbuVbnmbuWbpIbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrdmcbtXbqbbvtbnAbxebvwbxfbucbzcbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbqYbqXbqXbqXbqXbqXbqXbqXbqXbqXbqXbqZbraaGdbraaJrbfqbgNblwbimblxblxblxblybimblzbgNblAblBbjWblCblCblCblCblDblCblEbecblFblGblHblHblIblJbcoblKblLblMblNblOblPblQblRblSblRblTblTblTblTblTboFblUbeublVblWblXblYblZbmabmbbmcbmdbkBbmebmfbmgbmgbmgbmgbmhbmgbmibmjbmkbmlbmebmmbmnbcEbmobmpbmqbkNbmsbmtaYiaYibjfbmwbnCbmwbmwbmwaRebmwbmwbmvbmvbmwbmwbmxbeMbeMbmybmzbeMbeMbeMbmAbmBbmCaVbbgxbhNbeXbeXbeXbeXbhPbmDaVbbmEbmFbmFbmGbmFbmHbbPbbPbbPbbPbmIbbPbbPbbPbmJblobfgbfgbfgbfgbfgbfgbfgblnbloblpbgHbatbfjbfjbfkbfjbatddEbaAbmLbmMbmNbaAbBQbtmbmKbutbBQbtmbmKbutbBQbtmbmKbutbBQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbrbbrebrdbrfbrfbrgbrfbrfbrfbrgbluaInaInaKzbrVbcjbmQbimbmRblxblxblxblybmRbimbgNbmSbmTbjWblCbmUbmVbmWbmXblCbmYbmZbnabcobnbbncbndbnebcobejbnfbngbngbnhbngbngbngbngbnibnjbnjbnjbnkbnjbnlbuWbnnbnobnpbnqbnqbnqbnqbnqbnqbnrbnsbnrbmgbmgbntbnubnvbnwbnxbnybntbnzbmgbnAbnBbnAbnAbnAbnAbnAbnAbnAbmtaYiaYiaMebnEbnDcakbnGbmwbnFbmwbnJdmhdmgbmwbpjaUTbnKbnLaUTaUTczObnNddybnNaUTaUTaVbbnObnPbnQbnQbnQbnQbnPbnRaVbbnSbmFbmFbmGbnTaRDbnUbnVbnWbnXbnYbnZboabobbocaQbbodaRSboebfgbfgboeaRSbofaQbbogbgHbatbgIbgIbgJbgIbatddDbgKblrblrblrbaAbGVbtmbmKbutbGVbtmbmKbutbGVbtmbmKbutbGVbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbrcbltbltblubltbltbltblvbltbltbtnaabaInboibdFbokbgNbjObjObjObimbolbombonboobgNbopboqbjWblCborblCbosbotblCboubovbowbcobnbbncbndbiCbcobejbnfbngboxboybozboAboBbngboCboDboEbSVbyzbyzbyzbuVboGboHboIbnqboJboKboLboMboNboOboPboQbmgboRbnvboSboTboUboTboSbnvboVbmgboWboXboYboZbpabpbbpcbpdbnAbpebpfbpfbpgaMeaMeaMeaMebphbjfbphbpiaMeaURaMeaMeaUTaUTaUTaUTbplbpkbpkbpkbpkbpmbpJaVbbakbpnbakbpobpobakbpnbakaVbbnSbmFbmFbppbnTaRDaRDaRDaRDaRDbjvaRDaRDaRDaRDaQbbpqaQcaQcaQcaQcaQcaQcaQbaQbbprbpsbatbatbatbavbatbatddAbaAbaAbaAbaAbgKbqUddFbmKbmKbmKbmKbmKbmKbmKbmKbmKddGbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaKzaDEaDEaDEaDEaDEaDEbtobpubgNbgNbgNbgNbgNbgNbpvbgNbgNbgNbejbejbpxblCbpybpzbosbpAblCdlEbpCbpBbcobnbbncbndbecbcobejbnfbngbpDbpEbpFboAbpFbngboCbpGbpHbAibmubpKbpLbnmbpMbpNboIbpObpPbpQbpRbpSbpSbpRbpTbpUbmgbpVbnvbnvbpWbpXboTboSbnvbpYbmkbpZbqabqbbqcbqdbqebqbbqfbnAbqgbqhbqibqjbqkbqlbqmbqnbqnbqnbqnbqnbqnbqobqpbqqbqnbqnbqsbqnbqnbqnbqnbqnbqnbqnbqndcZbqubqvbqvbqvbqvbqvbqvbqwbqlbqxbqybqyaHkbqAbqBbqAbqCbqAbqDbqEbqFbqAbqGbqHbqIbqJbqKbqKbqKbqKbqKbqKbqKbqLbqMbqNbqNbqNbqNbqObqNbqPbKnddHbPfddIbiibPfdlbbmKbmKbmKbmKddKbmKddKbmKbmKbmKddGbdBbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbtpbtqbtqbtqbtqbwpbwpbtqbtqbxZbikaabaInaLAaJtbzPbzObzRbzQbzQbzQbzQbzSbzUbzTbcsbdVbBFbrhblCblCblCbribotblCbcobcobcobcobnbbrjbrkbrlbcobrmbrnbngbrobrpboAbpFbrqbngboCbrrbpHbAibpIbrsbrtbnmbrubpNboIbpObrvbrwbrxbrybrzbrAbpTbrBbmgbrCbpWbnvbrDbrEbrDbnvbpWbrFbnzbrGbqbbqbbqcbrHbqebqbbrIbnAbrJbqibqibqjbqkbqlbqnbqnbqnbqnbqnbqnbqnbrKbqnbqnbqnbqnbqnbqnbrLbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrMbrNbrObrPbqKbqKbrQbmFbmFbmFbmFbmFbmGbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbrRbmFbrSbrTbatbatbatbatbatbatbatddLbaAbgKbaAbaAbaAbqUddMddOddNbdBddPbdBddPbdBddQddMddObqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCbBHdjhbDDdjidjidjkdjjbtqbxZbjNaInaInaKBbrWbrXbrYbrXbrXbrXbrXbrZbsabsbbcsbcsbscbsdblCbmUbsebsfbpAblCbsgbshbsgbcobcobcobcobsibcobsjbskbngbslbsmbpFbsnbsobngboCbnmbspbAibpIbpIbsqbnmbsrbpNboIbpObWDbrwbrxbstbsubrAbpTbsvbmgbswbsxbnvbsybszbsAboSbsBbsCbsDbsEbsFbsGbsHbsIbsJbqbbsKbnAbsLbsMbqibqjbqkbqlbqnbsNbqnbqnbqnbqnbsObsPbsPbsPbsPbsQbqnbqnbqnbqnbsRbqnbsNbsSbqnbsTbsUbsVbqnbsWbsXbsXbsYbsZbtabtbbmFbmFbmFbmFbmFbmFbmFbtcbtdbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbmFbtebtfbtfbtgddSddRddUddTddTddTddTddVddWbaAaabbikbikaabbqUddXddZddYdeabqUbikbqUdecdebdecdecbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjldjidjidjidjidjidjidjideHdjnaGddjnaJrbtrbrXbtsbttbtubtvbtwbrZbtxbtybtzbtzbtAbtBblCblCblCbosbtCborbcsbcsbcsbcsbtDbejbejbskbejbsjbskbngbtEbtFbtGbtHboAbngbtIbnmbtJbAibpIbpIbtKbtLbtMbpNbtNbnqbtObtPbpRbpRbpRbpRbpTbtQbmgbtRbtSbmgbmgbmgbmgbmgbmgbmgbnzbnAbqrbtUbtVbtWbtXbtYbtZbnAbvubuabuabucbucbucbucbucbucbucbudbudbuebufbugbugbufbuebudbudbuhbuhbuhbuhbuhbuhbuibuibujbuibuibuibuibuibukafkbumbunbmFbmFbuobuobupbupbupbupbupbuqbtfbtfbtebtfbmFbtfbtfbtfbtfburbusbusbusbusdedbuubuubuubuubuubuubuubuubuubikbikbikbikbdBddYddYddYdeebqUbikbqUdefdebdebdegbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbBGbDCdjodjpdjpdjidjpdjpdjpbtqdjqaInaInaInaKBbuvbrXbuwbuxbuxbuxbuybrZbejbuzbuAbuBbuCbuDblCbmUbuEbosbuFborbuGbuHbuIbuJbuKbuLbuLbuMbuLbuNbuObngbuPbuQbuRbuSbuTbuUdngbyzdnidnhbpIbuXbuYbuZbtMbpNbvabnqbvbbvcbvdbvebvfbvgbvhbnqbnqbvibvjbvkbvlbvmbvlbvnbvjbikbvobnAbvpbvqbvrccIbtXbqbbvtbnAbxebvwbxfbucbzcbvybvzbvAbvBbvCbvDbvEbvFbvGbvHbvHbvGbvIbvJbvKbuhbvLbvMbvNbvObuhbvPbvQbvRbvSbvTbvUbvUbvVbukafNbvXbvYbvZbvYbwabwabupbwbbwcbwdbupbwebwfbwebupbwgbtfburbusbwhbwibwhbusbwjbwkbusdeicngbxXbwobikbikbikbikbikbikbikbikbikbikbqUddXddZddYdejbqUbikbqUdekdekdekdekbqUbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjrbtqbtqbtqbtqbtqbtqbtqbtqdjqbikbikaInbwqbdFbwrbrXbwsbrXbwtbuxbwubwvbrZbwwbwxbwybwzbuDblCblCblCblCblCblCbwAbwBbwCbwDbwEbngbngbngbngbngbngbngbwFbngbngbngbwGbngbwHbwIbwJbpIbpIbpIbwKbtLbwLbpNbwMbnqbIDbvcbnrbnrbnrbnqbwObnqbwPbwQbwRbwSbwTbwUbwVbwWbwXbwYbwZbnAbxabqbbxbbxcbtXbxdbqbbnAbzbbxgbANbucbxhbxibxjbxkbxlbxmbxnbvHbvHbvHbvHbvHbvHbvHbvHbxobxpbxqbxrbxsbxtbuhbxubxvbxwbxxbxybxzbxvbxAbukbDdbvXbxCbxDbxEbxFbxFbxGbxHbxIbxJbxKbxLbxMbxNbupbxObxPbxQbusbxRbxSbxTbLSbxUbxVbusbxWbxXbxYbwobikbikbikbikbikbikbikbikbikbikbDybtldemdemdemdenbikdeodepdepdepbtlbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaLyaCuaKzaKzaInaInaInaInaInaInaInaKBaJrbyabrXbybbycbydbyebyebyfbygbyhbyibyibyjbykbtzbtzbtzbtzbtzbtzbylbymbymbynbyobngbypbyqbyrbysbytbyubyvbywbngbyxbyybyzbuVbtLbwJbpIbpIbyAbnmbnmbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObwXbyPbyQbyPbyQbyRbwXbwYbySbyTbyUbyVbyWbyXbyYbyZbzabyTbAObvwbvwbucbzebzdcSCbzfbzgbucbxnbvHbvHbvHbvHbvHbvHbvHbzhbzibzjbzkbzlbxqbzmbuhbznbzobzpbxxbxAbxzbzqbzrbukbIbbztbzubzvbzvbzwbzxbzybzzbzAbzAbzAbzBbzAbzCbzDbzEbzFbzGbzHbzIbzJbzKbzKbzKbzLbusbzMbxXbzNbwobikbikbikbikbikbikbikbikbikbikbikbDyderderderbDzbikbDyderderderbDzbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjtdjsdjuaIoaIoaIobdFaJraJrbrXbzVbrXbzWbzXbzYbzZbrXbcsbAabAabAbbAcbAbbAbbAbbAcbAbbcsbcsbngbngbngbAdbngbAebAebAebAebAebAebyvbAfbAgbAhbAibAjbAkbAlbAmbAnbAobApbAqbArbAsbAtbAubAvbAwbAwbAxbAybAzbAAbABbACbADbAEbvjbAFbwVbAGbwTbAHbvjbikbAIbAJbAKbALbAJbAJbAJbAJbAMbnAbCBbvwbCCbAPbAQbARbASbATbAUbucbAVbAWbAXbAYbAZbBabBbbBcbvHbBdbuhbBebzlbBfbBgbuhbBhbBibxwbxxbxAbxzbxvbxAbukbDdbvXbBjbBkbBlbBmbBnbBobBpbBqbBrbBsbBtbBubKpbupbBwbBxbBybusbBzbBAbBBbxUbBCbKwbusbzMbxXbBEbwobikbikbikbikaabaabaabaabaabaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdetdesdesdesdesdesdeubikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukbIcbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjwdjvdjuaJqaJqbBIbBJaJqbBKbrXbBLbycbBMbBNbBObBPbrXbikaabaabdfMdesdesdesdesdesdfNbikbikbBRbBSbBTbBUbBVbAebAebAebAebAebAebBWbBXbBYbBZbCabCbbCcbCdbnmbnmbCebCfbnmbnmbCgbChbCibCjbCkbClbClbCmbClbCnbCobCpbCqbAEbvjbCrbvlbvlbvlbCsbvjbikbAIbAJbCtbCubCvbCwbCxbCybCzbCAbEsbvwbEtbucbvxbCDbCEbCFbCGbCHbCIbCJbCKbCLbCMbCNbCObCPbCQbCRbCSbCTbzlbCUbCVbuhbCWbCXbCYbCZbDabDbbDcbvVbukbIcbDebDfbDgbDgbDhbDibDjbDkbDlbDmbDnbDobDpbDqbupbDrbBxbDsbusbDtbDubDvbxUbxUbDwbusbxWbxXbDxbwobikbikbikbikaabbDAbFfbDBbFfbDBbFfbFgaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaIndjudjubDEaInaInaLyaCubDFbDGbrXbDHbycbycbycbrXbrXbrXbikbikbikdewdevdevdexdevdevdewbikbikbBRbDIbAebDJbDKbDKbDKbDKbDKbDLbDMbDKbDNbDObDPbDQbDRbDSbDTbnmbDUbpIbDVbDWbtLbDXbDYbDZbCjbCjbCpbEabEbbEcbEdbEebCpbvibAEbvjbEfbEgbEhbqtbEjbvjbikbEkbAJbElbEmbEnbEobEpbEobEqbErbFWbvwbHBbucbEubEubEvbEwbExbEybEzbEAbEBbECbEDbEDbEEbEFbEGbEHbuhbCTbEIaJSbuhbuhbuibEKbELbEMbuibukbukbukbENbIdbvXbEPbBkbBlbEQbDgbDjbERbESbESbETbxJbEUbEVbEWbEXbxPbEYbusbEZbFabxUbFbbFcbFdbusbzMbFebwobwobikbikbikbikaabbFhbFjbFibGSbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjydjydjydjAdjzdjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbFobFpbFqbFrbFrbFrbFpbAebyvbAfbAebAebAgbFsbFtbFubFvbFwbFxbFybpIbpIbFzbtLbDXbDYbFAbFBbFCbFDbFEbFFbFGbFHbFIbCpbFJbFKbwRbFLbFMbFNbFObFPbwXbwYbFQbAJbFRbFSbFTbEobFUbEobFVbErbJebvwbKObucbFYbFZbGabGbbGcbGdbGebGfbGgbGgbGhbGibGgbGgbGjbGkbGlbGmbGnbGobGpbGqbGrbGsbGtbGubGvbGwbKhbIebKjbKibvXbGBbGCbGDbGEbGFbxGbGGbESbESbGHbGIbEUbGJbupbGKbGKbGLbusbGMbGNbGObGPbxUbGQbusbzMbGRbwobikbikbikbikbikaabbGUbIybFibFkbFibKkbDBaabbikbikbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjCdjEdjDdjGdjFdjIdjHdjFdjJdjLdjKdjydjydjBbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbGWbmrbNkbmrbGXbGYbGZbGYbGYbGYbGYbHabyvbAfbHbbngbngbHcbpIbAibFvbHdbtLbHebHfbHfbHgbHhbHibHjbHkbHlbHmbHnbHobHpbHqbHrbHsbCpbCqbAEbvjbEibHubHvbHwbHxbvjbikbEkbHybHzbHybHybHybHybHybHAbHybKPbvwbKObucbHCbHDbHDbHEbHFbEybHGbHHbHIbHJbHKbHLbHMbHIbHNbHObHPbHQbHRbHSbHTbHTbHUbHVbHWbHXbHYbLibLCbLBbNdbNcbNebIfbIfbIgbIhbIibxGbIjbxJbxJbIkbIlbEUbImbInbIobIpbIqbIrbIsbItbIubIvbIubusbusbIwbEXbGxbLDbLDbLDbLDbLDbGxbFhbFkbFibFkbFkbGTbFhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjHdjHdjHdjMdjFdjNdjNdjFdjOdjHdjHdjQdjPdjydjBbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbLFbKmbIAbKmbIBbAebFqbFrbFrbFrbAebAebyvbAfbICbKobngbIEbpIbAibFvbIFbtLbIGbpIbrsbpIbIHbDXbvvbIIbHlbHmbIJbIKbILbIMbINbIObIPbIQbIRbISbISbITbIUbIVbvjbvjbikbEkbHybIWbIXbIYbIZbJabJbbJcbJdbMhbvwbKObCHbJfbJgbJhbJibJjbEybJkbJlbJmbJnbJobJpbJqbJrbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbGwchEbIecnfcjubvYbJIbJJbJKbJLbJLbxGbJMbJNbJObxGbJPbEUbJQbxGbJRbJSbJTbJUbJVbJWbJXbJYbJZbKabKbbKcbKdbKebKfbKfbIxbJFbJHbGzbKlbFfbDBbNhbDBbFfbLEaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydjSdjRdjUdjTdjVdjFdjWdjHdjXdjHdjHdjHdjHdjHdjMdjFbikbikbikbikbikbikbikbikbikbikdewdeCdevdevdevcOfdewbFnbBRbBRdezbAebFqbAebAebAebAebAebyvbAfbICbLwbngbLQbpIbKqbKrbpIbKsbpHbpIbpIbKtbtLbDXbvvbIIbHlbHmbCpbKubKvbqzbKxbKybKzbKAbKBbKCbKDbwXbKEbKFbwXbwYbwYbKGbHybKHbKIbKJbKKbKLbKLbKMbKNbMibvwbMjbucbEybKQbEubKRbKSbEybJkbKTbKUbKVbKWbKXbKYbKUbJkbKZbLabLbcchbLbbLcbLbbLdbLdbLebLfbLgbLhbLhcpLbLgbLgbLhbLhbLjbLkbLjbLjbxGbxGbxGbxGbxGbLlbLmbBobxGbLnbLobLpbLqbLqbLrbLsbLtbLubLvbLIbLxbLybLzbLAbLAbEObGAbHZbGxbGzbGzbGzbIabGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbNrbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPbWDbLRcobbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdjHdjHdkadkadkadjFdjHdjHdjFdkbdkddkcdkfdkedkgdjFbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevbWobKmbIAbKmbFobLGbLHbAebAebAebLGbAebyvbAfbICbNrbngbLJbpIbAibFvbpIbnmbLKbpIbpIbLLbtLbDXbvvbLMbHlbLNbCpbLObLPdiNbLRcobbKzbLTbLUbLVbLWbLXbLYbLZbMabikbikbikbHybMbbMcbMdbMdbMebMfbMgbHybNSbNRbKObNTbMkbMlbMmbMnbMobMpbMqbJlbMrbMsbMtbMubMvbMrbJkbKZbMwbMxbMybMzbMAbMBbLdbMCbMDbMEbLgbMFbMGbMHbMIbMJbMKbMLbKabMMbLqbLqbMNbMObLqbMPbMQbMRbMSbMTbLqbMUbiTbMWbMXbMYbMZbNabNbbNabNabNabIwbEXbGxbLDbLDbGxcnccndcnebOQbOSbUHbYdbGzbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdjHdjHdjHdjHdjHdkidjHdjHdjFdjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdeEdeDdeGdeDbNlbNmbNnbNnbNnbNnbNnbNobNpbNqbICbWSbngbNsbNtbNubNvbNwbNxbNybNybNybNzbNzbNAbvvbNBbNCbHmbCpbNDbNEbNFbKvbNGbKzbNHbNIbNJbNKbNLbFNbNMbMabikbikbikbHybNNbNObNPbNQbMebMfbMgbHybPibNUbQObPjbNVbNWbNXbNYbNZbOabObbOcbKUbKUbOdbOebKUbKUbJkbKZbOfbOgbOhbOibOjbOkbLdbOlbOmbOnbOobOpbOqbOrbOrbOsbOtbOubOvbOwbJVbJVbOxbJVbOybJVbOzbJVbOAbOBbOBbOCbODbOEbOFbOGbOHcsjbOJbOKbOLbNabOMcxHbikbikbikbGxbORbJFbOPbOQbGzbOObNibGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkmdkldkodkndjHdjFdjHdjHdjFdjHdkqdkpdkrbikbikbikbikbikbikbikbikbikbikbikbikbikdewdevdevdevdevdevdewbFnbBRbBRbngbngbBRbBRbBRbBRbBRbngbngbBRbBRbBRbngbOVbOVbOVbOWbOVbNzbOXbOYbOZbPabNzbDXbvvbPbbPcbPcbCpbCpbCpbCpbCpbPdbKzbISbIRbPebNKbPgbPhbMabMabvjbvjbvjbHybHzbHybHybHybHybHybHybHybQPbvwbQQbPkbPlbPmbPnbPlbPlbPobPpbPqbPrbPsbPtbPubPvbPwbMqbPxbPybPzbPAbPBbPCbPDbPEbPFbPGbPHbPIbPJbPKbPLbMHbPMbLhbLhbPNbPObPNbPPbPQbPPbPPbPPbPRbPSbPTbPTbPUbPVbPWbPXbOFbPYbPZbQabQbbQcbQdbNabOMcxHbikbikbikbGxbNfbNgbGxbGzbGxbGxbGzbGxbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjydjydjydjydjydjydjFdjOdjHdksdjHdkudktdkvbikbikbikbikbikbikbikbikbikbikbikbikbikdeJdeIdevdeKdevdeLdeMbikbikbikbikbikbikbikbikbikbikbQgaabbikbikbikbikbOVbQhbQibQjbQkbNzbQlbQmbQnbQobNzbDXbvvbQpbQqbQrbQsbQtbQubQvbQwbQxbQybQzbQAbQBbQCbQDbQEbQFbQGbQHbQIbQJbQKbQLbQMbQRbuabQSbvwbShbSgbSibvwbSjbPlbQTbQUbQVbQWbQXbJkbQYbQZbRabRbbRcbRdbRebRfbRgbRhbRibLbbRjbOibRkbRlbRmbRnbRobRpbLgbRqbMHbMHbMHbRrbLhbPNbRsbRtbRubRvbRwbRxbRybPPbRzbRAbRBbPTbPTbRCbPWbRDbREbWHbRGbRHbRIbRJbRKbNabRLbwobikbikbikbGxbGxbGxbGxbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydkxdkwdkydkxdkzdjFdjHdjHdjFdjHdkBdkAdkCbikbikbikbikbikbikbikbikbikbikbikbikbikdeOdeNdePdePdePdeNdeQbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbOVbRMbRNbRObRPbNybRQbRRbRSbRTbNzbDXbRUbRVbvvbvvbFXbRWbubbQNbQMbRXbRYbRXbRZbSabSabSbbScbSdbSabSabSebSabSfbSabQMbQRbuabSlbSkbTJbTIbTLbTKbvwbPlbSmbQUbSnbSobSpbJkbSqbSrbSsbStbSubSvbSwbSxbJkbSybSzbLbbSAbSBbSBbSCbSDbSEbSFbSGbLgbSHbSIbMHbSJbSKbLhbPNbSLbSMbSNbSObSPbSQbSRbPPbSSbRAbSTbSTbPTbSUbSVbSWbSXbSYbSZbTabTbbTcbTdbNabOMbwobTebikbikbikbikbikbikbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjxdjydkxdkwdkydkxdkzdjFdjHdjHdjFdjHdkBdkAdkCbikbikbikbikbikbikbikbikbikbikbikbikbikdmideNdePdePdePdeNdmHbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbOVbRMbRNbRObRPbNybRQbRRbRSbRTbNzbDXbRUbRVbvvbvvbFXbRWbubbQNbQMbRXbRYbRXbRZbSabSabSbbScbSdbSabSabSebSabSfbSabQMbQRbuabSlbSkbTJbTIbTLbTKbvwbPlbSmbQUbSnbSobSpbJkbSqbSrbSsbStbSubSvbSwbSxbJkbSybSzbLbbSAbSBbSBbSCbSDbSEbSFbSGbLgbSHbSIbMHbSJbSKbLhbPNbSLbSMbSNbSObSPbSQbSRbPPbSSbRAbSTbSTbPTbSUdnjbSWbSXbSYbSZbTabTbbTcbTdbNabOMbwobTebikbikbikbikbikbikbikbikaabbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdjZdjYdkDdkDdkDdkDdkDdkEdjHdjHdjFdjydjydjydjydjydjydjBbikbikbikbikbikbikbikbikbikbikbikdeRdeSdeSdeSdeTbikbikbikbikbikbikbikbikbOUbOTbQebOTbQfbikbikbikbOVbOVbTjbTkbRObTlbNybTmbQnbTnbTobNzbDXbTpbTqbTrbTsbTtbTubTvbTwbTxbTybTzbTAbTBbTCbTCbTDbTEbTEbTEbTEbTEbTEbTFbTGbTHbTNbTMbTPbTOdlidjmdlkdljdllbPlbTQbQUbQVbTRbSpbJkbSqbSrbTSbTTbTUbTVbTWbTXbJsbTYbTZbLbbLbbUabUabLbbSDbLdbUbbUcbLgbUdbUebUfbUgbUhbLhbPNbUibUjbUkbUlbUmbUnbUobPPbUpbRAbSTbSTbPTbUqbUrbUsbUtbUubUvbUwbUxbUybUzbNabOMbUAbUBbUAbUCbUDbUCbUCbUCbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabbikbikbikbikaabaabaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkhdjYdkDdkDdkDdkFdkGdjFdjHdjHdjFdjHdjHdjHdkHdjHdkIdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbTfbTibThbTgbUIbUIbUIbOVbUJbUKbULbUMbUNbUObUPbUQbUQbURbNzbUSbUTbUUbUVbUVbUWbUXbUYbUVbUZbUZbVabVbbONbUZbUZbVdbQMbQMbVebVfbVfbVfbVgbVhbVfbVfbVibVjbVkbVkbVlbVkbVmbVnbVkbVobVpbVqbPlbVrbVsbSqbVtbVubVvbVwbVxbVybVubJkbSybVzbVAbVBbVCbVDbVEbVFbVGbVHbVIbVJbVKbVLbVMbVNbVObLhbPNbPNbVPbVQbVRbVSbVRbVTbPPbVUbVVbVWbVWbPTbVXbVYbVZbNabNabNabNabNabNabNabNabOMbUAbWabWbbWcbWdbWdbWebUCbikbikbikbikbikbikbikaabbikbikbikbikbikbikbikbikbikbikbikbikaabbWfbWfbWfbWfbWgbWgbWhbWhbWhbWhbWiaabaabbikbikbikaahbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkKdkJdkDdkLdkMdjFdjHdjHdkNdjHdjHdjHdkOdjHdkPdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUEbUFbUEbQebUIbWmbWlbOVbWnbWpbWqbWrbWsbNzbWtbWubWvbWwbNzbUTbUTbWxbUVbWybWzbWAbWBbWCbUZdmdbWEbWFbWGcAzbUZbWIbWJbWKbVfbWLbWMbWObWNbWPbWQbWRceLbWTbWUbWVbWWbWXbWYbWZbXabXbbXcbXdbXebXfbXgbXhbSrbXibXjbXkbXlbXmbXnbJsbXobXpbXqbXrbVDbXsbXsbXtbXubLgbXvbXwbXxbXybXzbXAbXBbLhbXCbXDbXEbXFbXEbXEbXGbXHbXIbXJbXKbXLbXMbPTbXNbXObPXbEXbxXbXPbXQbXRbXRbXQbXRbXSbUAbXTbXUbWcbWdbXWbXVbUCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWfbXXbXYbXXbWgbWhbWhbXZbYabXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkKdkJdkDdkLdkMdjFdjHdjHdkNdjHdjHdjHdkOdjHdkPdjFbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUEbUFbUEbQebUIbWmbWlbOVbWnbWpbWqbWrbWsbNzbWtbWubWvbWwbNzbUTbUTbWxbUVbWybWzbWAbWBbWCbUZdmbbWEbWFbWGcAzbUZbWIbWJbWKbVfbWLbWMbWObWNbWPbWQbWRceLbWTbWUbWVbWWbWXbWYbWZbXabXbbXcbXdbXebXfbXgbXhbSrbXibXjbXkbXlbXmbXnbJsbXobXpbXqbXrbVDbXsbXsbXtbXubLgbXvbXwbXxbXybXzbXAbXBbLhbXCbXDbXEbXFbXEbXEbXGbXHbXIbXJbXKbXLbXMbPTbXNbXObPXbEXbxXbXPbXQbXRbXRbXQbXRbXSbUAbXTbXUbWcbWdbXWbXVbUCbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbWfbXXbXYbXXbWgbWhbWhbXZbYabXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkQdkDdkDdkRdjFdjHdjHdjFdkSdjHdjHdkUdkTdjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbTgbUGbUEbUEdeycOWbTkbTkdeAbZAbTkbWqbYhbYibNzbNzbNzbNzbNzbNzbYjbUTbYkbYlbYmbYnbYnbYnbYobUZbYpbYqbYqbYqbYrbYsbYtbYubYvbYwbYxbYybYzbYAbYBbYCbVfbVibYDbVkbYEbYFbYGbYHbYIbVkbSmbQVbSnbSobYJbYKbYLbYMbYNbYObYPbYQbYRbVubYSbYTbYUbYVbYWbYXbYYbYZbZabZbbLgbLgbLgbLgbLgbZcbZdbZebLhbZfbXEbXEbZgbZhbXEbZibZjbZkbZlbRAbZmbZmbPTbPVbZnbPXbEXbUAbZobUAbUAbUAbUAbUAbUAbUAbZpbZqbUCbZrbZtbZsbUCaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacaacbZubXXbXXbZvbWhbWhbXZbXZbZwbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydkWdkVdkXdjFdjHdkYdjFdkZdladjHdjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbQebUFbUFbUFbQebUIbYfbYebZzbZAbTkbZBbZCbZDbZEbZFbZFbZFbZGbUTbUTbUTbWxbUVbZHbYnbZIbYnbZJbUZbYpbYqbZKbYqbZLbUZbZMbZNbZObVfbZPbZQbZRbZSbZTbZUbZVbZWbZXbZYbZZcaacabcaccadbVkbTQbQVbQVcaebYJbYKcafcagcahbXjcaicajcElcalcamcancaocapcaqcarcIfcasbXscatbVAcaucavcawcaxcaycazcaAbZjbZfcaBbXEbXEbXEcaCcaDbZjbZkcaEbRAbZmbZmbPTcaFcaGbPXbEXcaHcaIcaJbUAcaKcaLcaMcaNcaOcaPcaQbUCcaRcaScaTbUCbUAbUAbUAbUAbUAbUAbUAbUAbikbikbikbikbikaabbikbikbikbikbikbikbikcaUbWhbZubWhbWhbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikdkkdjydjydjydjydjydjydjydjydjydjydkjbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaahbikbikbikbikbikbikbTgbWjbYbbWkbTgbUIbUIbUIbOVcaYcaZcaZcaZbOVbOVbUTcbacbacbbcbcbUTcbdcbebUVbZHbYnbYnbYncbfbUZbYpbYqbYqcbgcbhcbicbjcbkcblbVfbVfbVfbVfbVfcbmbVfbVfcbncbobVkbVkcbpbVkbVnbVkbVkbPlcbqcbqbPlccicbrcbscbtcbucbvcbwcbxcbycbzcbAcbBcaocapcbCcbDcbEcbFcbGcbHbVAcbIcbJcbKcbLcbMcbNcbOcbPcbQcbPcbRcbRcbRcbPcbScbPcbPcbTcbUbZmbZmbPTcbVbZnbPXcbWcbXcbYcbZccaccbccccccccdcceccfccgcckccjcdqcclcfeccmccnccoccpccqccrccscctaabaabaabaabaabaabaabaabbikbikbikbikbikbWgbWhccuccvccvbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik -bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbYcbOTbYgbOTbZxbikaabbikbOVbOVbUIbUIbUIbOVbikbUTccAccBccCccDbZFccEccFbUVccGccHccIbYnccJccKccLccMccNccOccPbUZccQccRccSccTccUccUccUccUccVccWccXccYccYccZccZcdacdbcdcbVibPlcddcdecdfcdgcdhbYKcdicbtcdjcdkcdlcdmbSwcdncdocdpcffcdrcdrcdscdrcdrcdrcdtbVAcducdvcdwcdxcdycdzcdAcbPcdBcdCcdDcdEcdFcdCcdGcdHcdCcdIcdJbRBbPTbPTcdKcdLcdMcdNcdOcdPcdQcdRcdScdTcdUcdVcdWcdXcdYcdZceacebceaceccebcebcebcedceecefcegcehaabbikbikbikbikaabbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik +bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbYcbOTbYgbOTbZxbikaabbikbOVbOVbUIbUIbUIbOVbikbUTccAccBccCccDbZFccEccFbUVccGccHdmcbYnccJccKccLccMccNccOccPbUZccQccRccSccTccUccUccUccUccVccWccXccYccYccZccZcdacdbcdcbVibPlcddcdecdfcdgcdhbYKcdicbtcdjcdkcdlcdmbSwcdncdocdpcffcdrcdrcdscdrcdrcdrcdtbVAcducdvcdwcdxcdycdzcdAcbPcdBcdCcdDcdEcdFcdCcdGcdHcdCcdIcdJbRBbPTbPTcdKcdLcdMcdNcdOcdPcdQcdRcdScdTcdUcdVcdWcdXcdYcdZceacebceaceccebcebcebcedceecefcegcehaabbikbikbikbikaabbikbikbikbikbikbikbikbWhbWhceibXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbXZbWhbWhaabaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcejbUTbUTbUTcekbUTbUTcelbUVcemcenceocepceqcercescetceucevcewccKcexceycezceAceBceBceBceBceCceDceEceFceGceFceHceIceJceKchvceMceNceOcePceQceRceSceTceUceVceWceXceYceZcfacfbcfccfgbMmbMmcfichOcgHceYchVcfjcfjcfkcfjcflcfmcfncfocbPcfpcfqcfrcfscfrcftcfucfvcdCbPTcfwbPTbPTcfxcfybZnbBxbEXbUAcfzbUAbUAcfAcfBcfCcfDcfEcebcfFcfGcfHcdUcfHcdUcfIcdUcdUbUAcfJcfKcfLcfMaabaabaabaabaabaabaabaabbikbikbikbikbikbWhbXZbXZbXZbXZbXZbXZcfNbXZcfObXZbXZbXZbXZbXZbWhbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejcfPbVccqsbUTcfSbUVcfTcfUcfVbZHcfWcfXcfYbYpcfZcgacgbcfXcgccgdcgecgfcgfcggcghcgicgjcgkcglcgmbGycgnbVicgobGybGycgpcgqcgrcgscgtceQcgucgvcgwcgxcgycgzbMVcgBcgCcgzcgzcgDcgEcgEcgEcgEcgEcgGcgFciOcgJcgJcgKcgLcgMcgNcgOcgPcbPcgQcgRcgScgTcgScgUcgVcfrcgWcgXcgYbBxcgZbBxcfybZnbBxbEXchachbchcbUAbUAbUAbUAbUAchdcdUchechfcfIcdUchgcdUbZpcdUchhbUAchichjchkbUAaabbikbikbikbikaabbikbikbikbikbikbikbikbWhchlchlchlchlchlchlchmbXZchnchlcfObXZbXZbXZbXZbWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik bikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikcejchocfQchpbUTcfSchrchrchrchrchrchrbUZbUZbUZbUZbUZbUZbUZchschtchucWpchwchxchychychzchAcglbGybGychBchCchDbGybGybGycqOchFchGceOchHchIchJcgEchKchLchMbSqchLchNcfdcfdcfdcjncjlcjlcjlcjlckacgIbSqclPchPchQchRchSchTchUclQcbPchWchXcfrchYcfrchZciacibciccidciecifbBxcigcfybZncihbEXbFeciicijcikbwobxXbxXbUAcilcimcinciocipciqcirciscitciucivbUAciwciycixcizbikbikbikbikaahbikbikbikbikbikbikbikbikciAbXXbXXbXXbXXbXXbXXbXXciBciCbXZbXZbXZbXZciDbYabWhaabbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbikbik diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 46b1662d8d6..a5d0cd3f66f 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -18,11 +18,11 @@ "ar" = (/obj/docking_port/stationary/transit{dir = 4; dwidth = 1; height = 4; id = "pod3_transit"; name = "pod 3 in transit"; width = 3},/turf/space/transit/east{dir = 8},/area/space) "as" = (/obj/docking_port/stationary/transit{dir = 8; dwidth = 10; height = 35; id = "whiteship_transit"; name = "whiteship in transit"; width = 21},/turf/space/transit/horizontal{dir = 4},/area/space) "at" = (/turf/unsimulated/wall,/area/vox_station) -"au" = (/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) +"au" = (/turf/unsimulated/floor/vox,/area/vox_station) "av" = (/obj/docking_port/stationary/transit{dir = 4; dwidth = 1; height = 4; id = "pod4_transit"; name = "pod 4 in transit"; width = 3},/turf/space/transit/east{dir = 8},/area/space) "aw" = (/obj/docking_port/stationary/transit{dir = 1; dwidth = 1; height = 4; id = "pod1_transit"; name = "pod 1 in transit"; width = 3},/turf/space/transit,/area/space) "ax" = (/obj/docking_port/stationary/transit{dir = 1; dwidth = 1; height = 4; id = "pod2_transit"; name = "pod 2 in transit"; width = 3},/turf/space/transit,/area/space) -"ay" = (/obj/vox/win_button,/turf/unsimulated/floor{tag = "icon-light_on"; icon_state = "light_on"},/area/vox_station) +"ay" = (/obj/vox/win_button,/turf/unsimulated/floor/vox{icon_state = "light_on"},/area/vox_station) "az" = (/obj/docking_port/stationary{dir = 1; dwidth = 1; height = 4; id = "pod1_away"; name = "recovery ship bay 1"; width = 3},/turf/space,/area/space) "aA" = (/obj/docking_port/stationary{dir = 1; dwidth = 1; height = 4; id = "pod2_away"; name = "recovery ship bay 2"; width = 3},/turf/space,/area/space) "aB" = (/obj/machinery/door/airlock/shuttle,/turf/simulated/shuttle/plating,/area/centcom/evac) @@ -32,11 +32,11 @@ "aF" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/vox_station) "aG" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/vox_station) "aH" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/vox_station) -"aI" = (/obj/machinery/door/airlock/centcom,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) -"aJ" = (/obj/structure/girder/displaced,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) -"aK" = (/obj/structure/closet/crate,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) +"aI" = (/obj/machinery/door/airlock/centcom,/turf/unsimulated/floor/vox,/area/vox_station) +"aJ" = (/obj/structure/girder/displaced,/turf/unsimulated/floor/vox,/area/vox_station) +"aK" = (/obj/structure/closet/crate,/turf/unsimulated/floor/vox,/area/vox_station) "aL" = (/obj/machinery/computer/shuttle/syndicate/recall,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"aM" = (/obj/structure/stool/bed/chair/comfy/red,/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) +"aM" = (/obj/structure/stool/bed/chair/comfy/red,/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor/vox,/area/vox_station) "aN" = (/turf/space,/area/space) "aO" = (/turf/unsimulated/wall{tag = "icon-iron6"; icon_state = "iron6"},/area/space) "aP" = (/obj/structure/window/reinforced,/turf/unsimulated/wall{tag = "icon-iron12"; icon_state = "iron12"},/area/space) @@ -57,11 +57,11 @@ "be" = (/obj/machinery/computer/shuttle/ert,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "bf" = (/obj/machinery/door/airlock/external{id_tag = "specops_away"; name = "Shuttle Hatch"; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) "bg" = (/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "specops_away"; name = "centcom bay 3"; width = 5},/turf/space,/area/space) -"bh" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) -"bi" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) -"bj" = (/obj/item/weapon/stool,/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/vox_station) -"bk" = (/obj/machinery/door/airlock/centcom{opacity = 1},/turf/unsimulated/floor,/area/vox_station) -"bl" = (/turf/unsimulated/floor,/area/vox_station) +"bh" = (/obj/structure/kitchenspike,/turf/unsimulated/floor/vox,/area/vox_station) +"bi" = (/obj/structure/table/woodentable,/turf/unsimulated/floor/vox,/area/vox_station) +"bj" = (/obj/item/weapon/stool,/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor/vox,/area/vox_station) +"bk" = (/obj/machinery/door/airlock/centcom{opacity = 1},/turf/unsimulated/floor/vox,/area/vox_station) +"bl" = (/turf/unsimulated/floor/plating/vox,/area/vox_station) "bm" = (/obj/docking_port/stationary/transit{dir = 2; dwidth = 2; height = 18; id = "skipjack_transit"; name = "skipjack in transit"; width = 19},/turf/space/transit,/area/space) "bn" = (/obj/docking_port/stationary{dir = 2; dwidth = 2; height = 18; id = "skipjack_away"; name = "vox bay 1"; width = 19},/turf/space,/area/space) "bo" = (/obj/docking_port/stationary/transit{dir = 8; dwidth = 3; height = 5; id = "mining_transit"; name = "mining in transit"; width = 7},/turf/space/transit,/area/space) @@ -309,12 +309,12 @@ "fW" = (/obj/structure/holowindow,/turf/simulated/floor/holofloor{dir = 4; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "fX" = (/turf/space,/turf/unsimulated/wall{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/centcom/control) "fY" = (/obj/structure/urinal{pixel_y = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"fZ" = (/obj/item/weapon/mop,/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) +"fZ" = (/obj/item/device/radio/intercom/syndicate{pixel_x = 0; pixel_y = 25},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "ga" = (/obj/structure/mirror{pixel_x = 28},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "gb" = (/obj/structure/table,/obj/machinery/kitchen_machine/microwave/upgraded,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "gc" = (/obj/structure/table,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "gd" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) -"ge" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) +"ge" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "gf" = (/obj/item/device/camera,/turf/unsimulated/beach/sand,/area/ninja/holding) "gg" = (/obj/structure/toilet{dir = 8},/obj/structure/window/reinforced/tinted{dir = 1},/obj/machinery/door/window{dir = 8; name = "Tactical Toilet"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "gh" = (/obj/machinery/light{dir = 1; on = 1},/turf/simulated/floor/plating/airless,/area/syndicate_mothership) @@ -343,8 +343,8 @@ "gE" = (/obj/structure/table,/obj/item/weapon/lighter/zippo,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "gF" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) "gG" = (/obj/structure/table,/obj/item/weapon/dice/d20,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/ninja/holding) -"gH" = (/obj/structure/stool{pixel_y = 8},/obj/item/clothing/head/bandana{pixel_y = -10},/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/beach/sand,/area/ninja/holding) -"gI" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/beach/sand,/area/ninja/holding) +"gH" = (/obj/structure/stool,/obj/item/clothing/head/bandana{pixel_y = -10},/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/beach/sand,/area/ninja/holding) +"gI" = (/obj/structure/stool,/turf/unsimulated/beach/sand,/area/ninja/holding) "gJ" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_basketball) "gK" = (/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor/holofloor,/area/holodeck/source_basketball) "gL" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_basketball) @@ -364,7 +364,7 @@ "gZ" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet13-0 (EAST)"; icon_state = "carpet13-0"; dir = 4},/area/holodeck/source_meetinghall) "ha" = (/obj/structure/stool,/turf/simulated/floor/holofloor{tag = "icon-carpet9-0 (EAST)"; icon_state = "carpet9-0"; dir = 4},/area/holodeck/source_meetinghall) "hb" = (/turf/simulated/floor/beach/coastline,/area/holodeck/source_beach) -"hc" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/computer/security/telescreen{name = "Entertainment monitor"; desc = "Damn, they better have /tg/thechannel on these things."; icon_state = "entertainment"; pixel_y = -30},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) +"hc" = (/obj/structure/stool,/obj/machinery/computer/security/telescreen{name = "Entertainment monitor"; desc = "Damn, they better have /tg/thechannel on these things."; icon_state = "entertainment"; pixel_y = -30},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "hd" = (/obj/machinery/vending/snack,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "he" = (/turf/unsimulated/beach/coastline,/area/ninja/holding) "hf" = (/obj/item/clothing/head/collectable/paper,/turf/unsimulated/beach/coastline,/area/ninja/holding) @@ -381,7 +381,7 @@ "hq" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_boxingcourt) "hr" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "hs" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) -"ht" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/light/spot,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) +"ht" = (/obj/structure/stool,/obj/machinery/light/spot,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "hu" = (/obj/machinery/vending/cola,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/ninja/holding) "hv" = (/turf/unsimulated/beach/water,/area/ninja/holding) "hw" = (/obj/machinery/light/spot,/turf/unsimulated/beach/water,/area/ninja/holding) @@ -440,11 +440,11 @@ "ix" = (/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/wizard_station) "iy" = (/obj/effect/landmark/start{name = "wizard"},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/wizard_station) "iz" = (/turf/unsimulated/floor{dir = 4; icon_state = "carpetside"},/area/wizard_station) -"iA" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"iB" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_r (NORTH)"; icon_state = "propulsion_r"; dir = 1},/turf/space,/area/shuttle/syndicate_elite/mothership) -"iC" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion (NORTH)"; icon_state = "propulsion"; dir = 1},/turf/space,/area/shuttle/syndicate_elite/mothership) -"iD" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (NORTH)"; icon_state = "propulsion_l"; dir = 1},/turf/space,/area/shuttle/syndicate_elite/mothership) -"iE" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) +"iA" = (/obj/docking_port/stationary/transit{dir = 8; dwidth = 3; height = 5; id = "sst_transit"; name = "sst in transit"; width = 11},/turf/space/transit,/area/space) +"iB" = (/obj/machinery/door/airlock/external{id_tag = "sst_away"; req_access_txt = "150"},/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) +"iC" = (/obj/docking_port/stationary{dir = 8; dwidth = 3; height = 5; id = "sst_away"; name = "syndicate docking bay"; width = 11},/turf/space,/area/space) +"iD" = (/obj/item/weapon/gun/projectile/automatic/pistol/m1911,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/head/helmet/space/deathsquad/beret,/obj/item/clothing/shoes/combat,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/gloves/combat,/obj/item/clothing/suit/space/deathsquad/officer,/obj/item/clothing/under/rank/centcom/captain,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs,/obj/item/clothing/mask/gas,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/device/radio/headset/ert{pixel_x = 6; pixel_y = -6},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) +"iE" = (/turf/space,/turf/unsimulated/wall{dir = 1; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/space) "iF" = (/obj/machinery/door/airlock/centcom{aiControlDisabled = 1; name = "Assault Pod"; opacity = 1; req_one_access_txt = "150"},/turf/simulated/floor/plating,/area/shuttle/assault_pod) "iG" = (/obj/effect/decal/warning_stripes/southwest,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "iH" = (/turf/space,/obj/machinery/gun_turret/assault_pod,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/assault_pod) @@ -456,8 +456,8 @@ "iN" = (/obj/structure/table/woodentable,/obj/item/trash/tray,/obj/item/weapon/paper/spells,/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/wizard_station) "iO" = (/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/wizard_station) "iP" = (/obj/structure/table/woodentable,/obj/effect/landmark{name = "Teleport-Scroll"},/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/wizard_station) -"iQ" = (/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/shuttle/syndicate_elite/mothership) -"iR" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{tag = "icon-heater (NORTH)"; icon_state = "heater"; dir = 1},/turf/simulated/floor/plating/airless,/area/shuttle/syndicate_elite/mothership) +"iQ" = (/turf/space,/turf/unsimulated/wall{dir = 2; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/space) +"iR" = (/obj/structure/rack,/obj/item/device/radio/headset/heads/captain{pixel_x = 3; pixel_y = -3},/obj/item/device/radio/headset/syndicate,/obj/item/device/radio/headset/heads/ntrep{pixel_x = -3; pixel_y = 3},/obj/item/device/radio/headset/ert{pixel_x = 6; pixel_y = -6},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "iS" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) "iT" = (/obj/effect/decal/warning_stripes/west,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "iU" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/light/small,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) @@ -471,7 +471,7 @@ "jc" = (/turf/simulated/floor/plasteel,/area/tdome/arena) "jd" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "je" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"jf" = (/obj/effect/landmark{name = "Syndicate-Commando-Bomb"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"jf" = (/obj/structure/rack,/obj/item/weapon/storage/belt/utility/full/multitool{pixel_x = -3; pixel_y = 3},/obj/item/weapon/storage/belt/military,/obj/item/weapon/storage/belt/military/assault{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/belt/champion/wrestling,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "jg" = (/mob/living/silicon/decoy{icon_state = "ai-malf"; name = "GLaDOS"},/turf/unsimulated/floor{icon_state = "whiteshiny"},/area/syndicate_mothership/control) "jh" = (/obj/structure/window/reinforced{dir = 4},/obj/item/device/radio/intercom/syndicate,/turf/unsimulated/floor{icon_state = "circuit"},/area/syndicate_mothership) "ji" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/small{tag = "icon-bulb1 (WEST)"; icon_state = "bulb1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/assault_pod) @@ -498,9 +498,9 @@ "jD" = (/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "jE" = (/obj/structure/rack,/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/twohanded/staff/broom,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "jF" = (/obj/structure/rack,/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/twohanded/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"jG" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) -"jH" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) -"jI" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"jG" = (/obj/structure/rack,/obj/item/weapon/storage/backpack/holding{pixel_x = -3; pixel_y = 3},/obj/item/weapon/storage/backpack/satchel,/obj/item/weapon/storage/backpack/holding{pixel_x = -6; pixel_y = 6},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"jH" = (/obj/structure/rack,/obj/item/weapon/implanter/adrenalin{pixel_x = 12; pixel_y = -12},/obj/item/weapon/implanter/emp{pixel_x = 9; pixel_y = -9},/obj/item/weapon/implanter/explosive{pixel_x = 6; pixel_y = -6},/obj/item/weapon/implanter/explosive_macro{pixel_x = 3; pixel_y = -3},/obj/item/weapon/implanter/freedom,/obj/item/weapon/implanter/krav_maga{pixel_x = -9; pixel_y = 9},/obj/item/weapon/implanter/loyalty{pixel_x = -6; pixel_y = 6},/obj/item/weapon/implanter/storage{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"jI" = (/turf/space,/area/adminconstruction) "jJ" = (/obj/effect/decal/warning_stripes/north,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "jK" = (/obj/effect/decal/warning_stripes/north,/obj/machinery/light,/turf/simulated/floor/plating/airless,/area/syndicate_mothership) "jL" = (/obj/docking_port/stationary/transit{dwidth = 3; height = 7; id = "steel_rain_transit"; name = "steel_rain in transit"; width = 7},/turf/space/transit/horizontal,/area/space) @@ -525,7 +525,7 @@ "ke" = (/obj/structure/rack,/obj/item/clothing/suit/wizrobe/red,/obj/item/clothing/shoes/sandal,/obj/item/clothing/head/wizard/red,/obj/item/weapon/twohanded/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "kf" = (/obj/machinery/light/spot,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "kg" = (/obj/structure/rack,/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/twohanded/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"kh" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"kh" = (/obj/structure/rack,/obj/item/weapon/gun/energy/lasercannon,/obj/item/weapon/gun/energy/lasercannon{pixel_x = 6; pixel_y = -6},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "ki" = (/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/space,/area/syndicate_mothership/elite_squad) "kj" = (/turf/simulated/shuttle/wall{dir = 4; icon_state = "wall3"},/area/syndicate_mothership/elite_squad) "kk" = (/obj/machinery/computer/pod{id_tags = list("syndicate_elite"); name = "Hull Door Control"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) @@ -575,9 +575,9 @@ "lc" = (/obj/structure/table/reinforced,/obj/structure/kitchenspike,/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) "ld" = (/obj/structure/table/reinforced,/obj/structure/kitchenspike,/turf/unsimulated/floor{dir = 1; icon_state = "chapel"},/area/wizard_station) "le" = (/obj/effect/decal/cleanable/cobweb2,/obj/structure/showcase,/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) -"lf" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"lf" = (/obj/structure/rack,/obj/item/weapon/gun/energy/laser/instakill/blue{pixel_x = 3; pixel_y = -3},/obj/item/weapon/gun/energy/laser/instakill/red{pixel_x = -3; pixel_y = 3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "lg" = (/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) -"lh" = (/obj/machinery/door/airlock/external{req_access_txt = "150"},/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) +"lh" = (/obj/machinery/computer/card/centcom,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "li" = (/turf/unsimulated/wall/abductor{icon_state = "alien7"},/area/abductor_ship) "lj" = (/obj/structure/stool/bed/abductor,/turf/unsimulated/floor/abductor,/area/abductor_ship) "lk" = (/obj/structure/table/abductor,/obj/item/weapon/surgicaldrill/alien,/obj/item/weapon/circular_saw/alien,/turf/unsimulated/floor/abductor,/area/abductor_ship) @@ -591,8 +591,8 @@ "ls" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "chapel"},/area/wizard_station) "lt" = (/mob/living/carbon/human/monkey,/turf/unsimulated/floor{dir = 8; icon_state = "chapel"},/area/wizard_station) "lu" = (/turf/unsimulated/floor{icon_state = "chapel"},/area/wizard_station) -"lv" = (/obj/machinery/light/spot{tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) -"lw" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "syndicate_elite"; name = "Side Hull Door"; opacity = 0; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"lv" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"lw" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "lx" = (/obj/machinery/door/airlock/glass_security{name = "Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{id_tag = "syndicate_elite_mech_room"; name = "Mech Room Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) "ly" = (/turf/unsimulated/wall/abductor,/area/abductor_ship) "lz" = (/turf/unsimulated/wall/abductor{icon_state = "alien4"},/area/abductor_ship) @@ -605,8 +605,8 @@ "lG" = (/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) "lH" = (/turf/unsimulated/floor{dir = 1; icon_state = "chapel"},/area/wizard_station) "lI" = (/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) -"lJ" = (/obj/machinery/computer/pod{id_tags = list("syndicate_elite"); name = "Hull Door Control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) -"lK" = (/obj/machinery/computer/syndicate_elite_shuttle,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"lJ" = (/obj/structure/stool/bed/chair/comfy/black,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"lK" = (/obj/structure/rack,/obj/item/weapon/storage/box/syndie_kit/hardsuit,/obj/item/weapon/storage/box/syndie_kit/elite_hardsuit{pixel_x = -6; pixel_y = 6},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "lL" = (/obj/machinery/abductor/experiment{team = 2},/turf/unsimulated/floor/abductor,/area/abductor_ship) "lM" = (/obj/machinery/abductor/pad{team = 2},/turf/unsimulated/floor/abductor,/area/abductor_ship) "lN" = (/obj/machinery/abductor/console{team = 2},/turf/unsimulated/floor/abductor,/area/abductor_ship) @@ -627,32 +627,79 @@ "mc" = (/obj/item/trash/chips,/obj/machinery/light/spot,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "md" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/cable,/turf/simulated/floor/plasteel,/area/shuttle/gamma/space) "me" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{dir = 8; icon_state = "chapel"},/area/wizard_station) -"mg" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"mh" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/syndicate_elite/mothership) -"mi" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/poddoor{icon_state = "pdoor1"; id_tag = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite/mothership) -"mj" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"ms" = (/turf/simulated/floor/plating/airless,/area/shuttle/syndicate_elite/mothership) +"mf" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"mg" = (/obj/item/weapon/mop,/obj/structure/mirror{pixel_x = 28},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) +"mh" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"mi" = (/obj/machinery/door_control{id = "nukeop_ready"; name = "Mission Launch Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "151"},/obj/item/weapon/twohanded/required/kirbyplants,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"mk" = (/obj/structure/stool,/obj/effect/landmark{name = "Syndicate-Spawn"},/obj/effect/decal/warning_stripes/east,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"ml" = (/obj/structure/stool,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) +"mm" = (/obj/structure/stool,/obj/structure/sign/poster/legit{pixel_y = 32},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) +"mn" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) +"mo" = (/obj/structure/stool,/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) +"mp" = (/obj/structure/stool,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) +"mq" = (/obj/structure/stool,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) +"mr" = (/turf/unsimulated/wall,/area/trader_station/sol) "mt" = (/turf/space,/area/syndicate_mothership/elite_squad) "mu" = (/obj/effect/landmark{name = "Syndicate-Commando"; tag = "Commando"},/obj/machinery/light/spot,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership/elite_squad) "mv" = (/obj/machinery/light/spot,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"mw" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/trader_station/sol) +"mx" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/trader_station/sol) +"my" = (/obj/machinery/computer/shuttle/trade/sol,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mz" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mA" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mB" = (/turf/unsimulated/floor{dir = 8; icon_state = "browncorner"},/area/trader_station/sol) +"mC" = (/obj/machinery/door/airlock/external{id_tag = "trade_sol_base"; name = "Docking Port"},/turf/unsimulated/floor/plating,/area/trader_station/sol) +"mD" = (/obj/docking_port/stationary{dir = 8; dwidth = 2; height = 11; id = "trade_sol_base"; name = "docking bay 2 at Jupiter Station"; width = 5},/turf/space,/area/space) +"mE" = (/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mF" = (/turf/unsimulated/floor{dir = 8; icon_state = "brown"},/area/trader_station/sol) +"mG" = (/turf/unsimulated/floor{dir = 1; icon_state = "browncorner"},/area/trader_station/sol) +"mH" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 1},/area/trader_station/sol) +"mI" = (/obj/machinery/light{dir = 1; in_use = 1},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mJ" = (/obj/structure/stool/bed/chair/comfy/brown,/obj/effect/landmark{name = "traderstart_sol"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mK" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/trader_station/sol) +"mL" = (/obj/structure/dispenser,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mM" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance{lootcount = 4; name = "4maintenance loot spawner"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mN" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/trade_sol_rare,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mO" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/trade_sol_common,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mP" = (/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mQ" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/effect/landmark{name = "traderstart_sol"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mR" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mS" = (/obj/structure/rack,/obj/item/weapon/storage/box/syndie_kit/space,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mT" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/obj/effect/landmark{name = "traderstart_sol"},/obj/machinery/light{dir = 4},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mU" = (/turf/unsimulated/wall/fakeglass{dir = 0; icon_state = "fakewindows"; tag = "icon-fakewindows (EAST)"},/area/trader_station/sol) +"mV" = (/obj/machinery/light,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mW" = (/obj/machinery/door/airlock{name = "Toilet"; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mX" = (/obj/machinery/light{dir = 8},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"mY" = (/obj/structure/urinal{pixel_y = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"mZ" = (/obj/item/weapon/mop,/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"na" = (/obj/structure/mopbucket,/obj/machinery/light{dir = 1},/obj/item/weapon/soap,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"nb" = (/turf/unsimulated/floor{icon_state = "browncorner"},/area/trader_station/sol) +"nc" = (/turf/unsimulated/floor{icon_state = "brown"},/area/trader_station/sol) +"nd" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"ne" = (/obj/structure/mirror{pixel_x = 28},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"nf" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/trader_station/sol) +"ng" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/trader_station/sol) +"nh" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (NORTHEAST)"; icon_state = "fakewindows"; dir = 5},/area/trader_station/sol) +"ni" = (/turf/unsimulated/wall{desc = "It opens and closes."; icon = 'icons/obj/doors/Doormining.dmi'; icon_state = "door_closed"; name = "Docking Bay 2"},/area/trader_station/sol) "nj" = (/turf/unsimulated/wall,/area/syndicate_mothership) +"nk" = (/obj/structure/toilet{dir = 8},/obj/structure/window/reinforced/tinted{dir = 1},/obj/machinery/door/window{dir = 8; name = "Toilet"; opacity = 1; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/trader_station/sol) +"nl" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (NORTH)"; icon_state = "fakewindows2"; dir = 1},/area/trader_station/sol) +"nm" = (/obj/machinery/light{dir = 4},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/trader_station/sol) +"nn" = (/obj/docking_port/stationary/transit{dir = 8; dwidth = 2; height = 11; id = "trade_sol_transit"; name = "trade_sol in transit"; turf_type = /turf/space/transit/horizontal; width = 5},/turf/space/transit/horizontal,/area/space) "oB" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (WEST)"; icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) "oC" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (EAST)"; icon_state = "fakewindows"; dir = 4},/area/syndicate_mothership) "oH" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "oI" = (/obj/machinery/washing_machine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "oJ" = (/obj/structure/table,/obj/item/weapon/storage/fancy/crayons,/obj/item/weapon/storage/fancy/crayons,/obj/machinery/light{dir = 1; on = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "oO" = (/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"oP" = (/obj/item/device/radio/intercom/syndicate{pixel_x = 0; pixel_y = 25},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "oQ" = (/obj/machinery/vending/syndisnack,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "oR" = (/obj/machinery/vending/syndicigs,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pa" = (/obj/structure/noticeboard{pixel_x = -32},/obj/item/weapon/paper/syndimemo,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"pb" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pc" = (/mob/living/simple_animal/pet/fox/Syndifox,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pd" = (/obj/effect/decal/warning_stripes/southeastcorner,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pe" = (/obj/effect/decal/warning_stripes/south,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pm" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/cans/beer{pixel_x = -2; pixel_y = 5},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"po" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark{name = "Syndicate-Spawn"},/obj/effect/decal/warning_stripes/east,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pp" = (/obj/machinery/computer/telecrystals/uplinker,/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership) "pu" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows (NORTHWEST)"; icon_state = "fakewindows"; dir = 9},/area/syndicate_mothership) "pv" = (/turf/unsimulated/wall/fakeglass{tag = "icon-fakewindows2 (WEST)"; icon_state = "fakewindows2"; dir = 8},/area/syndicate_mothership) @@ -663,7 +710,6 @@ "pA" = (/obj/machinery/light,/turf/unsimulated/floor{icon_state = "floor"},/area/syndicate_mothership) "pC" = (/obj/machinery/door/poddoor{id_tag = "nukeop_ready"; name = "Shuttle Dock Door"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "pF" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership) -"pH" = (/obj/machinery/door_control{id = "nukeop_ready"; name = "Mission Launch Control"; pixel_x = -26; pixel_y = -2; req_access_txt = "151"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "pR" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/drinkingglasses,/obj/item/weapon/reagent_containers/food/drinks/bottle/rum,/turf/unsimulated/floor{dir = 2; icon_state = "wood"},/area/syndicate_mothership) "pS" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{dir = 2; icon_state = "wood"},/area/syndicate_mothership) "pT" = (/obj/structure/table/woodentable,/obj/item/device/syndicatedetonator,/turf/unsimulated/floor{dir = 2; icon_state = "wood"},/area/syndicate_mothership) @@ -688,7 +734,6 @@ "qL" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "qM" = (/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "qX" = (/turf/unsimulated/wall/fakeglass{dir = 8; icon_state = "fakewindows3"; tag = "icon-fakewindows (WEST)"},/area/syndicate_mothership) -"qY" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "re" = (/obj/structure/closet/syndicate/personal,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/syndicate_mothership) "rf" = (/obj/structure/table,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/syndicate_mothership) "rE" = (/turf/unsimulated/wall,/area/start) @@ -727,10 +772,8 @@ "sx" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) "sy" = (/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "sz" = (/obj/machinery/atm{pixel_y = 24},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) -"sA" = (/obj/structure/stool{pixel_y = 8},/obj/structure/sign/poster/legit{pixel_y = 32},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) "sB" = (/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 2; pixel_y = 6},/obj/structure/table,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "sC" = (/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/structure/table,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) -"sD" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) "sE" = (/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/control) "sF" = (/obj/structure/closet/secure_closet/bar{req_access = null; req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "sG" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) @@ -742,7 +785,6 @@ "sM" = (/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/structure/table,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "sN" = (/obj/structure/table,/obj/machinery/juicer{pixel_y = 6},/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "sO" = (/obj/structure/piano,/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) -"sP" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/light/spot{tag = "icon-tube1 (EAST)"; icon_state = "tube1"; dir = 4},/turf/unsimulated/floor{tag = "icon-redyellowfull"; icon_state = "redyellowfull"},/area/centcom/control) "sQ" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "sR" = (/obj/structure/closet/secure_closet/freezer/meat{req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) "sS" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) @@ -751,7 +793,6 @@ "sV" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "sW" = (/obj/machinery/door/airlock/centcom{name = "Freezer"; opacity = 1; req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/control) "sX" = (/turf/unsimulated/wall,/area/centcom/specops) -"sY" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "sZ" = (/obj/structure/table,/obj/machinery/processor{pixel_x = 0; pixel_y = 10},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "ta" = (/obj/machinery/mech_bay_recharge_port/upgraded,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "tb" = (/obj/machinery/camera{c_tag = "CentComm Special Ops. Assault Armor North"; dir = 2; network = list("ERT","CentComm")},/obj/mecha/combat/marauder/seraph/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) @@ -907,7 +948,6 @@ "wc" = (/turf/unsimulated/floor{tag = "icon-warning (NORTHWEST)"; icon_state = "warning"; dir = 9},/area/centcom/specops) "wd" = (/turf/unsimulated/floor{dir = 5; icon_state = "warning"},/area/centcom/specops) "we" = (/turf/space,/area/centcom/specops) -"wf" = (/obj/item/weapon/gun/projectile/automatic/pistol/m2411,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/item/ammo_box/magazine/m45,/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/head/helmet/space/deathsquad/beret,/obj/item/clothing/shoes/combat,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/gloves/combat,/obj/item/clothing/suit/space/deathsquad/officer,/obj/item/clothing/under/rank/centcom/captain,/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs,/obj/item/clothing/mask/gas,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "wg" = (/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "wh" = (/obj/machinery/recharge_station/upgraded,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/specops) "wi" = (/turf/unsimulated/wall{icon = 'icons/obj/library.dmi'; icon_state = "book-5"; name = "bookcase (Tactics)"},/area/centcom/specops) @@ -1005,7 +1045,6 @@ "zd" = (/obj/machinery/vending/boozeomat,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "ze" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "zf" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) -"zg" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/evac) "zh" = (/obj/machinery/computer/card,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "zi" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) "zj" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/centcom/evac) @@ -1109,7 +1148,6 @@ "Ex" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/obj/item/weapon/reagent_containers/glass/beaker/bluespace,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) "Ey" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) "Ez" = (/obj/structure/table,/obj/item/weapon/storage/pill_bottle/random_drug_bottle,/obj/item/weapon/reagent_containers/glass/bottle/adminordrazine,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) -"EA" = (/turf/space,/turf/unsimulated/wall{dir = 1; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/adminconstruction) "EB" = (/obj/machinery/door/airlock/external,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "ADMINLOCKDOWN"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "EC" = (/obj/machinery/door/airlock/hatch{name = "External Airlock"; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "ED" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/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/admin) @@ -1136,12 +1174,12 @@ "EY" = (/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/turf/unsimulated/wall{dir = 4; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5"; name = "window"; opacity = 0; tag = "icon-window5 (EAST)"},/area/admin) "EZ" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/turf/unsimulated/wall{dir = 2; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5"; name = "window"; opacity = 0; tag = "icon-window5"},/area/admin) "Fa" = (/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "ADMINCHEMLOCKDOWN"; name = "Security Doors"; opacity = 0},/obj/machinery/door/airlock/hatch{name = "Chem Lab"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) -"Fb" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/ammo_box/magazine/m762,/obj/item/weapon/gun/projectile/automatic/l6_saw,/obj/item/weapon/gun/projectile/automatic/l6_saw{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"Fb" = (/obj/structure/rack,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/ammo_box/magazine/mm556x45,/obj/item/weapon/gun/projectile/automatic/l6_saw,/obj/item/weapon/gun/projectile/automatic/l6_saw{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fc" = (/obj/structure/rack,/obj/item/weapon/gun/projectile/automatic/proto,/obj/item/weapon/gun/projectile/automatic/proto{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fd" = (/obj/structure/rack,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/magazine/m556,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/ammo_box/a40mm,/obj/item/weapon/gun/projectile/automatic/m90,/obj/item/weapon/gun/projectile/automatic/m90{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Fe" = (/obj/structure/mirror{dir = 4; pixel_x = 0; pixel_y = -32},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Ff" = (/obj/machinery/optable,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) -"Fh" = (/obj/structure/table,/obj/item/weapon/gun/energy/pulse_rifle/pistol,/obj/machinery/door_control{desc = "A remote control switch to lock down the admin lab."; icon_state = "doorctrl0"; id = "ADMINCHEMLOCKDOWN"; name = "Lockdown"; pixel_y = 24; req_access_txt = "0"},/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/admin) +"Fh" = (/obj/structure/table,/obj/item/weapon/gun/energy/pulse/pistol,/obj/machinery/door_control{desc = "A remote control switch to lock down the admin lab."; icon_state = "doorctrl0"; id = "ADMINCHEMLOCKDOWN"; name = "Lockdown"; pixel_y = 24; req_access_txt = "0"},/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/admin) "Fi" = (/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/admin) "Fj" = (/obj/machinery/computer/secure_data,/obj/item/weapon/paper/sop,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/admin) "Fk" = (/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/turf/unsimulated/wall{dir = 8; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/admin) @@ -1163,7 +1201,7 @@ "FA" = (/obj/structure/table,/obj/structure/window/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/admin) "FB" = (/obj/structure/table,/obj/machinery/door/window/southleft{name = "security checkpoint"; req_access_txt = "0"},/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/admin) "FC" = (/obj/structure/table,/obj/structure/window/reinforced,/obj/machinery/recharger,/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/admin) -"FD" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911,/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"FD" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse/pistol/m1911,/obj/item/weapon/gun/energy/pulse/pistol/m1911{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FE" = (/obj/structure/table,/obj/item/weapon/tank/oxygen/yellow,/obj/random/bomb_supply,/obj/item/clothing/under/rebeloutfit,/obj/item/clothing/suit/poncho/ponchoshame,/obj/item/clothing/head/sombrero/shamebrero,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "FF" = (/obj/machinery/door/airlock/hatch{name = "Tool Storage"; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "FG" = (/obj/structure/table,/obj/item/weapon/FixOVein,/obj/item/weapon/retractor,/obj/item/weapon/cautery,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/admin) @@ -1174,8 +1212,8 @@ "FL" = (/turf/simulated/wall/r_wall,/area/adminconstruction) "FM" = (/obj/structure/rack,/obj/item/weapon/gun/energy/meteorgun,/obj/item/weapon/gun/energy/meteorgun{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FN" = (/obj/structure/rack,/obj/item/weapon/twohanded/knighthammer{pixel_x = -3; pixel_y = 3},/obj/item/weapon/twohanded/mjollnir,/obj/item/weapon/twohanded/singularityhammer{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"FO" = (/obj/structure/rack,/obj/item/weapon/gun/energy/crossbow,/obj/item/weapon/gun/energy/crossbow{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"FP" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse_rifle,/obj/item/weapon/gun/energy/pulse_rifle{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"FO" = (/obj/structure/rack,/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow,/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) +"FP" = (/obj/machinery/recharger/wallcharger{pixel_x = 30},/obj/structure/rack,/obj/item/weapon/gun/energy/pulse,/obj/item/weapon/gun/energy/pulse{pixel_x = 3; pixel_y = -3},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "FQ" = (/obj/structure/table,/obj/random/tool,/obj/item/clothing/gloves/color/yellow,/obj/item/weapon/pinpointer/advpinpointer,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "FR" = (/obj/structure/table,/obj/item/weapon/grenade/syndieminibomb{pixel_x = 4; pixel_y = 2; pixel_z = 0},/obj/item/weapon/grenade/syndieminibomb{pixel_x = -1},/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) "FS" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/obj/item/toy/cards/deck/syndicate/black,/turf/unsimulated/floor{tag = "icon-dark"; icon_state = "dark"},/area/admin) @@ -1199,7 +1237,6 @@ "Gk" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/turf/unsimulated/wall{dir = 2; icon = 'icons/turf/shuttle.dmi'; icon_state = "window5"; name = "window"; opacity = 0; tag = "icon-window5"},/area/admin) "Gl" = (/obj/structure/stool/bed/chair/comfy/black,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) "Gm" = (/obj/machinery/computer/card,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"Gn" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Go" = (/obj/machinery/door/airlock/glass{name = "Computer Hub"; req_access_txt = "0"},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "ADMINLOCKDOWN"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gp" = (/obj/effect/landmark{name = "aroomwarp"; tag = ""},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gq" = (/obj/machinery/door/airlock/hatch{desc = "For all your shady business needs"; name = "Gambling Den"; req_access_txt = "0"},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) @@ -1208,12 +1245,10 @@ "Gt" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/devilskiss,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) "Gu" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/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/admin) "Gv" = (/obj/machinery/computer/artillerycontrol{luminosity = 255},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"Gw" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "Gx" = (/obj/item/weapon/stool,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) "Gy" = (/obj/structure/table/woodentable,/obj/item/weapon/lighter/zippo/engraved,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/admin) "Gz" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/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/admin) "GA" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) -"GB" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) "GC" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/turf/unsimulated/wall{dir = 1; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/admin) "GD" = (/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/turf/unsimulated/wall{dir = 8; icon = 'icons/turf/shuttle.dmi'; icon_state = "diagonalWall3"},/area/admin) "GE" = (/obj/machinery/computer/message_monitor,/obj/item/weapon/paper/monitorkey,/turf/unsimulated/floor{tag = "icon-floor"; icon_state = "floor"},/area/admin) @@ -1342,68 +1377,68 @@ ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdkdjdjdjdlbsbqbEbqbqbFbsbGbHbGbHbGbsbIbIbIbIbIbsbxbJbxbJbxbsbybybybybybsbzbKbzbKbzbsbLbMbMbMbNbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdkdjdjdjdlbsbqbObqbqbqbsbPbQbPbQbPbsbIbIbIbIbIbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdkdjdjdjdlbsbqbqbRbSbqbsbTbTbTbTbTbsbUbUbUbUbVbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdndmdmdmdrbscabqbqbqbqbscbcccdcccebscfcgchcicfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdxdvdvdvdybsbqcabqbqctbscucccdcccvbscfcwcxcycfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcRcScTcocScUcocScVcocWcXcocScUcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqbEcabqbRbsbTbTbTbTbTbsdbcwcxcydbbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcododpcodocXcododqcodocUcodocTcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqbqbqcabqbsdsdtdsdtdsbsducwcxcydubsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapaparapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqdGbqbqcabsbGbHbGbHbGbsducwcxcydubsbxbJbxbJbxbsbybybybybybsbzbKbzbKbzbsczbMbMbMcAbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocSdpcodKcTcocScTcodLcUcocScXcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdCdBdBdBdDbsbRbqdNbqbEbsbtbubtbubtbsdOdPdQdRdObsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsdSdTdTdTdUbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcodocTcodocUcodocUcodoedcodoeecoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNhyhzhzhzhzhzbZejejejejejbZejejejejejbZejejejejejbZekekekekekbZekekekekekbZekekekekekbZekekekekekel -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeqbserererererbseseseteueubsevevevevevbsewexexexeybsezeAeAeAeBbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckbockckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeDeqeqeqbsereEeFeGerbseHeHeIeJeJbseveKeveLevbseMeNeNeNeObsePeQeQeQeRbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapavapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqeqeqeXeqbsereYeYeYerbseHeZeZeZeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfffffffffffgfgfhfififjfgfgfgfgfgfgfgfgfgfkfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeqbserererererbseHeIeIeIeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNftfufvfwfffgfxfyfzfAfAfBfCfDdJdMfGfHfIfHfHfJfKfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeqeqfMeqbserfNfOfPerbsfQfRfRfRfSbsevfTevevevbsfUfVfVfVfWbsePeQeQeQeRbD -ckckckckckckckclckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfffffffufufufffggbfyfyfyfyfygcgdgdgdgefHfHfHgffHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqgkeqeqeqbserglgmgnerbsgogpgpgpgqbsevevevgrevbsgsgtgtgtgubsgveQeQeQgwbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNgygzgAfufufufffggBfygCgDgEgFgGgdgdgdgdfHfHgHfHgIfIfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeDbserglgmgnerbsgJeIgKeIgLbsevevevevevbsgMeNeNeNgNbsgveQeQeQgwbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckcmckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNgOgPgQfufufufffggRgdgegegegegegdgdgdgdfHfHfHgSfHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbsgTeqeqeqeqbserglgmgnerbsgJgUgUgUgLbsgVgVgVgVgVbsgMeNeNeNgNbsgveQeQeQgwbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfffffffffffffffggWgdgdgdgdgdgdgdgdgdgdgXfHfHfHfHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqfMeqgkeqbsergYgZhaerbsgJgJeIgLgLbshbhbhbhbhbbsgMeNeNeNgNbsgveQeQeQgwbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfggWgdgdgdgdgdhcgdgdhcgdhdhehehehfhefgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqgTbserererererbshhhhhihjhjbshkhkhkhkhkbshlhmhmhmhnbshohphphphqbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfghrgdgdgdgdgehshtgehsgehuhvhvhvhwhvfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNhyhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhB -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfgfghChDhDhCfgfgfgfgfgfgfgfgfgfgfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfghEhFhFhFfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZaPaPaPaPaPbZaPaPaPaPaPbZaPaPaPaPaPbZ -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfghFhFhFhFfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphHhIhJhKhLbshMhNhOhPhQbshRhShThUhVbD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNfgfgfgfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphWhWhXhWhWbshYhZhZhZhYbsiaiaiaiaiabD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphWhWhWhWhWbshYhZhZhZhYbsiaiaiaiaiabD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpibichWicibbshYidhZidhYbsieifiaigiebD -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZhzhzhzhzhzbZhzhzhzhzhzbZhzhzhzhzhzbZ -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdndmdmdmdrbscabqbqbqbqbscbcccdcccebscfcgchcicfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsbLbMbMbMbNbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdxdvdvdvdybsbqcabqbqctbscucccdcccvbscfcwcxcycfbsbxbxbJbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcRcScTcocScUcocScVcocWcXcocScUcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqbEcabqbRbsbTbTbTbTbTbsdbcwcxcydbbsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcododpcodocXcododqcodocUcodocTcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqbqbqcabqbsdsdtdsdtdsbsducwcxcydubsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsczbMbMbMcAbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapaparapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdzdjdjdjdAbsbqdGbqbqcabsbGbHbGbHbGbsducwcxcydubsbxbJbxbJbxbsbybybybybybsbzbKbzbKbzbsczbMbMbMcAbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcocSdpcodKcTcocScTcodLcUcocScXcoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpdCdBdBdBdDbsbRbqdNbqbEbsbtbubtbubtbsdOdPdQdRdObsbxbxbxbxbxbsbybybybybybsbzbzbzbzbzbsdSdTdTdTdUbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcodocTcodocUcodocUcodoedcodoeecoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNhyhzhzhzhzhzbZejejejejejbZejejejejejbZejejejejejbZekekekekekbZekekekekekbZekekekekekbZekekekekekel +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNcocococococococococococococococoaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeqbserererererbseseseteueubsevevevevevbsewexexexeybsezeAeAeAeBbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckbockckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeDeqeqeqbsereEeFeGerbseHeHeIeJeJbseveKeveLevbseMeNeNeNeObsePeQeQeQeRbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapavapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqeqeqeXeqbsereYeYeYerbseHeZeZeZeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNfffffffffffgfgfhfififjfgfgfgfgfgfgfgfgfgfkfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeqbserererererbseHeIeIeIeJbsevevevevevbseMeNeNeNeObsePeQeQeQeRbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNftfufvfwfffgfxfyfzfAfAfBfCfDdJdMfGfHfIfHfHfJfKfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbseqeqeqfMeqbserfNfOfPerbsfQfRfRfRfSbsevfTevevevbsfUfVfVfVfWbsePeQeQeQeRbD +ckckckckckckckclckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNfffffffufufufffggbfyfyfyfyfygcgdgdgdgefHfHfHgffHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqgkeqeqeqbserglgmgnerbsgogpgpgpgqbsevevevgrevbsgsgtgtgtgubsgveQeQeQgwbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNgygzgAfufufufffggBfygCgDgEgFgGgdgdgdgdfHfHgHfHgIfIfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqeDbserglgmgnerbsgJeIgKeIgLbsevevevevevbsgMeNeNeNgNbsgveQeQeQgwbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckcmckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNgOgPgQfufufufffggRgdgegegegegegdgdgdgdfHfHfHgSfHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeoepeneoepbsgTeqeqeqeqbserglgmgnerbsgJgUgUgUgLbsgVgVgVgVgVbsgMeNeNeNgNbsgveQeQeQgwbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckiAckckckckckckckckckaNaNaNaNaNfffffffffffffffggWgdgdgdgdgdgdgdgdgdgdgXfHfHfHfHfHfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpepeneoepenbseqfMeqgkeqbsergYgZhaerbsgJgJeIgLgLbshbhbhbhbhbbsgMeNeNeNgNbsgveQeQeQgwbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNfggWgdgdgdgdgdhcgdgdhcgdhdhehehehfhefgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpeneoepeneobseqeqeqeqgTbserererererbshhhhhihjhjbshkhkhkhkhkbshlhmhmhmhnbshohphphphqbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNfghrgdgdgdgdgehshtgehsgehuhvhvhvhwhvfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNhyhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhAhzhzhzhzhzhB +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNapapapapapapapapapapapapapapapapapapapapapapapapaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNfgfghChDhDhCfgfgfgfgfgfgfgfgfgfgfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNfghEhFhFhFfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZaPaPaPaPaPbZaPaPaPaPaPbZaPaPaPaPaPbZ +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNfghFhFhFhFfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphHhIhJhKhLbshMhNhOhPhQbshRhShThUhVbD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNfgfgfgfgfgfgaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphWhWhXhWhWbshYhZhZhZhYbsiaiaiaiaiabD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbphWhWhWhWhWbshYhZhZhZhYbsiaiaiaiaiabD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbpibichWicibbshYidhZidhYbsieifiaigiebD +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZhzhzhzhzhzbZhzhzhzhzhzbZhzhzhzhzhzbZ +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihiiijikiliminihioipiqihaNaNirisisisisisitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauataNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikikikikixiyizihaNaNisiAiBiCiDiEitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauayauataNaNaNaNaNaNaNaNaNaNaNbZdEdEdEdEdEbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZdFdFdFdFdFbZaNaNaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihiLiLikikikiMihiNiOiPihaNaNisiQiRiRiRiQititititaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauataNaNaNaNaNaNaNaNaNbZbZbZiZiZiZiZiZjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaiZiZiZiZiZbZbZbZaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikjdjdihihjeihihaNaNisiQjfjfjfiQitjgjhitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatatatataFaGaGaGaGaGaGaGaHatataIatataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihjAjAikjBjCjDihjEjejFihaNaNisiQjGjHjIiQititititititititititititaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataJaJaJaKauauauauauauauauaKaKaKauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN -ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkbikikjBkckdihkekfkgihaNaNisiQkhjHjIiQkikjkkklkmknkjkokpkqkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataKauauauauauauauaMauauauauauauauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpkBkCkBjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkJikikikikihihihihihihaNaNisiQkhjHjIiQkKkjknknkLknkjknkrkrkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatbhauauauauauaubibibiauauauauauauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpkBkTkBjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkWkXkYkZiklalblcldleihaNaNisiQjHjHjHlflglhknknkLknkjkokpkrkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatbhauauauauaubjbibibibjauauauauauaKataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlolplqikikiklrlsltluihaNaNisiQlvjHjHlwlglhknknknknlxknkrkrkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatbhauauauauauaubjbjbjauauauauauauauataNaNaNaNaNaNaNaNaNbZbZbZlBlBlBlBlBlClDjpjpjpjpjpjplEjpjpjpjpjpjplDlClBlBlBlBlBbZbZbZaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlGlplqikikiklHlIlHlIihaNaNisiQlJjHlKiQkKkjknknkLknkjkokpkrkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauauauauauauauauauauauauauauauataNaNaNaNaNaNaNaNaNaNaNbZlWlWlWlWlWbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZlXlXlXlXlXbZaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlomambkJmcladclumeddihaNaNismgmhmimhmjkikjknknkLknkjknkrkrkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauaKaJaJaKauauauauauauauauauauauataNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNisaNmgmsmjaNmtkjknknmuknkjkokpmvkrksaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatbkatatatatatatatatatatatatatbkatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNititititititititititititititititititaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckbmckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckaackckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatatblblatatatatatatatatatatatatatblblatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckaEckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababacababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbnaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababacabababababababababababababababababababababababababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababadababababababababababababaeababacabafababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckawckckckckckaxckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababababafabafababababafabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababacababadababacafabadabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababagagagagagagagababababahababacabahabababacabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiacabababababajagagakagakababafabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababacamnjnjoBoCnjnjanagagagnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababaonjnjoHoIoIoJnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalababadaonjaLoOoOoOoOoPoQoRnjfYjMfZnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiababababaSnjpaoOpbpbpcoOpdpepWpXpXganjnjnjnjnjnjnjnjnjnjnjnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNaTagagababaUamnjplpbpmjNpboOpoppnjpXggnjnjghgjgigxgxhggxgxhxhGnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNpupvpvpvpvpvoCnjoOpbpwpxpboOpoppnjnjnjnjnjgjgiiuiwiviFiviHiGhxnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaiaNaNaNaNaNaNaNaNaNpypzpApzpzpzpzpCoOJboOoOoOoOpoppnjnjnjnjnjgjiIiwiviJiSiKiviHiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNpFaVoBpvpvpvoCnjpHpbpbpboOoOpoppoBpvpvpvpvpvpviviJiSiUiSiKiviTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikikikikixiyizihaNaNisaNaNaNaNaNitaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauayauataNaNaNaNaNaNaNaNaNaNaNbZdEdEdEdEdEbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZdFdFdFdFdFbZaNaNaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihiLiLikikikiMihiNiOiPihaNaNisaNaNaNaNaNititititaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNatauauauataNaNaNaNaNaNaNaNaNbZbZbZiZiZiZiZiZjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaiZiZiZiZiZbZbZbZaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihikikikikjdjdihihjeihihaNaNisaNaNaNaNaNitjgjhitaNaNaNaNaNaNaNaNaNaNmrmrmrmrmrmrmrmrmrmrmrmrmrmxmwatatatatataFaGaGaGaGaGaGaGaHatataIatataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihjAjAikjBjCjDihjEjejFihaNaNisaNaNaNaNaNititititititititititititaNaNmraNaNaNaNaNaNaNaNaNaNaNmrmzmyataJaJaJaKauauauauauauauauaKaKaKauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN +ckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkbikikjBkckdihkekfkgihaNaNisaNaNaNaNaNkikjkkklkmknkjkokpkqkrksaNaNmraNaNaNaNaNaNaNaNaNaNaNmrmBmAataKauauauauauauauaMauauauauauauauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpkBkCkBjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkJikikikikihihihihihihaNaNisaNaNaNaNaNkKkjknknkLknkjknkrkrkrksaNaNmraNaNaNaNaNaNaNaNaNaNmDmCmFmEatbhauauauauauaubibibiauauauauauauaJataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpkBkTkBjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihkWkXkYkZiklalblcldleihaNaNisaNaNaNaNaNlgiBknknkLknkjkokpkrkrksaNaNmraNaNaNaNaNaNaNaNaNaNaNmrmGmEatbhauauauauaubjbibibibjauauauauauaKataNaNaNaNaNaNaNaNaNbZjljmbZbZbZbZbZjnjojpjpjpjpjpjpjpjpjpjpjpjpjpjqjnbZbZbZbZbZjmjrbZaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlolplqikikiklrlsltluihaNaNisaNaNaNaNiClgiBknknknknlxknkrkrkrksaNaNmraNaNaNaNaNaNaNaNaNaNaNmrmEmEatbhauauauauauaubjbjbjauauauauauauauataNaNaNaNaNaNaNaNaNbZbZbZlBlBlBlBlBlClDjpjpjpjpjpjplEjpjpjpjpjpjplDlClBlBlBlBlBbZbZbZaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlGlplqikikiklHlIlHlIihaNaNisaNaNaNaNaNkKkjknknkLknkjkokpkrkrksaNaNmrmrmrmrmrmrmrmrmrmrmrmrmrmEmEatauauauauauauauauauauauauauauauauauataNaNaNaNaNaNaNaNaNaNaNbZlWlWlWlWlWbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZbZlXlXlXlXlXbZaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihlomambkJmcladclumeddihaNaNisaNaNaNaNaNkikjknknkLknkjknkrkrkrksaNaNaNaNaNaNmHmEmEmEmImEmEmEmEmEmJatauauaKaJaJaKauauauauauauauauauauauataNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbZbZbZbZbZbZbZaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNihihihihihihihihihihihihaNaNisaNaNaNaNaNmtkjknknmuknkjkokpmvkrksaNaNaNaNaNaNmKmEmLmNmMmOmOmMmEmQmPatatbkatatatatatatatatatatatatatbkatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNititititititititititititititititititaNaNaNaNaNaNmKmEmEmEmEmEmEmEmEmQmRatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckbmckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNmKmEmMmOmOmOmSmMmEmEmTatblblataNaNaNaNaNaNaNaNaNaNaNatblblataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckaackckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNmUmVmEmEmEmEmEmEmEmEatatblblatatatatatatatatatatatatatblblatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckaEckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababacababababababababababababababababababnjaNaNaNaNaNmrmrmrmWmrmXmOmOmMmEmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbnaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababacabababababababababababababababababababababababababnjaNaNaNaNaNmrmYnamZmrmEmEmEmEnbncataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababadababababababababababababaeababacabafababnjaNaNaNaNaNmrndndnemrnfngngngnhniataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckawckckckckckaxckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababababafabafababababafabababnjaNaNaNaNaNmrndnkmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababababababababababababacababadababacafabadabababnjaNaNaNaNaNmrmrmrmrmraNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababababababagagagagagagagababababahababacabahabababacabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiacabababababajagagakagakababafabnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlnmataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababacamnjnjoBoCnjnjanagagagnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalabababaonjnjoHoIoIoJnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaNaNaNaNaNaNaNaNaNalababadaonjaLoOoOoOoOfZoQoRnjfYjMmgnjaNaNaNaNaNaNaNaNaNaNaNaNnlmEataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababaiaNaNaNaNaNaNaNaiababababaSnjpaoOmfmfpcoOpdpepWpXpXganjnjnjnjnjnjnjnjnjnjnjnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNaTagagababaUamnjplmfpmjNmfoOmkppnjpXggnjnjghgjgigxgxhggxgxhxhGnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabababababababaNaNaNaNaNpupvpvpvpvpvoCnjmhmfpwpxmfoOmkppnjnjnjnjnjgjgiiuiwiviFiviHiGhxnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaiaNaNaNaNaNaNaNaNaNpypzpApzpzpzpzpCoOJboOoOoOoOmkppnjnjnjnjnjgjiIiwiviJiSiKiviHiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNpFaVoBpvpvpvoCnjmimfmfmfmhoOmkppoBpvpvpvpvpvpviviJiSiUiSiKiviTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaWaNaiababaXnjpRpSpTpSjOoOpUpViWiViViXiViViWiFiSiYjjjiiSiFiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjaYabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaZabaonjqfqgqhqiqjoOoOoOoBpvpvpvpvpvpviviJiSjkiSiSiviTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaNaNaNalabaonjnjppqtqrqunjqwoOnjnjnjnjnjgjiIjsiviJiSiKivjtiTnjaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjababaNaNaNaNaNaNaNaNaNaNaNaNaNaNanabababnjnjnjnjnjnjqDqDqEqFqGqHnjgjjvjujsivjwivjtjxjynjaNaNaNatatatatatatatatatatatatatatatatatatatatataNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaiabababbababbaXnjqLqMqMqMqMqMnjjzgjjvjJjJjKjJjJjyjznjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababacababaoqXqMqMqMqMqMqYnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababacababaoqXqMqMqMqMqMmlnjnjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababadbcakamnjrerererererfnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNalababaonjnjnjnjnjnjnjnjnjnjnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckckaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNnjabaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbdabababnjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1459,12 +1494,12 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqsqsqsqsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqsrssstsqsqsqsqsusvsvsvsqsqsqsqsqsqsqsqsqsqsqsqsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqswsssssxsyszsAsBsCsDsEsEsysysqsFsGsHsIsqsJsKsLsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqsqsqsqsqsysEsDsMsNsDsEsEsOsPsqsQsQsQsQsqsRsSsTsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqswsssssxsyszmmsBsCmnsEsEsysysqsFsGsHsIsqsJsKsLsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsqsqsqsqsqsysEmnsMsNmnsEsEsOmosqsQsQsQsQsqsRsSsTsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsvsEsEsEsEsEsEsEsEsysysqsQsUsVsVsqsqsWsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsqaNaNaNsvsEsEsEsEsEsEsEsEsEsEsusQsYsYsQsQsQsQsZsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXsXsXsXsXsXsXsXtatbtctdtdtesqsqsqsqsqsEsEsDsMsCsDsEsEsEsEsEsQsQsQsQtfsQsQtgsqsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNthtitititititititititjtktitititjtltmtntdtdtdsqsrssstsqtosEsDsMtpsDsEsEsEsEsutqsQsQsQtrsQsQtssqsqsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsqaNaNaNsvsEsEsEsEsEsEsEsEsEsEsusQmpmpsQsQsQsQsZsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXsXsXsXsXsXsXsXtatbtctdtdtesqsqsqsqsqsEsEmnsMsCmnsEsEsEsEsEsQsQsQsQtfsQsQtgsqsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNthtitititititititititjtktitititjtltmtntdtdtdsqsrssstsqtosEmnsMtpmnsEsEsEsEsutqsQsQsQtrsQsQtssqsqsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXsXsXsXsXsXsXsXtatttutdtdtdsqswsssssxsEsEsEsEsEsEsEsEsEsEsqsusususususususqsqdWdXsqsqsqsqsqsqsqsqsqsqsqsqsqdVaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNthtitititititititititvtktitititvtwtmtntdtdtdsqsqsqsqsqsqsqtxsqsqsqsqsEsEtysqtztztztztztztzsudZdYebeasuecegefeieheCemeTeSeVeUeWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXsXsXsXsXsXsXsXtatttutdtdtAsqtBtCtDsqtEtFtFtFtFtGsqsEsEtHsqtztztztztztztzsufbfatLfcsufdflfefnfmfpfofrfqfEfsfFaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1482,7 +1517,7 @@ aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXvkvkvkvxujujujvyvyujujujvzvdvAvBvCbesXvEtTuEtRtRvFtRtRtZsqsqsusususususqsqtQtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXvGvHsXvIvJujujujujvLujsXvdvMvNvOvPsXvQtRtRtRtZsutQtRtStTtTtTtTtTtTtTtTtTuEtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNsXsXsXsXsXsXsXsXbfbfsXsXsXvSvTvUvVvdsXvWtRtRtRvXsutQtRtRtRtRtRtRtRtRtRtRtRtRtRtZsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwbwcwdwbwesXwfwgwhwiwjsXwkudududwlsuwmudududududuetRucudududududwnsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwbwcwdwbwesXiDwgwhwiwjsXwkudududwlsuwmudududududuetRucudududududwnsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwrwswtwrwesXsXsXsXsXsXsXsqsqsqsqsqsqsqsqsqsqsqsqsqwusqsqsqsqsqsqsqsqaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwCwDwEwFwGwCwHwIwJwKwLwMwNwOwPwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwCwCwCwIwIwIwIwIwIwKxcxdxexdxfwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1496,9 +1531,9 @@ aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbW aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNxdxmxXxYwNxXxYxfyGytyGwNwNwNyHxzxzxzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyiyvyvyKyLyMyNyMyOyMyNyMyPyKyvyvyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKxyyQyQyQyRwNxfypxdwKyqwNwNwNwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNySyFyvyTyMyNyNyNyNyNyNyNyMyTyvywyUaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKwKwKwKxdxdwKwKxmwNxfxdxLwKwNwNwNwNwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNySylyoyWyXyYyZyNzazbyNzcykylyUaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKzdzezfzgzezewKxmwNxfypxdwKyqwNwNwNwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizhzizjzkyNzazbyNyyyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKzlzezmzgzezeznxmwNxfyGytyGwNwNwNygxzxzxzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizqzrzryZyNzazbyNyMyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKztzezuzgzezewKxyyQzvwKwKwKyqwNwNyrcnytcnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizxzrzrzyyNyMyMyNyNaBaCaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKzdzezfmqzezewKxmwNxfypxdwKyqwNwNwNwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizhzizjzkyNzazbyNyyyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKzlzezmmqzezeznxmwNxfyGytyGwNwNwNygxzxzxzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizqzrzryZyNzazbyNyMyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKztzezumqzezewKxyyQzvwKwKwKyqwNwNyrcnytcnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizxzrzrzyyNyMyMyNyNaBaCaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNwKztzezezezezewKwKzBwKwKxLwKwNwNwNyHxzxzxzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNykylylylyoyNzazbyNzHyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcjcjcjcjcjcjcjcjcjcjcjcjcjcjcjytytytwKxLwKxZxZxZxZwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNyizOzOzPzQyNzazbyNzRyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNcjcpcpcpcpcpcpcpcpcpcpcpcpcpcqytytytwKxLwKxzxzxzxzwKaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNzVzWzWzWzXyNzazbyNyMyiaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1536,34 +1571,34 @@ aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbW aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtaNaNaNaNaNDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDvDtDwDxDyDyDyDzDwDuDvaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDADBDCDDDEDFDGDHDADuaNaNaNaNaNaNDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDJDKDKDKDKDKDLDADwDMDwDMDwDMDwDwDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNDODKDPcQDRDKDSDADTDKDUDKDVDWDXDYDADuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNDZDKEaEbEcDKEdDADKDKDKDKDKDKDKEeDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfEgEhDKDKDKEhEiDAEjDKEkDKElDWDXDYEfaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwDKDKDKDwDwDADKDKDKDKDKDKDKEmDAEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDuaNDADwDwDMEoDMDwDwDwDwDwDMEpDMDwDwDwEnaNDtDwEqErErEsDwDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwEtDKDKDKDKDKDKDKDKDKDKDKDKEuDAEnaNDtDwEvEwExEyEwEzDwEAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEBDKECDKDKDKDKDKDKDKDKDKDKDKDKDKDKDAaNaNaNEDEEEFEwEwEwEGEDaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwDwDwDwDMEHDMDwDwDwDwDwEIDKDKDAaNaNaNEJEKEwEwEwEwELEJaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEnaNEMDAENEOEPDKDKEQERESETEuDADKDKDAaNaNDtDAEUEwEVEWEwEXDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWjLbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKDKDKDKDKDKDKEYDKDKDADwEZDwDwDwFaDwDwFaDwDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFbFcFdDKDKDKFeFeFeDKEHDKDKDAFfEwEwdfDADKDAFhFiFjDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKDKFkDwDwDwDwDADKDKDAEwEwFlFmDADKDAFnFoFpDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFqFrFsDKFtDAFuFvFwFxDADKDKDAFyEwEwFzDADKDAFAFBFCDNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKFDDAFEFvFvFvFFDKDKDAFGEwEwFHDADKDKDKDKDKEfaNaNaNaNDtDwFIFJFKDwDuaNaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFMFNFODKFPDAFQFvFRFSDADKDKDAFTFUEwEwFVDKDKDKDKDKDAaNaNaNDtDwFWFXFXFXFYDwDuaNaNaNaNaNaN -aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDwDwDwDwDwDwDwDwDwDwDwGaDKDKGbDwDwDwDwDwDwDwDwGcDwDADuaNDtDwFWFXFXFXFXFXFYDADuaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDAGdGeGfGgGhGiGjGbDAGaDKDKDKDKDKDKGbDwDwDwDwDwGaDKGbDwDwGkDwFWFXFXFXGlFXFXFXFYDAaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIGmDKDKGnDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKDKGqFXFXFXFXFXFXGrGsGtFXFXFXGuaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNGvGwDKDKDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKDKGqFXFXFXFXFXGxGyGrGrGxFXFXGzaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfGADKDKGBDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKFkDwDwGkDwGCFXFXGxGxGxFXFXGDDAaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDAGEGFGGGHGIGJGKFkDAEIDKDKDKDKDKDKFkDwDwEIDKFkDwDwDwDAEnaNEMDwGCFXFXFXFXFXGDDAEnaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwDwDwDwDwDwDwDwEIDKDKFkDwDwDwDwDwGLDwDwDwDADAaNaNaNEMDwGCFXFXFXGDDwEnaNaNaNaNaNaN -aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMaNaNaNaNaNaNaNaNaNDvDAGMGMDAaNDAFvGNFvFvFvGNFvDADAaNaNaNaNEMDwFIFJFKDwEnaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDvDtDwDxDyDyDyDzDwiEaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDADBDCDDDEDFDGDHDADvaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDJDKDKDKDKDKDLDADuaNaNaNaNaNaNDvaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNDODKDPcQDRDKDSDADwDMDwDMDwDMDwDwDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNDZDKDKDKDKDKEdDADTDKDUDKDVDWDXDYDADvaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfEgDKEaEbEcDKEiDADKDKDKDKDKDKDKEeDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNiQDAiRDKDKDKDKDKjfDAEjDKEkDKElDWDXDYEfaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAjGEhDKDKDKEhjHDADKDKDKDKDKDKDKEmDADvaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDuaNDADwDwDMEoDMDwDwDwDwDwDMEpDMDwDwDwEnaNDtDwEqErErEsDwDuaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwEtDKDKDKDKDKDKDKDKDKDKDKDKEuDAEnaNDvDwEvEwExEyEwEzDwjIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEBDKECDKDKDKDKDKDKDKDKDKDKDKDKDKDKDAaNaNaNEDEEEFEwEwEwEGEDaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWnnbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDADwDwDwDwDwDMEHDMDwDwDwDwDwEIDKDKDAaNaNaNEJEKEwEwEwEwELEJaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEnaNEMDAENEOEPDKDKEQERESETEuDADKDKDAiEaNDtDAEUEwEVEWEwEXDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWjLbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKDKDKDKDKDKDKEYDKDKDADwEZDwDwDwFaDwDwFaDwDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFbFcFdDKDKDKFeFeFeDKEHDKDKDAFfEwEwdfDADKDAFhFiFjDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYDKDKDKDKkhFkDwDwDwDwDADKDKDAEwEwFlFmDADKDAFnFoFpDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFqFrFsDKFtDAFuFvFwFxDADKDKDAFyEwEwFzDADKDAFAFBFCDNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEYlfDKDKDKFDDAFEFvFvFvFFDKDKDAFGEwEwFHDADKDKDKDKDKEfaNaNaNaNDtDwFIFJFKDwDuaNaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAFMFNFODKFPDAFQFvFRFSDADKDKDAFTFUEwEwFVDKDKDKDKDKDAaNaNaNDtDwFWFXFXFXFYDwDuaNaNaNaNaNaN +aNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDwDwDwDwDwDwDwDwDwDwDwDwGaDKDKGbDwDwDwDwDwDwDwDwGcDwDADuaNDtDwFWFXFXFXFXFXFYDADuaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWbWaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDAGaGdGeGfGgGhGiGjGbDAGaDKDKDKDKDKDKGbDwDwDwDwDwGaDKGbDwDwGkDwFWFXFXFXGlFXFXFXFYDAaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIGmlhDKDKlvDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKDKGqFXFXFXFXFXFXGrGsGtFXFXFXGuaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNDKlwDKDKDKDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKDKGqFXFXFXFXFXGxGyGrGrGxFXFXGzaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfGAGvDKDKlJDKDKDKDKDKGoDKDKGpGpGpGpDKDKDKDKDKDKDKDKDKFkDwDwGkDwGCFXFXGxGxGxFXFXGDDAaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDAEIGEGFGGGHGIGJGKFkDAEIDKDKDKDKDKDKFkDwDwEIDKFkDwDwDwDAEnaNEMDwGCFXFXFXFXFXGDDAEnaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDwDwDwDwDwDwDwDwDwDwEIDKDKFkDwDwDwDwDwGLDwDwDwDADAaNaNaNEMDwGCFXFXFXGDDwEnaNaNaNaNaNaN +aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDvDAGMGMDAaNDAFvGNFvFvFvGNFvDADAaNaNaNaNEMDwFIFJFKDwEnaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDtDwDwDwDwGaDKDKDAaNDAGOFvFvGPFvFvGQDADAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKDKDKDKDAaNDAGRGPFvFvFvGPGSDADAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfDKDKDKDKDKDKDKDAaNDAGTFvFvGPFvFvGUDADAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN @@ -1580,7 +1615,7 @@ aNaNaNaNaNaNHjdHdHdHdHdHHjIdIeIeIeIeIeIeIeIeIeIeIeIeIeIfHjdIdIdIdIdIHjaNaNaNaNaN aNaNaNaNHjHjHjIhIhIhIhIhjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaIhIhIhIhIhHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNjUjWlLlNlMkajZaNjUjWlOlQlPkajZaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfDKDKDKDKDKDKFkDAEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIkIkIkIkIlImjcjcjcjcjcjcjcjcjcjcjcjcjcInIlIoIoIoIoIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkwlRkxkxkxkAkzaNkwlSkxkxkxkAkzaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwDwDMIqDMDwDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIrIkIrIkIlImjcjcjcjcjcjcjcjcjcjcjcjcjcInIlIoIsIoIsIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkEkGlTkIlUkNkMaNkEkGlVkIlYkNkMaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDAItDKDKDKIuDAaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN -aNaNaNaNHjIiIjIkIkIvIkIkIlImjcjcjcjcjcIwIxIwjcjcjcjcjcInIlIoIoIyIoIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkQkRkxkxkxkAkSaNkQkRkxkxkxkAkSaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKDKDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN +aNaNaNaNHjIiIjIkIkIvIkIkIlImjcjcjcjcjcIwIxIwjcjcjcjcjcInIlIoIoIyIoIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkQkRkxkxkxkAkSaNkQkRkxkxkxkAkSaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDIDKDKDKDKlKDIaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIrIkIrIkIlImjcjcjcjcjcIwIzIwjcjcjcjcjcInIlIoIsIoIsIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNkUlikVlkljlmllaNkUlikVlkljlmllaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNDNIADKDKDKIBDNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjIiIjIkIkIkIkIkIlImjcjcjcjcjcjcjcjcjcjcjcjcjcInIlIoIoIoIoIoIjIpHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNlylnlAlzlFaNaNaNlylnlAlzlFaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEfICDKDKDKIDEfaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN aNaNaNaNHjHjHjIEIEIEIEIEjajbjcjcjcjcjcjcjcjcjcjcjcjcjcjbjaIEIEIEIEIEHjHjHjaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNFLFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFZFLaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNEMDwIFIGIHIIIJDwEnaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNaN diff --git a/_maps/map_files/cyberiad/z4.dmm b/_maps/map_files/cyberiad/z4.dmm index e0701e70cb1..b980f8a7098 100644 --- a/_maps/map_files/cyberiad/z4.dmm +++ b/_maps/map_files/cyberiad/z4.dmm @@ -140,7 +140,7 @@ "cJ" = (/obj/machinery/recharge_station,/turf/simulated/floor/plating/airless,/area/constructionsite/ai) "cK" = (/obj/structure/table,/obj/item/weapon/lighter/random,/obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich,/obj/item/clothing/head/chefhat,/obj/item/weapon/storage/box/donkpockets,/obj/structure/sign/fire{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/engiestation) "cL" = (/obj/structure/table,/obj/machinery/kitchen_machine/microwave{pixel_x = -3; pixel_y = 6},/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/engiestation) -"cM" = (/obj/structure/flora/kirbyplants,/obj/machinery/light{dir = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/engiestation) +"cM" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/light{dir = 1},/obj/machinery/status_display{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/engiestation) "cN" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/structure/sign/singulo{pixel_y = 32},/turf/simulated/floor/plasteel{dir = 1; icon_state = "blue"},/area/engiestation) "cO" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/meatballsoup,/turf/simulated/floor/plasteel{dir = 5; icon_state = "blue"},/area/engiestation) "cP" = (/obj/machinery/pipedispenser/disposal,/turf/simulated/floor/plasteel,/area/engiestation) @@ -186,7 +186,7 @@ "dD" = (/obj/machinery/vending/cola,/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 10},/area/engiestation) "dE" = (/obj/machinery/light,/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = -28},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/engiestation) "dF" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/engiestation) -"dG" = (/obj/machinery/light_switch{pixel_y = -28},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/engiestation) +"dG" = (/obj/machinery/light_switch{pixel_y = -28},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/engiestation) "dH" = (/turf/simulated/floor/plasteel{icon_state = "blue"; dir = 6},/area/engiestation) "dI" = (/obj/machinery/door/airlock/glass{name = "Kitchen"},/turf/simulated/floor/plasteel,/area/engiestation) "dJ" = (/obj/machinery/door/airlock/glass{name = "Cabin"},/turf/simulated/floor/plasteel{icon_state = "wood"},/area/engiestation) @@ -196,14 +196,14 @@ "dN" = (/obj/machinery/door/airlock{name = "Restroom"; req_access_txt = "0"},/turf/simulated/floor/plasteel,/area/engiestation) "dO" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engiestation) "dP" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel,/area/engiestation) -"dQ" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/engiestation) +"dQ" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "wood"},/area/engiestation) "dR" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/engiestation) "dS" = (/obj/structure/table,/obj/item/toy/minimeteor,/obj/item/toy/carpplushie,/turf/simulated/floor/plasteel{dir = 2; icon_state = "carpet"},/area/engiestation) "dT" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/engiestation) "dU" = (/obj/structure/toilet{dir = 4},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engiestation) "dV" = (/obj/machinery/light_switch{pixel_x = 0; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engiestation) "dW" = (/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engiestation) -"dX" = (/obj/structure/flora/kirbyplants,/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engiestation) +"dX" = (/obj/item/weapon/twohanded/required/kirbyplants,/obj/machinery/light{dir = 1; in_use = 1},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 5},/area/engiestation) "dY" = (/obj/structure/closet/firecloset,/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engiestation) "dZ" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/wall,/area/constructionsite/hallway/aft) "ea" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) diff --git a/_maps/map_files/cyberiad/z5.dmm b/_maps/map_files/cyberiad/z5.dmm index 8d593d21011..d84a5dfbf24 100644 --- a/_maps/map_files/cyberiad/z5.dmm +++ b/_maps/map_files/cyberiad/z5.dmm @@ -697,7 +697,7 @@ "nv" = (/obj/machinery/mineral/unloading_machine{input_dir = 1; output_dir = 2},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/research_outpost/tempstorage) "nw" = (/obj/structure/closet/firecloset,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "nx" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) -"ny" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) +"ny" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "nz" = (/obj/machinery/light_switch{pixel_x = 27},/obj/structure/stool/bed/chair/sofa/left{dir = 8},/turf/simulated/floor/plasteel,/area/research_outpost/gearstore) "nA" = (/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor/plating,/area/research_outpost/maint) "nB" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/plating,/area/research_outpost/maint) @@ -1385,7 +1385,7 @@ "AH" = (/obj/machinery/hologram/holopad,/obj/machinery/firealarm{pixel_y = 25},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters{name = "Mining Station Break Room"}) "AI" = (/obj/machinery/power/apc{dir = 1; name = "Mining Station Break Room APC"; pixel_x = 1; pixel_y = 25},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters{name = "Mining Station Break Room"}) "AJ" = (/obj/machinery/alarm{pixel_y = 25},/obj/structure/closet/crate/bin{name = "Garbage bin"},/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters{name = "Mining Station Break Room"}) -"AK" = (/obj/structure/flora/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters{name = "Mining Station Break Room"}) +"AK" = (/obj/item/weapon/twohanded/required/kirbyplants,/turf/simulated/floor/plasteel{icon_state = "bar"},/area/mine/living_quarters{name = "Mining Station Break Room"}) "AL" = (/obj/machinery/door/firedoor,/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/mine/living_quarters{name = "Mining Station Break Room"}) "AM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plasteel,/area/mine/lobby) "AN" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plasteel,/area/mine/lobby) diff --git a/_maps/map_files/cyberiad/z6.dmm b/_maps/map_files/cyberiad/z6.dmm index 104c590cccc..84dd4bfbd99 100644 --- a/_maps/map_files/cyberiad/z6.dmm +++ b/_maps/map_files/cyberiad/z6.dmm @@ -127,7 +127,7 @@ "cw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = ""},/turf/simulated/wall,/area/derelict/bridge/access) "cx" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) "cy" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/turf/simulated/floor/plating/airless,/area/solar/derelict_starboard) -"cz" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/space) +"cz" = (/turf/space,/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_f6"; tag = "icon-swall_f6"},/area/space) "cA" = (/turf/simulated/floor/plating,/area/derelict/bridge/access) "cB" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plasteel,/area/derelict/bridge/access) "cC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/derelict/bridge/access) @@ -648,7 +648,7 @@ "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/weapon/storage/box/donkpockets,/obj/item/ammo_box/magazine/m762,/obj/item/weapon/gun/projectile/automatic/m90,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) +"mA" = (/obj/structure/closet/crate{name = "munitions crate"},/obj/item/weapon/storage/box/donkpockets,/obj/item/ammo_box/magazine/mm556x45,/obj/item/weapon/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/weapon/storage/fancy/cigarettes/cigpack_syndicate,/obj/item/weapon/storage/firstaid/tactical,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/syndicate_depot) @@ -657,10 +657,10 @@ "mG" = (/turf/simulated/mineral,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_depot) "mH" = (/turf/simulated/mineral,/area/space) "mI" = (/turf/simulated/floor/plating/airless/asteroid,/area/space) -"mJ" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s6"; icon_state = "swall_s6"; dir = 2},/area/space) +"mJ" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f10"; icon_state = "swall_f10"; dir = 2},/area/space) "mK" = (/turf/simulated/shuttle/wall{tag = "icon-swall12"; icon_state = "swall12"; dir = 2},/area/space) "mL" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/floor/plasteel/airless,/area/space) -"mM" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s10"; icon_state = "swall_s10"; dir = 2},/area/space) +"mM" = (/turf/space,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/space) "mN" = (/turf/simulated/floor/plating/airless/asteroid,/turf/simulated/shuttle/wall{tag = "icon-swall_f9"; icon_state = "swall_f9"; dir = 2},/area/space) "mO" = (/obj/effect/landmark/corpse/clown,/turf/simulated/floor/plasteel/airless,/area/space) "mP" = (/obj/structure/closet/crate,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/turf/simulated/floor/plasteel/airless,/area/space) @@ -682,10 +682,7 @@ "nf" = (/obj/item/weapon/pickaxe,/turf/simulated/floor/plasteel/airless,/area/space) "ng" = (/obj/structure/closet/crate,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/obj/item/weapon/ore/bananium,/turf/simulated/floor/plasteel/airless,/area/space) "nh" = (/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (WEST)"; icon_state = "propulsion_l"; dir = 8},/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (WEST)"; icon_state = "propulsion_l"; dir = 8},/turf/space,/area/space) -"ni" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s5"; icon_state = "swall_s5"; dir = 2},/area/space) -"nj" = (/turf/simulated/shuttle/wall{tag = "icon-swall_s9"; icon_state = "swall_s9"; dir = 2},/area/space) "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" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/space) "nm" = (/obj/item/weapon/shard,/turf/simulated/floor/plasteel/airless,/area/space) "nn" = (/obj/item/weapon/broken_bottle,/turf/simulated/floor/plasteel/airless,/area/space) "no" = (/turf/simulated/shuttle/wall{tag = "icon-swall11"; icon_state = "swall11"; dir = 2},/area/space) @@ -905,20 +902,20 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacvcvcvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznknknknlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznknknkmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamLnnnmncmLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamJnonpaznpnqmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamInrnomTnsnsnqnjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacznonpaznpnqmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaaaaaaaamInrnomTnsnsnqmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHaaaamHmHmHmHmHntnvnumHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmImImHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmImIaaaamJmKmKmLmLmKmKmKmKmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmImJmKmNmImOazazmPmPmQazmRmSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmImIaaaaczmKmKmLmLmKmKmKmKmJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmIczmKmNmImOazazmPmPmQazmRmSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmTazazazazazmUazmRmVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmWmXmYazmZmUazmUazmUmRmVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHnaaznbazncazmOazazazmUmRmVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHndmKneaznfazazngmPmPazmRnhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHnimKmKmLmLmKmKmKmKnjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHndmKmKmLmLmKmKmKmKmMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHaamHmHmHmHmHmImImHmHmHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamHmHmHmHmImImImHmHmHmHmHmHmHmHmHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index bf620aad6e3..ca293307099 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -53,3 +53,11 @@ #define AI_ON 1 #define AI_IDLE 2 #define AI_OFF 3 + +//Gun Stuff + #define SAWN_INTACT 0 + #define SAWN_OFF 1 + + #define WEAPON_LIGHT 0 + #define WEAPON_MEDIUM 1 + #define WEAPON_HEAVY 2 diff --git a/code/__DEFINES/error_handler.dm b/code/__DEFINES/error_handler.dm new file mode 100644 index 00000000000..0c98f4a9b9f --- /dev/null +++ b/code/__DEFINES/error_handler.dm @@ -0,0 +1,9 @@ +// Settings for the error handler and error viewer + +#define ERROR_COOLDOWN 600 // The "cooldown" time for each occurrence of a unique error +#define ERROR_LIMIT 9 // How many occurrences before the next will silence them +#define ERROR_MAX_COOLDOWN (ERROR_COOLDOWN * ERROR_LIMIT) +#define ERROR_SILENCE_TIME 6000 // How long a unique error will be silenced for + +// How long to wait between messaging admins about occurrences of a unique error +#define ERROR_MSG_DELAY 50 diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index f57e096e0ec..915cb8816e8 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -62,11 +62,12 @@ #define HAS_TAIL 16 #define TAIL_OVERLAPPED 32 #define HAS_SKIN_TONE 64 -#define HAS_SKIN_COLOR 128 -#define HAS_MARKINGS 256 -#define TAIL_WAGGING 512 -#define NO_EYES 1024 -#define HAS_FUR 2048 +#define HAS_ICON_SKIN_TONE 128 +#define HAS_SKIN_COLOR 256 +#define HAS_MARKINGS 512 +#define TAIL_WAGGING 1024 +#define NO_EYES 2048 +#define HAS_FUR 4096 //Species Diet Flags #define DIET_CARN 1 diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 14161a5775f..1937ac3be85 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -1 +1,3 @@ -#define ismovableatom(A) istype(A, /atom/movable) \ No newline at end of file +#define isatom(A) istype(A, /atom) +#define ismovableatom(A) istype(A, /atom/movable) +#define isclient(A) istype(A, /client) \ No newline at end of file diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index c6f2b947f4f..40e3edfcfb0 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -259,3 +259,7 @@ 0.3, 0.3, 0.3, 0,\ 0.3, 0.3, 0.3, 0,\ 0, 0, 0, 1) +//Gun trigger guards +#define TRIGGER_GUARD_ALLOW_ALL -1 +#define TRIGGER_GUARD_NONE 0 +#define TRIGGER_GUARD_NORMAL 1 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 96ae9ea6281..12722c0a2bb 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -27,6 +27,7 @@ #define ROLE_HOG_GOD "hand of god: god" // We're prolly gonna port this one day or another #define ROLE_HOG_CULTIST "hand of god: cultist" #define ROLE_RAIDER "vox raider" +#define ROLE_TRADER "trader" #define ROLE_VAMPIRE "vampire" #define ROLE_MUTINEER "mutineer" // Role tags for EVERYONE! @@ -71,4 +72,5 @@ var/global/list/special_roles = list( ROLE_REVENANT, ROLE_GUARDIAN, ROLE_MORPH, + ROLE_TRADER, ) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 36bb824e642..a8c548bdd7a 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -46,6 +46,14 @@ if(S.flags & IS_WHITELISTED) whitelisted_species += S.name + paths = subtypesof(/datum/emote) + for(var/T in paths) + var/datum/emote/E = new T + if(istype(T, /datum/emote/custom)) + continue + emotes += E + + init_subtypes(/datum/table_recipe, table_recipes) return 1 diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 4c2517d9617..6376ebb4215 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -167,7 +167,7 @@ mob Output_Icon() set name = "2. Output Icon" - to_chat(src, "Icon is: \icon[getFlatIcon(src)]") + to_chat(src, "Icon is: [bicon(getFlatIcon(src))]") Label_Icon() set name = "3. Label Icon" diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm index 09830792201..5d2427603c7 100644 --- a/code/__HELPERS/logging.dm +++ b/code/__HELPERS/logging.dm @@ -91,4 +91,23 @@ */ /proc/log_startup_progress(var/message) to_chat(world, "[message]") - log_to_dd(message) \ No newline at end of file + log_to_dd(message) + +// Helper procs for building detailed log lines + +/proc/datum_info_line(var/datum/d) + if(!istype(d)) + return + if(!istype(d, /mob)) + return "[d] ([d.type])" + var/mob/m = d + return "[m] ([m.ckey]) ([m.type])" + +/proc/atom_loc_line(var/atom/a) + if(!istype(a)) + return + var/turf/t = get_turf(a) + if(istype(t)) + return "[a.loc] ([t.x],[t.y],[t.z]) ([a.loc.type])" + else if(a.loc) + return "[a.loc] (0,0,0) ([a.loc.type])" diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 3d1648fa77a..9657f867b5a 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -100,27 +100,42 @@ proc/random_name(gender, species = "Human") else return current_species.get_random_name(gender) -proc/random_skin_tone() - switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) - if("caucasian") . = -10 - if("afroamerican") . = -115 - if("african") . = -165 - if("latino") . = -55 - if("albino") . = 34 - else . = rand(-185,34) - return min(max( .+rand(-25, 25), -185),34) +proc/random_skin_tone(species = "Human") + if(species == "Human" || species == "Drask") + switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) + if("caucasian") . = -10 + if("afroamerican") . = -115 + if("african") . = -165 + if("latino") . = -55 + if("albino") . = 34 + else . = rand(-185, 34) + return min(max(. + rand(-25, 25), -185), 34) + else if(species == "Vox") + . = rand(1, 6) + return . -proc/skintone2racedescription(tone) - switch (tone) - if(30 to INFINITY) return "albino" - if(20 to 30) return "pale" - if(5 to 15) return "light skinned" - if(-10 to 5) return "white" - if(-25 to -10) return "tan" - if(-45 to -25) return "darker skinned" - if(-65 to -45) return "brown" - if(-INFINITY to -65) return "black" - else return "unknown" +proc/skintone2racedescription(tone, species = "Human") + if(species == "Human") + switch (tone) + if(30 to INFINITY) return "albino" + if(20 to 30) return "pale" + if(5 to 15) return "light skinned" + if(-10 to 5) return "white" + if(-25 to -10) return "tan" + if(-45 to -25) return "darker skinned" + if(-65 to -45) return "brown" + if(-INFINITY to -65) return "black" + else return "unknown" + else if(species == "Vox") + switch(tone) + if(2) return "dark green" + if(3) return "brown" + if(4) return "gray" + if(5) return "emerald" + if(6) return "azure" + else return "green" + else + return "unknown" proc/age2agedescription(age) switch(age) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index be0b6bbf245..0ac3da3a10a 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -239,7 +239,7 @@ var/syndicate_code_response//Code response for traitors. set name = "Generate Code Phrase" set category = "Debug" - to_chat(world, "\red Code Phrase is: \black [generate_code_phrase()]") + to_chat(world, "Code Phrase is: [generate_code_phrase()]") return diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 59784a357e0..0aa9589c510 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -371,4 +371,22 @@ proc/checkhtml(var/t) //If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites - //this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitizeSafe()! /proc/sanitizeSafe(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1) - return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra) \ No newline at end of file + return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra) + + +//Replaces \red \blue \green \b etc with span classes for to_chat +/proc/replace_text_macro(match, code, rest) + var/regex/text_macro = new("(\\xFF.)(.*)$") + switch(code) + if("\red") + return "[text_macro.Replace(rest, /proc/replace_text_macro)]" + if("\blue", "\green") + return "[text_macro.Replace(rest, /proc/replace_text_macro)]" + if("\b") + return "[text_macro.Replace(rest, /proc/replace_text_macro)]" + else + return text_macro.Replace(rest, /proc/replace_text_macro) + +/proc/macro2html(text) + var/static/regex/text_macro = new("(\\xFF.)(.*)$") + return text_macro.Replace(text, /proc/replace_text_macro) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ff4ee54b2e9..5ef6646e8cc 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -248,7 +248,7 @@ Turf and target are seperate in case you want to teleport some distance from a t var/pressure = air_contents.return_pressure() var/total_moles = air_contents.total_moles() - to_chat(user, "Results of analysis of \icon[icon] [target].") + to_chat(user, "Results of analysis of [bicon(icon)] [target].") if(total_moles>0) var/o2_concentration = air_contents.oxygen/total_moles var/n2_concentration = air_contents.nitrogen/total_moles @@ -1733,10 +1733,6 @@ var/global/list/g_fancy_list_of_types = null matches[key] = value return matches -// Use this to send to a client's chat, no exceptions (except this proc itself). -/proc/to_chat(var/thing, var/output) - thing << output - //Key thing that stops lag. Cornerstone of performance in ss13, Just sitting here, in unsorted.dm. /proc/stoplag() . = 1 diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index b6dc1c58b8f..e1e8b818356 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -4,6 +4,7 @@ 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] var/global/list/all_nations[0] +var/global/list/emotes[0] var/global/list/whitelisted_species = list() var/list/clients = list() //list of all clients diff --git a/code/_onclick/_defines.dm b/code/_onclick/_defines.dm index 3c76c35e807..a02a1f43590 100644 --- a/code/_onclick/_defines.dm +++ b/code/_onclick/_defines.dm @@ -1 +1,3 @@ -#define CLICKCATCHER_PLANE -99 \ No newline at end of file +#define CLICKCATCHER_PLANE -99 + +#define HUD_PLANE 90 \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index b44ba964628..db5a0bbcd0f 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -45,7 +45,7 @@ if(modifiers["middle"]) MiddleClickOn(A) if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden. - controlled_mech.click_action(A, src) //Override AI normal click behavior. + controlled_mech.click_action(A, src, params) //Override AI normal click behavior. return if(modifiers["shift"]) ShiftClickOn(A) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index d135e62ae69..fa1d696a067 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -74,7 +74,7 @@ if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled return var/obj/mecha/M = loc - return M.click_action(A,src) + return M.click_action(A, src, params) if(restrained()) changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow @@ -167,9 +167,8 @@ animals lunging, etc. */ /mob/proc/RangedAttack(var/atom/A, var/params) - if(ishuman(src) && (istype(src:gloves, /obj/item/clothing/gloves/color/yellow/power)) && a_intent == I_HARM) - PowerGlove(A) - if(!mutations.len) return + if(!mutations.len) + return if((LASER in mutations) && a_intent == I_HARM) LaserEyes(A) // moved into a proc below return @@ -319,61 +318,8 @@ LE.current = T LE.yo = U.y - T.y LE.xo = U.x - T.x - spawn(1) - LE.process() + LE.fire() -/mob/proc/PowerGlove(atom/A) - return - -/mob/living/carbon/human/PowerGlove(atom/A) - var/obj/item/clothing/gloves/color/yellow/power/G = src:gloves - var/time = 100 - var/turf/T = get_turf(src) - var/turf/U = get_turf(A) - var/obj/structure/cable/cable = locate() in T - if(!cable || !istype(cable)) - to_chat(src, "There is no cable here to power the gloves.") - return - if(world.time < G.next_shock) - to_chat(src, "[G] aren't ready to shock again!") - return - src.visible_message("[name] fires an arc of electricity!", \ - "You fire an arc of electricity!", \ - "You hear the loud crackle of electricity!") - var/datum/powernet/PN = cable.get_powernet() - var/available = 0 - var/obj/item/projectile/beam/lightning/L = new /obj/item/projectile/beam/lightning/(get_turf(src)) - if(PN) - available = PN.avail - L.damage = PN.get_electrocute_damage() - if(available >= 5000000) - L.damage = 205 - if(L.damage >= 200) - time = 200 - else if(L.damage >= 100) - time = 150 - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - if(L.damage <= 0) - qdel(L) - if(L) - playsound(get_turf(src), 'sound/effects/eleczap.ogg', 75, 1) - L.tang = L.adjustAngle(get_angle(U,T)) - L.icon = midicon - L.icon_state = "[L.tang]" - L.firer = usr - L.def_zone = get_organ_target() - L.original = src - L.current = U - L.starting = U - L.yo = U.y - T.y - L.xo = U.x - T.x - spawn( 1 ) - L.process() - - next_move = world.time + 12 - G.next_shock = world.time + time // Simple helper to face what you clicked on, in case it should be needed in more than one place /mob/proc/face_atom(var/atom/A) @@ -419,4 +365,4 @@ else var/turf/T = screen_loc2turf(modifiers["screen-loc"], get_turf(usr)) T.Click(location, control, params) - return 1 \ No newline at end of file + return 1 diff --git a/code/_onclick/click_override.dm b/code/_onclick/click_override.dm index 092398ee174..d37b7368b8f 100644 --- a/code/_onclick/click_override.dm +++ b/code/_onclick/click_override.dm @@ -40,4 +40,29 @@ newObject.loc = get_turf(A) to_chat(user, "You release the power you had stored up, summoning \a [newObject.name]! ") usr.loc.visible_message("[user] waves \his hand and summons \a [newObject.name]") - ..() \ No newline at end of file + ..() + +/datum/middleClickOverride/power_gloves + var/last_shocked = 0 + var/shock_delay = 120 + +/datum/middleClickOverride/power_gloves/onClick(var/atom/A, var/mob/living/user) + if(user.incapacitated()) + return + if(world.time < last_shocked + shock_delay) + to_chat(user, "The gloves are still recharging.") + return + if(!isliving(A)) + to_chat(user, "Shocking an inanimate object would be pointless.") + return + var/mob/living/L = A + var/turf/T = get_turf(user) + var/obj/structure/cable/C = locate() in T + if(!C || !istype(C)) + to_chat(user, "There is no cable here to power the gloves.") + return + user.visible_message("[user.name] fires an arc of electricity at [L]!", "You fire an arc of electricity at [L]!", "You hear the loud crackle of electricity!") + var/datum/powernet/PN = C.get_powernet() + user.Beam(L,icon_state="lightning[rand(1,12)]",icon='icons/effects/effects.dmi',time=5) + electrocute_mob(L, PN, user) + last_shocked = world.time diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 02c5bfc2ac3..e49e99ad6b7 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -186,4 +186,3 @@ to_chat(usr, "Switched HUD mode. Press F12 to toggle.") else to_chat(usr, "This mob type does not use a HUD.") - diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 7aa9839d663..861209033af 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -209,6 +209,7 @@ else A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" A.layer = 20 + A.plane = HUD_PLANE x++ if(x == 4) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 1f0e6205200..58fb139ce33 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -10,9 +10,11 @@ name = "" icon = 'icons/mob/screen_gen.dmi' layer = 20 + plane = HUD_PLANE unacidable = 1 var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. var/datum/hud/hud = null + appearance_flags = NO_CLIENT_COLOR /obj/screen/Destroy() master = null diff --git a/code/_onclick/oldcode.dm b/code/_onclick/oldcode.dm index b3f2c1dde05..89b1131a6f0 100644 --- a/code/_onclick/oldcode.dm +++ b/code/_onclick/oldcode.dm @@ -369,8 +369,7 @@ A.current = T A.yo = U.y - T.y A.xo = U.x - T.x - spawn( 1 ) - A.process() + A.fire() usr.next_move = world.time + 6 return diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index ee953edac3f..50b6716c977 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -69,6 +69,7 @@ var/const/tk_maxrange = 15 //item_state = null w_class = 10.0 layer = 20 + plane = HUD_PLANE var/last_throw = 0 var/atom/movable/focus = null diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm index 27ba2479ae5..620dafca4ec 100644 --- a/code/controllers/ProcessScheduler/core/process.dm +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -326,6 +326,11 @@ stat("[name]", "T#[getTicks()] | AR [averageRunTime] | LR [lastRunTime] | HR [highestRunTime] | D [cpu_defer_count]") /datum/controller/process/proc/catchException(var/exception/e, var/thrower) + if(istype(e)) // Real runtimes go to the real error handler + // There are two newlines here, because handling desc sucks + e.desc = " Caught by process: [name]\n\n" + e.desc + world.Error(e, e_src = thrower) + return var/etext = "[e]" var/eid = "[e]" // Exception ID, for tracking repeated exceptions var/ptext = "" // "processing..." text, for what was being processed (if known) diff --git a/code/datums/Emote_system/emote.dm b/code/datums/Emote_system/emote.dm new file mode 100644 index 00000000000..4f130fbf330 --- /dev/null +++ b/code/datums/Emote_system/emote.dm @@ -0,0 +1,587 @@ +/******************************************************************************************************* + Emotes +Remember, only 1 instance of each emote is made, and used by all mobs that can access it. As such, the +ONLY place you can safely set object variables during runtime is in New(). Otherwise override the emote. +The only exception to this is custom emotes, which are created as needed and only last until they are finished +VampyrBytes + +*******************************************************************************************************/ +#define EMOTE_COOLDOWN 20 //Time in deciseconds that the cooldown lasts +#define HEARING_RANGE 7 +#define INVALID -1 //Using -1 as I can't see how a negative number could be a valid input + +/datum/emote + var/name = "" + var/desc = "" + var/list/commands[0] // list of commands that trigger the emote. + var/text = "" + var/selfText = "" // the version of text that you should see - eg, if text is screams, you want scream here, as You screams is bad grammer + var/startText = "" // if you need to put something in before [user] + var/selfStart = 1 // whether the start text is used in what you see + + var/audible = 0 + var/mimeText = "" + var/mimeSelf = "" //self version of mimeText + var/sound // sound file + var/vol = 50 + var/muzzleAffected = 0 // whether being muzzled affects this emote + var/muzzledNoise = "" // if the emote is audible and you're muzzled, this is what type of noise you make (eg weak, loud). + var/cooldown = 0 // How long the cooldown should be on this emote. Defaults to EMOTE_COOLDOWN if not set and the emote plays a sound + + var/restrained = 0 // 1 if being restrained prevents this emote + + var/canTarget = 0 // 1 if the emote accepts a target + var/targetMob = 0 // 0 if target can be any atom, 1 if it has to be a mob, + var/mustTarget = 0 // 1 if the emote needs a target to work (won't get None as an option) + var/targetText = "at" // what goes inbetween user and target + var/takesNumber = 0 // 1 if the emote uses a number parameter + + var/emoteSpanClass = "notice" + var/userSpanClass = "em" + var/baseLevel = 1 + var/allowParent = 0 // 1 if you want the parent available as well as this one + + +/datum/emote/New() + var/pathString = "[type]" + var/count = 0 + for(var/i in 1 to lentext(pathString)) + var/char = copytext(pathString, i, i+1) + if(char == "/") + count++ + if(count == 4) + baseLevel = 0 + break + + if(sound && !cooldown) + cooldown = EMOTE_COOLDOWN + + if(targetText) + if(!findtextEx(targetText, " ", lentext(targetText))) + targetText += " " + +/datum/emote/proc/doEmote(var/mob/user, var/command = "") + if(!istype(user)) + return + if(cooldown) + if(handle_emote_CD(user)) + return + + var/message = "" + var/list/params[0] + + params = getParams(user) + + for(var/p in params) + if(params[p] == INVALID) + return + + if(text) + message = createMessage(user, params) + + if(message) + message = addExtras(user, params, message) + . = processMessage(user, params, message) + + if(!doMime(user) && (!muzzleAffected || !isMuzzled(user))) + if(playSound(user, params)) + . = 2 + + doAction(user, params) + + for(var/obj/item/weapon/implant/I in user) + if(I.implanted) + I.trigger(command, user) + + return + +// for things that the emote does that aren't text or sound based +/datum/emote/proc/doAction(var/mob/user, var/list/params) + return + +/datum/emote/proc/getParams(var/mob/user) + var/list/params[0] + + if(takesNumber) + user.set_typing_indicator(1) + user.hud_typing = 1 + params["num"] = getNumber(user) + user.hud_typing = 0 + user.set_typing_indicator(0) + + if(canTarget) + user.set_typing_indicator(1) + user.hud_typing = 1 + params["target"] = getTarget(user) + user.hud_typing = 0 + user.set_typing_indicator(0) + return params + +// return INVALID from either of these getters if you've tested the input and it's failed +/datum/emote/proc/getNumber(var/mob/user) + var/number = input("How many?", "Enter number") as null|num + return number + +/datum/emote/proc/getTarget(var/mob/user) + if(user.sdisabilities & BLIND || user.blinded || user.paralysis) + return + var/list/targets = list() + if(!mustTarget) + targets += "None" + var/target + if(targetMob) + target = getMobTarget(user, targets) + else + target = getAtomTarget(user, targets) + if(!target) + return INVALID + if(target == "None") + return + return target + +/datum/emote/proc/getMobTarget(var/mob/user, var/list/targets) + for(var/mob/M in view(getLoc(user))) + targets += M + var/mob/target = input("Select target", "Target Mob") as null|anything in targets + return target + + +/datum/emote/proc/getAtomTarget(var/mob/user, var/list/targets) + for(var/A in oview(getLoc(user))) + if(ismob(A) || isobj(A) || isturf(A)) + targets += A + var/atom/target = input("Select target", "Target") as null|anything in targets + return target + +// returns the reason the user can't currently do the emote +/datum/emote/proc/prevented(var/mob/user) + if(user.stat == DEAD) + return "you are dead" + if(user.stat == UNCONSCIOUS) + return "you are unconscious" + if(restrained && user.restrained()) + return "you are restrained" + if(isbrain(user)) + var/mob/living/carbon/brain/brain = user + if(!(brain.container && istype(brain.container, /obj/item/device/mmi))) + return "you need to be in an mmi to do this" + +// return 1 if this emote can be used by this type of user +/datum/emote/proc/available(var/mob/user) + return + +/datum/emote/proc/createMessage(var/mob/user, var/list/params) + if(!text) + return + var/message = "" + + if(doMime(user)) + message = mimeMessage(user, params) + if(message) + return message + + if(muzzleAffected && isMuzzled(user)) + message = muzzleMessage(user, params) + return message + + if(checkForParams(params)) + message = paramMessage(user, params) + return message + + message = standardMessage(user, params) + + return message + +/datum/emote/proc/isMuzzled(var/mob/user) + if(user.sdisabilities & MUTE || user.is_muzzled()) + return 1 + if(!isliving(user)) + return + var/mob/living/L = user + if(L.silent) + return 1 + +/datum/emote/proc/checkForParams(var/list/params) + for(var/p in params) + if(p == "target") + continue + return 1 + +/datum/emote/proc/addExtras(var/mob/user, var/list/params, var/message = "") + if(!message) + return + if(startText) + message = "[startText] [message]" + message = addPunc(message) + message = "[message]" + return message + +/datum/emote/proc/addPunc(var/message = "") + var/regex/endingPunc = new("\[\\.!\\?\"]$") + if(!endingPunc.Find(message)) + message += "." + return message + +/datum/emote/proc/standardMessage(var/mob/user, var/list/params) + var/message = "\The [user] [text]" + if("target" in params) + message = addTarget(user, params, message) + return message + +/datum/emote/proc/mimeMessage(var/mob/user, var/list/params) + if(!mimeText) + return + if(checkForParams(params)) + return paramMimeMessage(user, params) + var/message = "\The [user] [mimeText]" + if(message && "target" in params) + message = addTarget(user, params, message) + return message + +/datum/emote/proc/muzzleMessage(var/mob/user, var/list/params) + var/message = "\The [user] makes a " + if(muzzledNoise) + message += "[muzzledNoise] " + message += "noise" + return message + +// if the emote takes a non target parameter, set up and return the with parameter version in here +/datum/emote/proc/paramMessage(var/mob/user, var/list/params) + return + +// as above, but for mimes when there is mimeText +/datum/emote/proc/paramMimeMessage(var/mob/user, var/list/params) + return + +/datum/emote/proc/addTarget(var/mob/user, var/list/params, var/message = "") + if(!canTarget) + return message + if(!params["target"]) + return message + if(params["target"] == user) + message += " [targetText][getHimself(user)]" + return message + message += " [targetText]\the [params["target"]]" + return message + + +// What you should see when you perform the emote +/datum/emote/proc/createSelfMessage(var/mob/user, var/list/params, var/message = "") + if(!selfText) + return message + + message = replacetext(message, text, selfText) + message = changeTextMacros(user, message) + + if(mimeSelf) + message = replacetext(message, mimeText, mimeSelf) + + if(startText && !selfStart) + var/start = findtextEx(message, startText) + var/end = start + lentext(startText) + 1 + message = copytext(message, 1, start) + copytext(message, end, lentext(message) + 1) + + message = replaceMobWithYou(user, message, user) + + return message + +/datum/emote/proc/replaceMobWithYou(var/mob/M, var/message = "", var/mob/user) // user passed in in case an override needs to do something different if M != user (see johnny) VB + + message = replacetext(message, "\The [M]", "You") + message = replacetext(message, "\the [M]", "you") + + return message + +/datum/emote/proc/processMessage(var/mob/user, var/list/params, var/message = "") + var/visualOrAudible = audible + 1 + if(doMime(user)) + visualOrAudible = 1 + + log_emote("[user.name]/[user.key] : [message]") + sendToDead(user, message) + for(var/mob/M in getRecipients(getLoc(user, message), visualOrAudible)) + var/msg = "" + + if(M==user) + msg = createSelfMessage(user, params, message) + if(msg) + outputMessage(M, msg, user) + continue + + if(M.stat == UNCONSCIOUS || (M.sleeping && M.stat != DEAD)) + if(!visualOrAudible == 2) + continue + msg = "... You can almost hear someone talking ..." + outputMessage(M, msg, user) + continue + + if(M.sdisabilities & DEAF || M.ear_deaf) + if(M.sdisabilities & BLIND || M.blinded || M.paralysis) + continue + if(!(M in getRecipients(user, 1)) || M.see_invisible < user.invisibility) + continue + + msg = createDeafMessage(user, params, message) + if(!msg && visualOrAudible == 2) + continue + if(msg) + outputMessage(M, msg, user) + continue + + if(M.sdisabilities & BLIND || M.blinded || M.paralysis || (M.see_invisible < user.invisibility && visualOrAudible == 2)) + if(!(M in getRecipients(user, 2))) + continue + + msg = createBlindMessage(user, params, message) + if(!msg && visualOrAudible == 1) + continue + if(msg) + outputMessage(M, msg, user) + continue + + if(M.see_invisible < user.invisibility && visualOrAudible == 1) + continue + + msg = message + outputMessage(M, msg, user) + + if(visualOrAudible == 2) + handleListeningObjects(user, message) + + return visualOrAudible + +/datum/emote/proc/outputMessage(var/mob/M, var/msg = "", var/mob/user) + msg = replaceMobWithYou(M, msg, user) + to_chat(M, msg) + +/datum/emote/proc/getLoc(var/mob/user, var/message = "") + var/loc = checkForHolopad(user, message) + if(loc) + return loc + return user + +/datum/emote/proc/checkForHolopad(var/mob/user, var/message = "") + if(!isAI(user)) + return + var/mob/living/silicon/ai/AI = user + var/obj/machinery/hologram/holopad/T = AI.holo + if(!(T && T.hologram && T.master == AI)) + return + if(message) + to_chat(AI, "Holopad action relayed, [message]") + return T + +/datum/emote/proc/handleListeningObjects(var/mob/user, var/message = "") + // based on say code + var/omsg = replacetext(message, "[user] ", "") + var/list/listening_obj = new + for(var/atom/movable/A in view(HEARING_RANGE, user)) + if(istype(A, /mob)) + var/mob/M = A + for(var/obj/O in M.contents) + listening_obj |= O + else if(istype(A, /obj)) + var/obj/O = A + listening_obj |= O + for(var/obj/O in listening_obj) + O.hear_message(user, omsg) + +/datum/emote/proc/getRecipients(var/location, var/visualOrAudible) + if(visualOrAudible == 1) + return viewers(location) + return get_mobs_in_view(HEARING_RANGE, location) + +// set up different messages for blind people here. Empty will mean no message for +//non-audible emotes and the standard message for audible ones +/datum/emote/proc/createBlindMessage(var/mob/user, var/list/params, var/message) + if(audible && selfText) + message = "You hear someone [selfText]" + message = addExtras(message) + return message + +// set up different messages for deaf people here. Empty will mean no message for +// audible emotes and standard for non-audible ones +/datum/emote/proc/createDeafMessage(var/mob/user, var/list/params, var/message) + message = mimeMessage(user, params) + message = addExtras(message) + return message + +/datum/emote/proc/sendToDead(var/mob/user, var/message = "", var/ghostEmote) + for(var/mob/M in dead_mob_list) + if(!M.client || istype(M, /mob/new_player)) + continue //skip monkeys, leavers and new players + if(M.stat == DEAD) + if(ghostEmote && ((M.client.prefs.toggles & CHAT_GHOSTSIGHT) || (M in viewers(user)))) + M.show_message(message) + else if((M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(user))) + M.show_message(message) + +/datum/emote/proc/playSound(var/mob/user, var/list/params) + if(!sound) + return + playsound(user, sound, vol) + return 1 + +/datum/emote/proc/doMime(var/mob/user) + if(mimeText && user.mind && user.mind.miming) + return 1 + +//Emote Cooldown System (it's so simple!) +/datum/emote/proc/handle_emote_CD(var/mob/user) + if(user.emote_cd == 2) return 1 // Cooldown emotes were disabled by an admin, prevent use + if(user.emote_cd == 1) return 1 // Already on CD, prevent use + + user.emote_cd = 1 // Starting cooldown + + spawn(cooldown) + if(user.emote_cd == 2) return 1 // Don't reset if cooldown emotes were disabled by an admin during the cooldown + user.emote_cd = 0 // Cooldown complete, ready for more! + + return 0 // Proceed with emote +//--FalseIncarnate + +/datum/emote/proc/changeTextMacros(var/mob/user, var/message = "") + message = swapHisToYour(user, message) + message = swapHimselfToYourself(user, message) + return message + +/datum/emote/proc/getHis(var/mob/user) + var/his = "[user]\his" + his = copytext(his, lentext("[user]") + 1) + return his + +/datum/emote/proc/swapHisToYour(var/mob/user, var/message = "") + var/his = getHis(user) + message = replacetext(message, " [his] ", " your ") + return message + +/datum/emote/proc/getHimself(var/mob/user) + var/himself = "[user]\himself" + himself = copytext(himself, lentext("[user]") + 1) + return himself + +/datum/emote/proc/swapHimselfToYourself(var/mob/user, var/message) + var/himself = getHimself(user) + message = replacetext(message, "[himself]", "yourself") + return message + +/****************************************************************************************** + Emote Verbs +******************************************************************************************/ + +/datum/emote/proc/addVerbs(var/mob/user) + if(!istype(user)) + return + new /obj/emoteVerb(user, src, commands) + +// Dummy object to allow access to the verb, needed as verbs require a valid loc for setting the src +/obj/emoteVerb + var/datum/emote/emote + var/mob/owner + +/obj/emoteVerb/New(var/mob/user, var/datum/emote/toAccess) + if(!(istype(user))) + return + if(!(istype(toAccess))) + return + if(!toAccess.commands) + return + owner = user + emote = toAccess + name = "[emote]" + loc = user + user.verbs += new/obj/emoteVerb/proc/runEmote(src, emote.commands[1], emote.desc) + +/obj/emoteVerb/proc/runEmote() + set src = usr.contents + set category = "Emotes" + return usr.emoteHandler.runEmote(emote.commands[1]) + +/obj/emoteVerb/Destroy() + owner.verbs -= new/obj/emoteVerb/proc/runEmote(src, emote.commands[1]) + ..() + +/obj/emoteVerb/custom + +obj/emoteVerb/custom/New(var/mob/user) + if(!(istype(user))) + return + owner = user + name = "custom" + user.verbs += new/obj/emoteVerb/proc/runEmote(src, "custom", "Make your own emote") + +/obj/emoteVerb/custom/runEmote() + set src = usr.contents + set category = "Emotes" + return usr.emoteHandler.runEmote("me") + + + +/************************************************************************************************************************** + Custom Emotes +As these are made as needed, they aren't searched for the appropriate one. As such, you need to specify conditions for which +one is used in /datum/emote_handler/customEmote(). + +***************************************************************************************************************************/ + +/datum/emote/custom + name = "Custom emote" + baseLevel = 0 + +/datum/emote/custom/New(var/mob/user, var/message = "", var/isAudible) + if(!message) + message = getMessage(user) + text = message + audible = isAudible + +/datum/emote/custom/proc/getMessage(var/mob/user) +// user.set_typing_indicator(1) +// user.hud_typing = 1 + var/input = copytext(input(user,"What do you want to emote?", "Custom emote") as text|null,1,MAX_MESSAGE_LEN) +// user.hud_typing = 0 +// user.set_typing_indicator(0) + input = trim_strip_html_properly(input) + return input + +/datum/emote/custom/available(var/mob/user) + return 1 + +/datum/emote/custom/prevented(var/mob/user) + if(!user.use_me) + return "you are prevented from using custom emotes" + +// Yeah, no +/datum/emote/custom/createSelfMessage(var/mob/user, var/list/params, var/message = "") + return + +/datum/emote/custom/replaceMobWithYou(var/mob/M, var/message = "", var/mob/user) + return message + +/datum/emote/custom/ghost + name = "Ghost emote" + startText = "DEAD: " + emoteSpanClass = "game deadsay" + +/datum/emote/custom/ghost/prevented(var/mob/user) + . = ..() + if(.) + return + if(user.client.prefs.muted & MUTE_DEADCHAT) + return "you are muted from deadchat" + if(!(user.client.prefs.toggles & CHAT_DEAD)) + return "you have deadchat muted" + if(!user.client.holder) + if(!config.dsay_allowed) + return "deadchat is globally muted" + +/datum/emote/custom/ghost/getMessage(var/mob/user) + var/input = copytext(input(user,"What do you want to emote?", "Custom emote") as text|null,1,MAX_MESSAGE_LEN) + input = trim_strip_html_properly(input) + return input + +/datum/emote/custom/ghost/processMessage(var/mob/user, var/list/params, var/message = "") + if(!message) + return + log_emote("Ghost/[user.key] : [message]") + sendToDead(user, message, ghostEmote = 1) + diff --git a/code/datums/Emote_system/emote_handler.dm b/code/datums/Emote_system/emote_handler.dm new file mode 100644 index 00000000000..be962a72dc7 --- /dev/null +++ b/code/datums/Emote_system/emote_handler.dm @@ -0,0 +1,90 @@ +/datum/emoteHandler + var/mob/owner + var/list/commands + +/datum/emoteHandler/New(var/mob/user) + owner = user + setupCommands() + +/datum/emoteHandler/proc/setupCommands(var/reset = 0) + spawn(0) // needed so at mob creation species is set before emotes are allocated + if(reset) + deleteEmoteVerbs() + commands = new/list() + for(var/e in emotes) + var/datum/emote/emote = e + if(emote.baseLevel || emote.allowParent) + var/datum/emote/found = searchTree(emote) + if(found) + for(var/command in found.commands) + commands[lowertext(command)] = found + found.addVerbs(owner) + +/datum/emoteHandler/proc/deleteEmoteVerbs() + for(var/obj/emoteVerb/E in owner.contents) + qdel(E) + +/datum/emoteHandler/proc/runEmote(var/command = "", var/message = "", var/audible = 0) // message and audible only used in custom emotes + if(!command) + return 0 + if(command == "help") + showCommands() + return 1 + + var/datum/emote/emote + + if(copytext(command, 1, 3) == "me" && !message && lentext(command) >= 4) + message = copytext(command, 4) + command = "me" + + if(command == "me") + emote = customEmote(message, audible) + if(!emote) + return 0 + + if(!commands[command] && !(command == "me")) + to_chat(owner, "Unknown emote, please check *help for emotes available to your character") + return 0 + + if(!emote) + emote = commands[command] + + if(!emote.available(owner)) // something's changed, remake the commands list, then try again to see if they've got a different version + setupCommands() + return runEmote(command, message, audible) + + var/prevented = emote.prevented(owner) + if(prevented) + to_chat(owner, "You can't do that because [prevented]!") + return 0 + return emote.doEmote(owner, command) + +/datum/emoteHandler/proc/showCommands() + var/emoteList = "Available emotes are " + var/commandAdded = 0 + for(var/c in commands) + if(commandAdded) + emoteList += ", " + emoteList += c + commandAdded = 1 + + to_chat(owner, emoteList) + +// recursive search of subtypes - starts checking at the lowest level and breaks out if it finds one that can be done +/datum/emoteHandler/proc/searchTree(var/datum/emote/emote) + var/list/subtypes = subtypesof(emote.type) + var/datum/emote/found + for(var/t in subtypes) + var/datum/emote/em = new t + if(em.allowParent) + continue + found = searchTree(em) + if(found) + return (found) + if(emote.available(owner)) + return emote + +/datum/emoteHandler/proc/customEmote(var/custom, var/audible) + if(isobserver(owner)) + return new /datum/emote/custom/ghost(owner, custom, audible) + return new /datum/emote/custom(owner, custom, audible) diff --git a/code/datums/Emote_system/emotes.dm b/code/datums/Emote_system/emotes.dm new file mode 100644 index 00000000000..fd17fcc3953 --- /dev/null +++ b/code/datums/Emote_system/emotes.dm @@ -0,0 +1,1735 @@ + +/datum/emote/airguitar + name = "airguitar" + desc = "Makes the mob play an air guitar" + commands = list("airguitar") + text = "is strumming the air and headbanging like a safari chimp" + selfText = "are strumming the air and headbanging like a safari chimp" + restrained = 1 + +/datum/emote/airguitar/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/alarm + name = "alarm" + desc = "makes the mob sound an alarm" + commands = list("alarm") + text = "sounds an alarm" + selfText = "sound an alarm" + audible = 1 + +/datum/emote/alarm/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/alarm/createBlindMessage(var/mob/user, var/params, var/messaage) + return "You hear an alarm" + +/datum/emote/alert + name = "alert" + desc = "Makes the mob sound an alert" + commands = list("alert") + text = "lets out a distressed noise" + selfText = "let out a distressed noise" + audible = 1 + +/datum/emote/alert/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/beep + name = "beep" + desc = "makes the mob let out a beep" + commands = list("beep") + text = "beeps" + selfText = "beep" + audible = 1 + +/datum/emote/beep/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/beep/targetted + sound = 'sound/machines/twobeep.ogg' + cooldown = 50 + canTarget = 1 + targetMob = 1 + +/datum/emote/beep/targetted/available(var/mob/user) + if(user.is_mechanical()) + return 1 + +/datum/emote/blink + name = "blink" + desc = "Makes the mob blink" + commands = list("blink", "blinks") + text = "blinks" + selfText = "blink" + +/datum/emote/blink/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isbrain(user)) + return 1 + +/datum/emote/blink/rapid + name = "rapid blink" + desc = "Makes the mob blink rapidly" + commands = list("blink_r", "blinks_r") + allowParent = 1 + +/datum/emote/blink/rapid/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/blink/rapid/standardMessage(var/mob/user) + var/message = ..() + message += " rapidly" + return message + +/datum/emote/blush + name = "blush" + desc = "Makes the mob blush" + commands = list("blush", "blushes") + text = "blushes" + selfText = "blush" + +/datum/emote/blush/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/boop + name = "boop" + desc = "Makes the mob boop" + commands = list("boop", "boops") + text = "boops" + selfText = "boop" + +/datum/emote/boop/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/bounce + name = "bounce" + desc = "Makes the mob bounce" + commands = list("bounce", "bounces") + text = "bounces in place" + selfText = "bounce in place" + +/datum/emote/bounce/available(var/mob/user) + if(isslime(user)) + return 1 + +/datum/emote/bow + name = "bow" + desc = "Makes the mob bow" + commands = list("bow", "bows") + text = "bows" + selfText = "bow" + canTarget = 1 + targetMob = 1 + targetText = "to" + +/datum/emote/bow/available(var/mob/user) + if(isrobot(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/bow/prevented(var/mob/user) + . = ..() + if(!. && user.buckled) + return "you are buckled to something" + +/datum/emote/burp + name = "burp" + desc = "Makes the mob burp" + commands = list("burp", "burps") + text = "burps" + selfText = "burp" + audible = 1 + mimeText = "opens their mouth rather obnoxiously" + mimeSelf = "open your mouth rather obnoxiously" + muzzleAffected = 1 + muzzledNoise = "peculiar" + +/datum/emote/burp/available(var/mob/user) + if(ishuman(user)) + return 1 + if(islarva(user) || isalienadult(user)) + return 1 + +/datum/emote/buzz + name = "buzz" + desc = "Makes the mob buzz" + commands = list("buzz", "buzzes", "buzzs") + text = "buzzes" + selfText = "buzz" + audible = 1 + sound = 'sound/machines/buzz-sigh.ogg' + canTarget = 1 + targetMob = 1 + +/datum/emote/buzz/available(var/mob/user) + if(user.is_mechanical()) + return 1 + +/datum/emote/buzz/buzz2 + name = "buzz 2" + desc = "makes the mob buzz in an irritated way" + commands = list("buzz2") + text = "makes an irritated buzzing sound" + selfText = "make an irritated buzzing sound" + sound = "sound/machines/buzz-two.ogg" + allowParent = 1 + +/datum/emote/chirp + name = "chirp" + desc = "Makes the mob chirp" + commands = list("chirp", "chirps") + text = "chirps" + selfText = "chirp" + audible = 1 + sound = 'sound/misc/nymphchirp.ogg' + vol = 40 + cooldown = 50 + +/datum/emote/chirp/available(var/mob/user) + if(istype(user, /mob/living/simple_animal/diona)) + return 1 + +/datum/emote/choke + name = "choke" + desc = "Makes the mob choke" + commands = list("choke", "chokes") + text = "chokes" + selfText = "choke" + audible = 1 + mimeText = "clutches" + mimeSelf = "clutch" + muzzleAffected = 1 + muzzledNoise = "strong" + +/datum/emote/choke/available(var/mob/user) + if(ishuman(user)) + return 1 + if(islarva(user) || isalienadult(user)) + return 1 + +// This has to be done here not mimeText because \his will throw a compile error +// instead of a runtime if there's not a valid target in the string *frown VB +/datum/emote/choke/mimeMessage(var/mob/user, var/list/params) + var/message = "[user] [mimeText] \his throat desperately" + return message + +/datum/emote/chuckle + name = "chuckle" + desc = "chuckle" + commands = list("chuckle", "chuckles") + text = "chuckles" + selfText = "chuckle" + audible = 1 + mimeText = "appears to chuckle" + mimeSelf = "appear to chuckle" + muzzleAffected = 1 + +/datum/emote/chuckle/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/clap + name = "clap" + desc = "clap" + commands = list("clap", "claps") + text = "claps" + selfText = "clap" + audible = 1 + mimeText = "claps silently" + restrained = 1 + +/datum/emote/clap/available(var/mob/user) + if(isrobot(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/collapse + name = "collapse" + desc = "Makes the mob collapse" + commands = list("collapse", "collapses") + text = "collapses" + selfText = "collapse" + audible = 1 + mimeText = "collapses without a sound" + +/datum/emote/collapse/available(var/mob/user) + if(islarva(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/collapse/doAction(var/mob/user, var/list/params) + user.Paralyse(2) + +/datum/emote/cough + name = "cough" + desc = "Makes the mob cough" + commands = list("cough", "coughs") + text = "coughs" + selfText = "cough" + audible = 1 + mimeText = "appears to cough" + mimeSelf = "appear to cough" + muzzleAffected = 1 + muzzledNoise = "strong" + +/datum/emote/cough/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/cry + name = "cry" + desc = "Makes the mob cry" + commands = list("cry", "cries") + text = "cries" + selfText = "cry" + audible = 1 + mimeText = "cries silently" + muzzleAffected = 1 + muzzledNoise = "weak" + +/datum/emote/cry/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/dance + name = "dance" + desc = "makes the mob dance around happily" + commands = list("dance", "dances") + text = "dances around happily" + selfText = "dance around happily" + restrained = 1 + +/datum/emote/dance/available(var/mob/user) + if(islarva(user)) + return 1 + +/datum/emote/dap + name = "dap" + desc = "Makes the mob give daps" + commands = list("dap", "daps") + text = "gives daps" + selfText = "give daps" + restrained = 1 + canTarget = 1 + targetMob = 1 + targetText = "to" + +/datum/emote/dap/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/dap/addTarget(var/mob/user, var/list/params, var/message = "") + if(!params["target"] || params["target"] == user) + message = "[user] sadly can't find anybody to give daps to, and daps \himself. Shameful" + return message + return ..() + +/datum/emote/deathgasp + name = "deathgasp" + desc = "Makes the mob let out it's final gasp" + commands = list("deathgasp", "deathgasps") + audible = 1 + +/datum/emote/deathgasp/alien + text = "lets out a waning guttural screech, green blood bubbling from its maw..." + selfText = "let out a waning guttural screech, green blood bubbling from your maw..." + +/datum/emote/deathgasp/alien/available(var/mob/user) + if(isalienadult(user)) + return 1 + +// sorry, no selftext for humans as we'd have to add a var to species for it and that's yuk - VB +/datum/emote/deathgasp/human + text = "dummytext" + +/datum/emote/deathgasp/human/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/deathgasp/human/standardMessage(var/mob/user, var/list/params) + var/mob/living/carbon/human/U = user + var/message = "\The [user] [U.species.death_message]" + return message + +/datum/emote/deathgasp/human/createSelfMessage(var/mob/user, var/list/params, var/message) + return message + +/datum/emote/deathgasp/human/replaceMobWithYou(var/mob/user, var/message) + return message + +/datum/emote/deathgasp/robot + text = "shudders violently for a moment, then becomes motionless, its eyes slowly darkening" + selfText = "shudder violently for a moment, then become motionless, your eyes slowly darkening" + audible = 0 + +/datum/emote/deathgasp/robot/available(var/mob/user) + if(isrobot(user)) + return 1 + +/datum/emote/drone + name = "drone" + desc = "Makes the mob drone and rumble" + commands = list("drone", "drones", "rumble", "rumbles", "hum", "hums") + text = "rumbles" + selfText = "rumble" + audible = 1 + sound = 'sound/voice/DraskTalk.ogg' + canTarget = 1 + targetMob = 1 + +/datum/emote/drone/available(var/mob/user) + if(user.get_species() == "Drask") + return 1 + +/datum/emote/drone/addTarget(var/mob/user, var/list/params, var/message) + if(!params["target"]) + return message + message = replacetext(message, "rumbles", "drones") + return ..() + +/datum/emote/drone/createSelfMessage(var/mob/user, var/list/params, var/message) + message = ..() + message = replacetext(message, "drones", "drone") + return message + +/datum/emote/drool + name = "drool" + desc = "Makes the mob drool" + commands = list("drool", "drools") + text = "drools" + selfText = "drool" + +/datum/emote/drool/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/eyebrow + name = "eyebrow" + desc = "Makes the mob raise an eyebrow" + commands = list("eyebrow") + text = "raises an eyebrow" + selfText = "raise an eyebrow" + +/datum/emote/eyebrow/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/faint + name = "faint" + desc = "makes the mob faint" + commands = list("faint", "faints") + text = "faints" + selfText = "faint" + +/datum/emote/faint/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/faint/doAction(var/mob/user, var/list/params) + if(!user.sleeping) + user.sleeping += 1 + +/datum/emote/fart + name = "fart" + desc = "makes the mob fart" + commands = list("fart", "farts") + text = "farts" + selfText = "fart" + cooldown = 50 + audible = 1 + +/datum/emote/fart/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/fart/standardMessage(var/mob/user) + var/message + + if(TOXIC_FARTS in user.mutations) + message = "\The [user] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart" + return message + message = "\The [user] [pick("passes wind","farts")]" + return message + +/datum/emote/fart/createSelfMessage(var/mob/user, var/list/params, var/message) + message = ..() + message = replacetext(message, "unleashes", "unleash") + message = replacetext(message, "passes", "pass") + return message + +/datum/emote/fart/doAction(var/mob/user) + if(TOXIC_FARTS in user.mutations) + for(var/mob/M in range(get_turf(user),2)) + if(M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT)) + continue + if(M == user) + continue + M.reagents.add_reagent("jenkem", 1) + + if(locate(/obj/item/weapon/storage/bible) in get_turf(user)) + to_chat(viewers(user), "[user] farted on the Bible!") + to_chat(viewers(user), "A mysterious force smites [user]!") + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, user) + s.start() + user.gib() + +/datum/emote/flap + name = "flap" + desc = "Makes the mob flap their wings" + commands = list("flap", "flaps") + text = "flaps" + selfText = "flap" + restrained = 1 + audible = 1 + +/datum/emote/flap/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/flap/standardMessage(var/mob/user, var/list/params) + var/message = "\The [user] [text] \his wings" + return message + +/datum/emote/flap/angry + name = "angry flap" + desc = "makes the mob flap their wings angrily" + commands = list("a_flap", "a_flaps") + allowParent = 1 + +/datum/emote/flap/angry/standardMessage(var/mob/user) + var/message = ..() + message += " angrily" + return message + +/datum/emote/flash + name = "flash" + desc = "Makes the lights on the mob flash quickly" + commands = list("flash", "flashes") + text = "flash quickly" + selfText = "flash quickly" + startText = "The lights on" + +/datum/emote/flash/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/flip + name = "flip" + desc = "Makes the mob flip, possibly in the direction of someone" + commands = list("flip", "flips") + text = "flips" + selfText = "flip" + canTarget = 1 + targetMob = 1 + targetText = "in" + +/datum/emote/flip/available(var/mob/user) + if(isrobot(user)) + return 1 + +/datum/emote/flip/prevented(var/mob/user) + . = ..() + if(!. && user.buckled) + return "you are buckled to something" + +/datum/emote/flip/createMessage(var/mob/user, var/list/params) + var/message = "" + if(user.lying || user.weakened) + message = "\The [user] flops and flails around on the floor" + else + message = ..() + return message + +/datum/emote/flip/addTarget(var/mob/user, var/list/params, var/message) + message = ..() + if(params["target"]) + message += "'s general direction" + return message + +/datum/emote/flip/createSelfMessage(var/mob/user, var/list/params, var/message) + message = ..() + message = replacetext(message, "flops", "flop") + message = replacetext(message, "flails", "flail") + return message + +/datum/emote/flip/doAction(var/mob/user, var/list/params, var/message) + if(user.lying || user.weakened) + return + user.SpinAnimation(5,1) + +/datum/emote/flip/flipOver + desc = "Makes the mob flip, possibly in the direction of, or even over someone" + +/datum/emote/flip/flipOver/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/flip/flipOver/createMessage(var/mob/user, var/params) + var/message = "" + var/obj/item/weapon/grab/G = user.get_active_hand() + if(istype(G) && G.affecting && !G.affecting.buckled) + params["target"] = G.affecting + message = "\The [user] [text] over [params["target"]]!" + return message + return ..() + +/datum/emote/flip/flipOver/doAction(var/mob/user, var/params, var/message) + var/obj/item/weapon/grab/G = user.get_active_hand() + if(istype(G) && (G.affecting == params["target"]) && !G.affecting.buckled) + var/turf/oldloc = user.loc + var/turf/newloc = G.affecting.loc + if(isturf(oldloc) && isturf(newloc)) + user.SpinAnimation(5,1) + user.forceMove(newloc) + G.affecting.forceMove(oldloc) + return + ..() + +/datum/emote/frown + name = "frown" + desc = "Makes the mob frown" + commands = list("frown", "frowns") + text = "frowns" + selfText = "frown" + +/datum/emote/frown/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/gasp + name = "gasp" + desc = "Makes the mob gasp" + commands = list("gasp", "gasps") + text = "gasps" + selfText = "gasp" + audible = 1 + mimeText = "appears to be gasping" + mimeSelf = "appear to be gasping" + muzzleAffected = 1 + muzzledNoise = "weak" + +/datum/emote/gasp/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/giggle + name = "giggle" + desc = "Makes the mob giggle" + commands = list("giggle", "giggles") + text = "giggles" + selfText = "giggle" + audible = 1 + mimeText = "giggles silently" + muzzleAffected = 1 + +/datum/emote/giggle/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/glare + name = "glare" + desc = "Makes the mob glare" + commands = list("glare", "glares") + text = "glares" + selfText = "glare" + canTarget = 1 + targetMob = 1 + +/datum/emote/glare/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/gnarl + name = "gnarl" + desc = "Makes the mob gnarl and show its teeth" + commands = list("gnarl", "gnarls") + text = "gnarls and shows its teeth" + selfText = "gnarl and show your teeth" + audible = 1 + muzzleAffected = 1 + +/datum/emote/gnarl/available(var/mob/user) + if(islarva(user)) + return 1 + +/datum/emote/grin + name = "grin" + desc = "Makes the mob grin" + commands = list("grin", "grins") + text = "grins" + selfText = "grin" + +/datum/emote/grin/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/groan + name = "groan" + desc = "Makes the mob groan" + commands = list("groan", "groans") + text = "groans" + selfText = "groan" + audible = 1 + mimeText = "appears to groan" + mimeSelf = "appear to groan" + muzzleAffected = 1 + +/datum/emote/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/grumble + name = "grumble" + desc = "Makes the mob grumble" + commands = list("grumble", "grumbles") + text = "grumbles" + selfText = "grumble" + audible = 1 + mimeText = "grumbles" + muzzleAffected = 1 + +/datum/emote/grumble/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/halt + name = "halt" + desc = "Makes the mob sound a halt warning. Only available with a security module" + commands = list("halt") + text = "'s speakers skreech, \"Halt! Security!\"" + selfText = " speakers skreech, \"Halt! Security!\"" + audible = 1 + sound = 'sound/voice/halt.ogg' + +/datum/emote/halt/available(var/mob/user) + if(isrobot(user)) + return 1 + +/datum/emote/halt/prevented(var/mob/user) + . = ..() + if(.) + return + var/mob/living/silicon/robot/U = user + if(!(istype(U.module, /obj/item/weapon/robot_module/security))) + return "you are not security" + +/datum/emote/handshake + name = "handshake" + desc = "Makes the mob shake hands with a target" + commands = list("handshake") + text = "shakes hands" + selfText = "shake hands" + canTarget = 1 + targetMob = 1 + mustTarget = 1 + targetText = "with" + restrained = 1 + +/datum/emote/handshake/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/handshake/prevented(var/mob/user) + . = ..() + if(!. && user.r_hand) + return "you need your right hand free" + +/datum/emote/handshake/addTarget(var/mob/user, var/list/params, var/message) + var/mob/target = params["target"] + if(target.r_hand) + message = "\The [user] holds out his hand to [params["target"]]" + return message + return ..() + +/datum/emote/hiss + name = "hiss" + desc = "Makes the mob hiss" + commands = list("hiss", "hisses") + text = "hisses" + selfText = "hiss" + audible = 1 + +/datum/emote/hiss/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + +/datum/emote/hug + name = "hug" + desc = "Makes the mob hug a target or themselves" + commands = list("hug", "hugs") + text = "hugs" + selfText = "hug" + canTarget = 1 + targetMob = 1 + targetText = "" + +/datum/emote/hug/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/hug/getTarget(var/mob/user) + var/mob/target = ..() + if(target) + return target + return user + +/datum/emote/jiggle + name = "jiggle" + desc = "Makes the mob jiggle" + commands = list("jiggle", "jiggles") + text = "jiggles" + selfText = "jiggle" + +/datum/emote/jiggle/available(var/mob/user) + if(isslime(user)) + return 1 + +/datum/emote/johnny + name = "johnny" + desc = "Yeah, just try it" + commands = list("johnny") + text = "takes a drag from a cigarette and blows their name out in smoke" + selfText = "take a drag from a cigarette and blow their name out in smoke" + audible = 1 + mimeText = "takes a drag from a cigarette and blows" + mimeSelf = "take a drag from a cigarette and blow" + canTarget = 1 + targetMob = 1 + mustTarget = 1 + targetText = "" + +/datum/emote/johnny/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/johnny/getTarget(var/mob/user) + var/mob/target = ..() + if(target != user) + return target + to_chat(user, "You need a target that isn't yourself") + return INVALID + +/datum/emote/johnny/createMessage(var/mob/user, var/params) + if(doMime(user)) + return ..() + var/message = "\The [user] says \"[params["target"]], please. They had a family.\" [user] [text]" + return message + +/datum/emote/johnny/createSelfMessage(var/mob/user, var/list/params, var/message = "") + message = ..() + message = replacetext(message, "says", "say") + return message + +/datum/emote/johnny/createDeafMessage(var/mob/user, vap/list/params, var/message) + message = "\The [user] says something, then [text]" + return message + +/datum/emote/johnny/replaceMobWithYou(var/mob/M, var/message, var/mob/user) + if(user && M != user) + return message + return ..() + +/datum/emote/johnny/createBlindMessage(var/mob/user, var/list/params, var/message) + message = "You hear someone say \"[params["target"]], please, They had a family\"" + return message + +/datum/emote/jump + name = "jump" + desc = "Makes the mob jump" + commands = list("jump", "jumps") + text = "jumps" + selfText = "jump" + +/datum/emote/jump/available(var/mob/user) + if(islarva(user) || isalienadult(user)) + return 1 + if(issmall(user)) + return 1 + +/datum/emote/laugh + name = "laugh" + desc = "Makes the mob laugh" + commands = list("laugh", "laughs") + text = "laughs" + selfText = "laugh" + audible = 1 + mimeText = "acts out a laugh" + mimeSelf = "act out a laugh" + muzzleAffected = 1 + +/datum/emote/laugh/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/law + name = "law" + desc = "Makes the mob prove it is the law" + commands = list("law") + text = "shows its legal authorization barcode" + selfText = "show your legal authorization barcode" + audible = 1 + sound = 'sound/voice/biamthelaw.ogg' + +/datum/emote/law/available(var/mob/user) + if(isrobot(user)) + return 1 + +/datum/emote/law/prevented(var/mob/user) + . = ..() + if(.) + return + var/mob/living/silicon/robot/U = user + if(!(istype(U.module, /obj/item/weapon/robot_module/security))) + return "You are not THE LAW, pal" + +/datum/emote/light + name = "light" + desc = "makes the mob light up" + commands = list("light", "lights") + text = "lights up for a bit, then stops" + selfText = "light up for a bit, then stop" + +/datum/emote/light/available(var/mob/user) + if(isslime(user)) + return 1 + +/datum/emote/look + name = "look" + desc = "Makes the mob look" + commands = list("look", "looks") + text = "looks" + selfText = "look" + canTarget = 1 + targetMob = 1 + +/datum/emote/look/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/look/addTarget(var/mob/user, var/list/params, var/message) + if(!params["target"]) + message += " around" + return message + return ..() + +/datum/emote/moan + name = "moan" + desc = "Makes the mob moan" + commands = list("moan", "moans") + text = "moans" + selfText = "moan" + audible = 1 + +/datum/emote/moan/available(var/mob/user) + if(isslime(user)) + return 1 + if(islarva(user)) + return 1 + +/datum/emote/mumble + name = "mumble" + desc = "Makes the mob mumble" + commands = list("mumble", "mumbles") + text = "mumbles" + selfText = "mumble" + audible = 1 + mimeText = "mumbles" + +/datum/emote/mumble/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/no + name = "no" + desc = "Makes the mob let out a negative blip" + commands = list("no") + text = "emits a negative blip" + selfText = "emit a negative blip" + audible = 1 + sound = 'sound/machines/synth_no.ogg' + +/datum/emote/no/New() + ..() + commands += "no" + +/datum/emote/no/available(var/mob/user) + if(user.is_mechanical()) + return 1 + +/datum/emote/nod + name = "nod" + desc = "Makes the mob nod" + commands = list("nod", "nods") + text = "nods" + selfText = "nod" + +/datum/emote/nod/available(var/mob/user) + if(islarva(user)) + return 1 + if(isrobot(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/notice + name = "notice" + desc = "Makes the mob play a loud tone" + commands = list("notice") + text = "plays a loud tone" + selfText = "play a loud tone" + audible = 1 + +/datum/emote/notice/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/pale + name = "pale" + desc = "Makes the mob go pale" + commands = list("pale", "pales") + text = "goes pale for a second" + selfText = "go pale for a second" + +/datum/emote/pale/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/ping + name = "ping" + desc = "Makes the mob ping" + commands = list("ping", "pings") + text = "pings" + selfText = "ping" + audible = 1 + sound = 'sound/machines/ping.ogg' + canTarget = 1 + targetMob = 1 + +/datum/emote/ping/available(var/mob/user) + if(user.is_mechanical()) + return 1 + +/datum/emote/point + name = "point" + desc = "Makes the mob point" + commands = list("point", "points") + text = "points" + selfText = "point" + canTarget = 1 + +/datum/emote/point/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/point/createMessage(var/mob/user, var/list/params) + if(params["target"]) + return + return ..() + +/datum/emote/point/doAction(var/mob/user, var/list/params) + if(!params["target"]) + return + user.pointed(params["target"]) + +/datum/emote/quiver + name = "quiver" + desc = "Makes the mob quiver" + commands = list("quiver", "quivers") + text = "quivers" + selfText = "quiver" + +/datum/emote/quiver/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/raise + name = "raise" + desc = "Makes the mob raise a hand" + commands = list("raise", "raises") + text = "raises a hand" + selfText = "raise a hand" + restrained = 1 + +/datum/emote/raise/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/roar + name = "roar" + desc = "Makes the mob roar" + commands = list("roar", "roars") + text = "roars" + selfText = "roar" + audible = 1 + muzzleAffected = 1 + muzzledNoise = "loud" + +/datum/emote/roar/available(var/mob/user) + if(isalienadult(user)) + return 1 + +/datum/emote/roll + name = "roll" + desc = "Makes the mob roll" + commands = list("roll", "rolls") + text = "rolls" + selfText = "roll" + +/datum/emote/roll/available(var/mob/user) + if(islarva(user)) + return 1 + if(issmall(user)) + return 1 + +/datum/emote/salute + name = "salute" + desc = "Makes the mob salute" + commands = list("salute", "salutes") + text = "salutes" + selfText = "salute" + canTarget = 1 + targetMob = 1 + targetText = "to" + +/datum/emote/salute/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/salute/prevented(var/mob/user) + . = ..() + if(!. && user.buckled) + return "you are buckled to something" + +/datum/emote/salute/getMobTarget(var/mob/user, var/list/targets) + var/mob/target = ..() + if(target != user) + return target + +/datum/emote/scratch + name = "scratch" + desc = "Makes the mob scratch" + commands = list("scratch", "scratches") + text = "scratches" + selfText = "scratch" + restrained = 1 + +/datum/emote/scratch/available(var/mob/user) + if(islarva(user) || isalienadult(user)) + return 1 + if(issmall(user)) + return 1 + +/datum/emote/scream + name = "scream" + desc = "makes the mob scream" + commands = list("scream", "screams") + text = "screams!" + selfText = "scream!" + audible = 1 + mimeText = "acts out a scream" + muzzledNoise = "very loud" + cooldown = 50 + vol = 80 + +/datum/emote/scream/createMessage(var/mob/user, var/list/params) + var/mob/living/carbon/human/H = user + + if(istype(H)) + return "\The [user] [H.species.scream_verb]!" + else + return ..() + +/datum/emote/scream/replaceMobWithYou(var/mob/M, var/message = "", var/mob/user) + var/mob/living/carbon/human/H = user + + if(istype(H) && (H.species.scream_verb != "screams")) + return message + return ..() + +/datum/emote/scream/machine + name = "machine scream" + sound = 'sound/goonstation/voice/robot_scream.ogg' + +/datum/emote/scream/machine/available(var/mob/user) + if(user.is_mechanical()) + return 1 + +/datum/emote/scream/human + name = "human scream" + +/datum/emote/scream/human/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/scream/human/playSound(var/mob/user) + var/mob/living/carbon/human/H = user + + if(H.gender == FEMALE) + playsound(H, "[H.species.female_scream_sound]", vol, 1, 0, pitch = H.get_age_pitch()) + else + playsound(H, "[H.species.male_scream_sound]", vol, 1, 0, pitch = H.get_age_pitch()) + return 1 + +/datum/emote/scretch + name = "scretch" + desc = "makes the mob scretch" //whatever that is! + commands = list("scretch", "scretches") + text = "scretches" + selfText = "scretch" + audible = 1 + muzzleAffected = 1 + +/datum/emote/scretch/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + +/datum/emote/shake + name = "shake" + desc = "Makes the mob shake its head" + commands = list("shake", "shakes") + text = "shakes" + selfText = "shake" + +/datum/emote/shake/available(var/mob/user) + if(islarva(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/shake/standardMessage(var/mob/user) + var/message = ..() + message += " [getHis(user)] head" + return message + +/datum/emote/shiver + name = "shiver" + desc = "Makes the mob shiver" + commands = list("shiver", "shivers") + text = "shivers" + selfText = "shiver" + audible = 1 + mimeText = "shivers" + +/datum/emote/shiver/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + if(isslime(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/shiver/createBlindMessage(var/mob/user, var/list/params, var/message) + message = "you hear someone's teeth chattering together" + +/datum/emote/shrug + name = "shrug" + desc = "Makes the mob shrug" + commands = list("shrug", "shrugs") + text = "shrugs" + selfText = "shrug" + +/datum/emote/shrug/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/sigh + name = "sigh" + desc = "Makes the mob sigh" + commands = list("sigh", "sighs") + text = "sighs" + selfText = "sigh" + audible = 1 + mimeText = "sighs" + muzzleAffected = 1 + muzzledNoise = "weak" + +/datum/emote/sigh/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/sign + name = "sign" + desc = "Makes the mob sign a number" + commands = list("sign", "signs") + text = "signs" + selfText = "sign" + restrained = 1 + takesNumber = 1 + +/datum/emote/sign/available(var/mob/user) + if(isalienadult(user) || islarva(user)) + return 1 + +/datum/emote/sign/getNumber(var/mob/user) + var/number = ..() + if(number == null) + to_chat(user, "You need a number to sign") + return INVALID + return number + +/datum/emote/sign/paramMessage(var/mob/user, var/list/params) + var/message = "\The [user] [text] [params["num"]]" + return message + +/datum/emote/sign/fingers + desc = "Makes the mob raise a number of fingers" + text = "raises" + selfText = "raise" + +/datum/emote/sign/fingers/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/sign/fingers/getNumber(var/mob/user) + var/number = ..() + if(number == INVALID) + return INVALID + var/fingersAvailable = 0 + if(!user.r_hand) + fingersAvailable += 5 + if(!user.l_hand) + fingersAvailable += 5 + if(fingersAvailable < number) + to_chat(user, "You don't have enough fingers free") + return INVALID + return number + +/datum/emote/sign/fingers/paramMessage(var/mob/user, var/list/params) + var/message = "\The [user] [text] [params["num"]] finger\s" // no, we can't just add " finger\s" to the parent version because the text macro won't work then :( VB + return message + +/datum/emote/slap + name = "slap" + desc = "makes the mob slap someone" + commands = list("slap", "slaps") + text = "slaps" + selfText = "slap" + audible = 1 + sound = 'sound/effects/snap.ogg' + canTarget = 1 + targetMob = 1 + targetText = "" + +/datum/emote/slap/New() + ..() + cooldown = 0 + +/datum/emote/slap/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/slap/getMobTarget(var/mob/user, var/list/targets) + for(var/mob/M in view(getLoc(user), 1)) + targets += M + var/mob/target = input("Select target", "Target Mob") as null|anything in targets + if(target == "None") + target = user + return target + +/datum/emote/slap/createBlindMessage(var/mob/user, var/list/params, var/message) + message = ..() + message = replacetext(message, "someone", "a") + return message + +/datum/emote/slap/doAction(var/mob/user, var/list/params) + if(user == params["target"]) + var/mob/living/U = user + U.adjustFireLoss(4) + +/datum/emote/smile + name = "smile" + desc = "Makes the mob smile" + commands = list("smile", "smiles") + text = "smiles" + selfText = "smile" + +/datum/emote/smile/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/snap + name = "snap" + desc = "Makes the mob snap it's fingers" + commands = list("snap", "snaps") + text = "snaps" + selfText = "snap" + audible = 1 + sound = 'sound/effects/fingersnap.ogg' + +/datum/emote/snap/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/snap/prevented(var/mob/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/H = user + var/obj/item/organ/external/L = H.get_organ("l_hand") + var/obj/item/organ/external/R = H.get_organ("r_hand") + var/left_hand_good = 0 + var/right_hand_good = 0 + if(L && (!(L.status & ORGAN_DESTROYED)) && (!(L.status & ORGAN_SPLINTED)) && (!(L.status & ORGAN_BROKEN))) + left_hand_good = 1 + if(R && (!(R.status & ORGAN_DESTROYED)) && (!(R.status & ORGAN_SPLINTED)) && (!(R.status & ORGAN_BROKEN))) + right_hand_good = 1 + + if(!left_hand_good && !right_hand_good) + return "You need at least one hand in good working order to snap your fingers" + +/datum/emote/snap/standardMessage(var/mob/user, var/list/params) + var/message = ..() + message += " [getHis(user)] fingers" + params["prob"] = prob(5) + if(!params["prob"]) + return message + message += " right off!" + return message + +/datum/emote/snap/playSound(var/mob/user, var/list/params) + if(params["prob"]) + playsound(user.loc, 'sound/effects/snap.ogg', 50, 1) + return 1 + return ..() + +/datum/emote/snap/createBlindMessage(var/mob/user, var/list/params, var/message) + message = ..() + message += " their fingers" + return message + +/datum/emote/snap/createDeafMessage(var/mob/user, var/list/params, var/message) + return message + +/datum/emote/sneeze + name = "sneeze" + desc = "Makes the mob sneeze" + commands = list("sneeze", "sneezes") + text = "sneezes" + selfText = "sneeze" + audible = 1 + mimeText = "sneeze" + muzzleAffected = 1 + muzzledNoise = "strange" + +/datum/emote/sneeze/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/sniff + name = "sniff" + desc = "Makes the mob sniff" + commands = list("sniff", "sniffs") + text = "sniffs" + selfText = "sniff" + audible = 1 + mimeText = "sniffs" + +/datum/emote/sniff/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/snore + name = "snore" + desc = "Makes the mob snore" + commands = list("snore", "snores") + text = "snores" + selfText = "snore" + audible = 1 + mimeText = "sleeps soundly" + mimeSelf = "sleep soundly" + muzzleAffected = 1 + +/datum/emote/snore/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/squish + name = "squish" + desc = "Makes the mob squish" + commands = list("squish", "squishes") + text = "squishes" + selfText = "squish" + audible = 1 + sound = 'sound/effects/slime_squish.ogg' + canTarget = 1 + targetMob = 1 + +/datum/emote/squish/available(var/mob/user) + if(isslime(user)) + return 1 + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.species.name == "Slime People") //Only Slime People can squish + return 1 + for(var/obj/item/organ/external/L in H.organs) // if your limbs are squishy you can squish too! + if(L.dna.species =="Slime People") + return 1 + +/datum/emote/stare + name = "stare" + desc = "Makes the mob stare" + commands = list("stare", "stares") + text = "stares" + selfText = "stare" + canTarget = 1 + targetMob = 1 + +/datum/emote/stare/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/sulk + name = "sulk" + desc = "Makes the mob sulk" + commands = list("sulk", "sulks") + text = "sulks down sadly" + selfText = "sulk down sadly" + +/datum/emote/sulk/available(var/mob/user) + if(islarva(user)) + return 1 + +/datum/emote/sway + name = "sway" + desc = "Makes the mob sway" + commands = list("sway", "sways") + text = "sways around dizzily" + selfText = "sway around dizzily" + +/datum/emote/sway/available(var/mob/user) + if(islarva(user)) + return 1 + if(isslime(user)) + return 1 + +/datum/emote/tail + name = "tail" + desc = "Makes the mob wave it's tail" + commands = list("tail") + text = "waves it's tail" + selfText = "wave your tail" + +/datum/emote/tail/available(var/mob/user) + if(islarva(user) || isalienadult(user)) + return 1 + if(issmall(user)) + return 1 + +/datum/emote/tail/wag + name = "wag" + desc = "Makes the mob start wagging its tail" + commands = list("wag", "wags") + text = "starts" + selfText = "start" + +/datum/emote/tail/wag/available(var/mob/user) + if(issmall(user)) + return + if(ishuman(user)) + return 1 + +/datum/emote/tail/wag/prevented(var/mob/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/H = user + if(H.species.bodyflags & TAIL_WAGGING) + if(H.wear_suit && (H.wear_suit.flags_inv & HIDETAIL || istype(H.wear_suit, /obj/item/clothing/suit/space))) + return "your clothing is stopping you wag your tail" + return + if(!H.body_accessory) + return "you have no tail to wag!" + if(!H.body_accessory.try_restrictions()) + return "your clothing is stopping you wag your tail" + +/datum/emote/tail/wag/standardMessage(var/mob/user, var/list/params) + var/message = ..() + message += " wagging [getHis(user)] tail" + return message + +/datum/emote/tail/wag/doAction(var/mob/user, var/list/params) + var/mob/living/carbon/human/H = user + H.start_tail_wagging(1) + +/datum/emote/tail/wag/stop + name = "swag" + desc = "Makes the mob stop wagging its tail" + commands = list("swag", "swags") + text = "stops" + selfText = "stop" + allowParent = 1 + +// seemingly no way to tell if a mob is wagging it's tail! VB +/datum/emote/tail/wag/stop/prevented(var/mob/user) + . = ..() + if(.) + return + var/mob/living/carbon/human/H = user + if(!(H.species.bodyflags & TAIL_WAGGING) && !H.body_accessory) + return "you can't stop wagging a tail you don't have!" + +/datum/emote/tail/wag/stop/doAction(var/mob/user, var/list/params) + var/mob/living/carbon/human/H = user + H.stop_tail_wagging(1) + +/datum/emote/tremble + name = "tremble" + desc = "Makes the mob tremble" + commands = list("tremble", "trembles") + text = "trembles" + selfText = "tremble" + +/datum/emote/tremble/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/twitch_s + name = "twitch_s" + desc = "Makes the mob twitch" + commands = list("twitch_s", "twitches_s") + text = "twitches" + selfText = "twitch" + +/datum/emote/twitch_s/available(var/mob/user) + if(ishuman(user)) + return 1 + if(isrobot(user)) + return 1 + +/datum/emote/twitch_s/twitch + name = "twitch" + desc = "Makes the mob twitch violently" + commands = list("twitch", "twitches") + allowParent = 1 + +/datum/emote/twitch_s/twitch/available(var/mob/user) + if(isslime(user)) + return 1 + if(islarva(user)) + return 1 + return ..() + +/datum/emote/twitch_s/twitch/standardMessage(var/mob/user, var/list/params) + var/message = ..() + message += " violently" + return message + +/datum/emote/vibrate + name = "vibrate" + desc = "Makes the mob vibrate" + commands = list("vibrate", "vibrates") + text = "vibrates" + selfText = "vibrate" + +/datum/emote/vibrate/available(var/mob/user) + if(isslime(user)) + return 1 + +/datum/emote/wave + name = "wave" + desc = "Makes the mob wave" + commands = list ("wave", "waves") + text = "waves" + selfText = "wave" + +/datum/emote/wave/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/whimper + name = "whimper" + desc = "Makes the mob whimper" + commands = list("whimper", "whimpers") + text = "whimpers" + selfText = "whimper" + audible = 1 + mimeText = "appears hurt" + mimeSelf = "appear hurt" + muzzleAffected = 1 + +/datum/emote/whimper/available(var/mob/user) + if(islarva(user) || isalienadult(user)) + return 1 + if(ishuman(user)) + return 1 + +/datum/emote/whistle + name = "whistle" + desc = "Makes the mob whistle" + commands = list("whistle", "whistles") + text = "whistles" + selfText = "whistle" + audible = 1 + +/datum/emote/whistle/available(var/mob/user) + if(isbrain(user)) + return 1 + +/datum/emote/wink + name = "wink" + desc = "Makes the mob wink" + commands = list("wink", "winks") + text = "winks" + selfText = "wink" + +/datum/emote/wink/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/yawn + name = "yawn" + desc = "makes the mob yawn" + commands = list("yawn", "yawns") + text = "yawns" + selfText = "yawn" + audible = 1 + mimeText = "yawns" + muzzleAffected = 1 + +/datum/emote/yawn/available(var/mob/user) + if(ishuman(user)) + return 1 + +/datum/emote/yes + name = "yes" + desc = "Makes the mob let out an affirmative beep" + commands = list("yes") + text = "lets out an affirmative beep" + selfText = "let out an affirmative beep" + audible = 1 + sound = 'sound/machines/synth_yes.ogg' + canTarget = 1 + targetMob = 1 + +/datum/emote/yes/available(var/mob/user) + if(user.is_mechanical()) + return 1 \ No newline at end of file diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 062b8441a30..3cb965964b3 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -54,6 +54,7 @@ qdel(W) continue W.layer = initial(W.layer) + W.plane = initial(W.plane) W.loc = affected_mob.loc W.dropped(affected_mob) var/mob/living/new_mob = new new_form(affected_mob.loc) diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm index 382e96d2075..05998a708b0 100644 --- a/code/datums/helper_datums/map_template.dm +++ b/code/datums/helper_datums/map_template.dm @@ -62,10 +62,10 @@ /proc/preloadTemplates(path = "_maps/map_files/templates/") //see master controller setup - var/list/filelist = flist(path) - for(var/map in filelist) - var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") - map_templates[T.name] = T + for(var/map in flist(path)) + if(cmptext(copytext(map, length(map) - 3), ".dmm")) + var/datum/map_template/T = new(path = "[path][map]", rename = "[map]") + map_templates[T.name] = T if(!config.disable_space_ruins) // so we don't unnecessarily clutter start-up preloadRuinTemplates() diff --git a/code/datums/spells/dumbfire.dm b/code/datums/spells/dumbfire.dm index c1eb4889a93..7b5c77b7d21 100644 --- a/code/datums/spells/dumbfire.dm +++ b/code/datums/spells/dumbfire.dm @@ -79,8 +79,11 @@ qdel(trail) current_loc = projectile.loc + var/matrix/M = new + M.Turn(dir2angle(projectile.dir)) + projectile.transform = M sleep(proj_step_delay) if(projectile) - qdel(projectile) \ No newline at end of file + qdel(projectile) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 247d481f1be..be25ea14f1f 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -234,9 +234,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /datum/supply_packs/security/taser name = "Stun Guns Crate" - contains = list(/obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/gun/energy/advtaser, - /obj/item/weapon/gun/energy/advtaser) + contains = list(/obj/item/weapon/gun/energy/gun/advtaser, + /obj/item/weapon/gun/energy/gun/advtaser, + /obj/item/weapon/gun/energy/gun/advtaser) cost = 15 containername = "stun gun crate" diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 08c418778a3..ad13d541d96 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -101,9 +101,9 @@ var/list/uplink_items = list() if(istype(I,/obj/item/weapon/storage/box/) && I.contents.len>0) for(var/atom/o in I) - U.purchase_log += "\icon[o]" + U.purchase_log += "[bicon(o)]" else - U.purchase_log += "\icon[I]" + U.purchase_log += "[bicon(I)]" //U.interact(user) return 1 @@ -341,7 +341,7 @@ var/list/uplink_items = list() reference = "SPI" desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible with suppressors." item = /obj/item/weapon/gun/projectile/automatic/pistol - cost = 9 + cost = 4 /datum/uplink_item/dangerous/revolver name = "Syndicate .357 Revolver" @@ -410,6 +410,13 @@ var/list/uplink_items = list() item = /obj/item/weapon/twohanded/chainsaw cost = 13 +/datum/uplink_item/dangerous/batterer + name = "Mind Batterer" + desc = "A device that has a chance of knocking down people around you for a long amount of time. 50% chance per person. The user is unaffected. Has 5 charges." + reference = "BTR" + item = /obj/item/device/batterer + cost = 5 + /datum/uplink_item/dangerous/manhacks name = "Viscerator Delivery Grenade" desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred any non-operatives in the area." @@ -605,10 +612,10 @@ var/list/uplink_items = list() gamemodes = list(/datum/game_mode/nuclear) /datum/uplink_item/ammo/machinegun - name = "Box Magazine - 7.62x51mm" - desc = "A 50-round magazine of 7.62x51mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." + name = "Box Magazine - 5.56x45mm" + desc = "A 50-round magazine of 5.56x45mm ammunition for use in the L6 SAW machine gun. By the time you need to use this, you'll already be on a pile of corpses." reference = "762" - item = /obj/item/ammo_box/magazine/m762 + item = /obj/item/ammo_box/magazine/mm556x45 cost = 12 gamemodes = list(/datum/game_mode/nuclear) surplus = 0 @@ -686,7 +693,7 @@ var/list/uplink_items = list() desc = "Fitted for use on any small caliber weapon with a threaded barrel, this suppressor will silence the shots of the weapon for increased stealth and superior ambushing capability." reference = "US" item = /obj/item/weapon/suppressor - cost = 3 + cost = 1 surplus = 10 /datum/uplink_item/stealthy_weapons/pizza_bomb @@ -1016,7 +1023,7 @@ var/list/uplink_items = list() /datum/uplink_item/implants/uplink name = "Uplink Implant" - desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 5 telecrystals. The ability for an agent to open an uplink after their possessions have been stripped from them makes this implant excellent for escaping confinement." + desc = "An implant injected into the body, and later activated using a bodily gesture to open an uplink with 10 telecrystals. The ability for an agent to open an uplink after their possessions have been stripped from them makes this implant excellent for escaping confinement." reference = "UI" item = /obj/item/weapon/implanter/uplink cost = 14 @@ -1213,7 +1220,7 @@ var/list/uplink_items = list() bought_items += I.item remaining_TC -= I.cost - U.purchase_log += "\icon[C]" + U.purchase_log += "[bicon(C)]" for(var/item in bought_items) new item(C) - U.purchase_log += "\icon[item]" + U.purchase_log += "[bicon(item)]" diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index d52b410b3dd..f6ffd2ed427 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -66,7 +66,7 @@ var/const/CAMERA_WIRE_NOTHING2 = 32 C.light_disabled = !C.light_disabled if(CAMERA_WIRE_ALARM) - C.visible_message("\icon[C] *beep*", "\icon[C] *beep*") + C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*") return /datum/wires/camera/proc/CanDeconstruct() diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm index 30d767eef21..7b59479720d 100644 --- a/code/datums/wires/mulebot.dm +++ b/code/datums/wires/mulebot.dm @@ -28,15 +28,15 @@ var/const/WIRE_BEACON_RX = 256 // beacon ping recv /datum/wires/mulebot/UpdatePulsed(var/index) switch(index) if(WIRE_POWER1, WIRE_POWER2) - holder.visible_message("\blue \icon[holder] The charge light flickers.") + holder.visible_message("\blue [bicon(holder)] The charge light flickers.") if(WIRE_AVOIDANCE) - holder.visible_message("\blue \icon[holder] The external warning lights flash briefly.") + holder.visible_message("\blue [bicon(holder)] The external warning lights flash briefly.") if(WIRE_LOADCHECK) - holder.visible_message("\blue \icon[holder] The load platform clunks.") + holder.visible_message("\blue [bicon(holder)] The load platform clunks.") if(WIRE_MOTOR1, WIRE_MOTOR2) - holder.visible_message("\blue \icon[holder] The drive motor whines briefly.") + holder.visible_message("\blue [bicon(holder)] The drive motor whines briefly.") else - holder.visible_message("\blue \icon[holder] You hear a radio crackle.") + holder.visible_message("\blue [bicon(holder)] You hear a radio crackle.") // HELPER PROCS diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index 948ac9dda6c..53a166a79e7 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -28,7 +28,7 @@ var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be. C.interface_control = !C.interface_control if(PARTICLE_LIMIT_POWER_WIRE) - C.visible_message("\icon[C][C] makes a large whirring noise.") + C.visible_message("[bicon(C)][C] makes a large whirring noise.") /datum/wires/particle_acc/control_box/UpdateCut(var/index, var/mended) var/obj/machinery/particle_accelerator/control_box/C = holder diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm index af084ee00f9..6feaf9221ed 100644 --- a/code/datums/wires/syndicatebomb.dm +++ b/code/datums/wires/syndicatebomb.dm @@ -21,17 +21,17 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if switch(index) if(WIRE_BOOM) if (P.active) - P.loc.visible_message("\icon[holder] An alarm sounds! It's go-") + P.loc.visible_message("[bicon(holder)] An alarm sounds! It's go-") P.timer = 0 if(WIRE_UNBOLT) - P.loc.visible_message("\icon[holder] The bolts spin in place for a moment.") + P.loc.visible_message("[bicon(holder)] The bolts spin in place for a moment.") if(WIRE_DELAY) playsound(P.loc, 'sound/machines/chime.ogg', 30, 1) - P.loc.visible_message("\icon[holder] The bomb chirps.") + P.loc.visible_message("[bicon(holder)] The bomb chirps.") P.timer += 10 if(WIRE_PROCEED) playsound(P.loc, 'sound/machines/buzz-sigh.ogg', 30, 1) - P.loc.visible_message("\icon[holder] The bomb buzzes ominously!") + P.loc.visible_message("[bicon(holder)] The bomb buzzes ominously!") if (P.timer >= 61) //Long fuse bombs can suddenly become more dangerous if you tinker with them P.timer = 60 if (P.timer >= 21) @@ -41,11 +41,11 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if if(WIRE_ACTIVATE) if(!P.active && !P.defused) playsound(P.loc, 'sound/machines/click.ogg', 30, 1) - P.loc.visible_message("\icon[holder] You hear the bomb start ticking!") + P.loc.visible_message("[bicon(holder)] You hear the bomb start ticking!") P.active = 1 P.icon_state = "[initial(P.icon_state)]-active[P.open_panel ? "-wires" : ""]" else - P.loc.visible_message("\icon[holder] The bomb seems to hesitate for a moment.") + P.loc.visible_message("[bicon(holder)] The bomb seems to hesitate for a moment.") P.timer += 5 /datum/wires/syndicatebomb/UpdateCut(var/index, var/mended) @@ -54,7 +54,7 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if if(WIRE_EXPLODE) if(!mended) if(P.active) - P.loc.visible_message("\icon[holder] An alarm sounds! It's go-") + P.loc.visible_message("[bicon(holder)] An alarm sounds! It's go-") P.timer = 0 else P.defused = 1 @@ -63,15 +63,15 @@ var/const/WIRE_ACTIVATE = 16 // Will start a bombs timer if pulsed, will hint if if(WIRE_UNBOLT) if (!mended && P.anchored) playsound(P.loc, 'sound/effects/stealthoff.ogg', 30, 1) - P.loc.visible_message("\icon[holder] The bolts lift out of the ground!") + P.loc.visible_message("[bicon(holder)] The bolts lift out of the ground!") P.anchored = 0 if(WIRE_PROCEED) if(!mended && P.active) - P.loc.visible_message("\icon[holder] An alarm sounds! It's go-") + P.loc.visible_message("[bicon(holder)] An alarm sounds! It's go-") P.timer = 0 if(WIRE_ACTIVATE) if (!mended && P.active) - P.loc.visible_message("\icon[holder] The timer stops! The bomb has been defused!") + P.loc.visible_message("[bicon(holder)] The timer stops! The bomb has been defused!") P.icon_state = "[initial(P.icon_state)]-inactive[P.open_panel ? "-wires" : ""]" P.active = 0 P.defused = 1 \ No newline at end of file diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 1706763b824..3ac3feb3bef 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -295,6 +295,10 @@ var/list/ghostteleportlocs = list() name = "\improper Special Ops Shuttle" icon_state = "shuttlered2" +/area/shuttle/syndicate_elite + name = "\improper Syndicate Elite Shuttle" + icon_state = "shuttlered" + /area/shuttle/syndicate_elite/mothership name = "\improper Syndicate Elite Shuttle" icon_state = "shuttlered" @@ -438,6 +442,14 @@ var/list/ghostteleportlocs = list() name = "Syndicate Infiltrator" icon_state = "shuttle" +/area/shuttle/trade + name = "Trade Shuttle" + icon_state = "shuttle" + requires_power = 0 + +/area/shuttle/trade/sol + name = "Sol Freighter" + /area/airtunnel1/ // referenced in airtunnel.dm:759 /area/dummy/ // Referenced in engine.dm:261 @@ -675,6 +687,14 @@ var/list/ghostteleportlocs = list() icon_state = "southeast" requires_power = 0 +/area/trader_station + name = "Trade Base" + icon_state = "yellow" + requires_power = 0 + +/area/trader_station/sol + name = "Jupiter Station 6" + /area/vox_station/mining name = "\improper Nearby Mining Asteroid" icon_state = "north" diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm index 6071a804aa8..9ac351e6c2f 100644 --- a/code/game/asteroid.dm +++ b/code/game/asteroid.dm @@ -123,7 +123,7 @@ var/global/max_secret_rooms = 6 theme = "plantlab" treasureitems = list(/obj/item/weapon/gun/energy/floragun=1,/obj/item/seeds/ambrosiadeusseed=2,/obj/item/seeds/bluespacetomatoseed=2,/obj/item/seeds/bluetomatoseed=2, /obj/item/seeds/coffeerseed=2, /obj/item/seeds/stobaccoseed=2) - fluffitems = list(/obj/structure/flora/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/portable_atmospherics/hydroponics=1, + fluffitems = list(/obj/item/weapon/twohanded/required/kirbyplants=1,/obj/structure/table/reinforced=2,/obj/machinery/portable_atmospherics/hydroponics=1, /obj/effect/glowshroom/single=2,/obj/item/weapon/reagent_containers/syringe/charcoal=2, /obj/item/weapon/reagent_containers/glass/bottle/diethylamine=3,/obj/item/weapon/reagent_containers/glass/bottle/ammonia=3) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d13ce8b0bfa..557de91356a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -187,7 +187,7 @@ else f_name += "oil-stained [name][infix]." - to_chat(user, "\icon[src] That's [f_name] [suffix]") + to_chat(user, "[bicon(src)] That's [f_name] [suffix]") to_chat(user, desc) if(reagents && is_open_container()) //is_open_container() isn't really the right proc for this, but w/e diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 92c894cba10..b169deeee10 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -331,4 +331,4 @@ /atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5) if(buckled_mob == mover) return 1 - return ..() \ No newline at end of file + return ..() diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index b308d996de9..936e5ac0001 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -70,20 +70,40 @@ switch(health) if(100 to INFINITY) return "health100" - if(70 to 100) - return "health80" - if(50 to 70) - return "health60" - if(30 to 50) - return "health40" - if(18 to 30) - return "health25" - if(5 to 18) - return "health10" - if(1 to 5) + if(93 to 100) + return "health93" + if(86 to 93) + return "health86" + if(78 to 86) + return "health78" + if(71 to 78) + return "health71" + if(64 to 71) + return "health64" + if(56 to 64) + return "health56" + if(49 to 56) + return "health49" + if(42 to 49) + return "health42" + if(35 to 42) + return "health35" + if(28 to 35) + return "health28" + if(21 to 28) + return "health21" + if(14 to 21) + return "health14" + if(7 to 14) + return "health7" + if(1 to 7) return "health1" - if(-99 to 0) + if(-50 to 1) return "health0" + if(-85 to -50) + return "health-50" + if(-99 to -85) + return "health-85" else return "health-100" return "0" diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm index 3a6d5066ab3..c50c04860cf 100644 --- a/code/game/dna/genes/goon_powers.dm +++ b/code/game/dna/genes/goon_powers.dm @@ -410,13 +410,16 @@ "You hear the flexing of powerful muscles and suddenly a crash as a body hits the floor.") return 0 var/prevLayer = usr.layer + var/prevFlying = usr.flying usr.layer = 9 + usr.flying = 1 for(var/i=0, i<10, i++) step(usr, usr.dir) if(i < 5) usr.pixel_y += 8 else usr.pixel_y -= 8 sleep(1) + usr.flying = prevFlying if (FAT in usr.mutations && prob(66)) usr.visible_message("\red [usr.name] crashes due to their heavy weight!") diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm index 13f334c010b..08784b71a61 100644 --- a/code/game/dna/genes/vg_powers.dm +++ b/code/game/dna/genes/vg_powers.dm @@ -116,11 +116,24 @@ //Skin tone. if(M.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) + 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 M.s_tone = 35 - max(min(round(text2num(new_tone)), 220), 1) + 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; i <= M.species.icon_skin_tones.len; i++) + prompt += "[i] = [M.species.icon_skin_tones[i]]" + if(i != M.species.icon_skin_tones.len) + prompt += ", " + prompt += ")" + + var/new_tone = input(prompt, "Character Generation", M.s_tone) as null|text + if(!new_tone) + new_tone = 0 + M.s_tone = max(min(round(text2num(new_tone)), M.species.icon_skin_tones.len), 1) + //Skin colour. if(M.species.bodyflags & HAS_SKIN_COLOR) var/new_body_colour = input("Please select body colour.", "Character Generation", rgb(M.r_skin, M.g_skin, M.b_skin)) as null|color diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm index a41dcb8d583..4f785ca99aa 100644 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ b/code/game/gamemodes/autotraitor/autotraitor.dm @@ -133,7 +133,7 @@ equip_traitor(newtraitor) traitors += newtraitor.mind - to_chat(newtraitor, "\red ATTENTION: \black It is time to pay your debt to the Syndicate...") + to_chat(newtraitor, "ATTENTION: It is time to pay your debt to the Syndicate...") to_chat(newtraitor, "You are now a traitor.") newtraitor.mind.special_role = "traitor" var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR] diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 1238adebcf5..069edaa6ecf 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -103,9 +103,6 @@ if(isovermind(M) || isobserver(M)) M.show_message(rendered, 2) -/mob/camera/blob/emote(var/act,var/m_type=1,var/message = null) - return - /mob/camera/blob/blob_act() return diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a16d120bb4d..448a4a9179d 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -334,7 +334,7 @@ //Reports player logouts// ////////////////////////// proc/display_roundstart_logout_report() - var/msg = "\blue Roundstart logout report\n\n" + var/msg = "Roundstart logout report\n\n" for(var/mob/living/L in mob_list) if(L.ckey) diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 83d21e8cfad..a4c4656391c 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -253,6 +253,7 @@ var/round_start_time = 0 cinematic.icon = 'icons/effects/station_explosion.dmi' cinematic.icon_state = "station_intact" cinematic.layer = 20 + cinematic.plane = HUD_PLANE cinematic.mouse_opacity = 0 cinematic.screen_loc = "1,0" diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 952b43d5f37..6079a3c1a2e 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -84,7 +84,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' /datum/game_mode/proc/create_vox(var/datum/mind/newraider) - var/sounds = rand(2,8) var/i = 0 var/newname = "" @@ -97,10 +96,12 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' var/obj/item/organ/external/head/head_organ = vox.get_organ("head") vox.real_name = capitalize(newname) + vox.dna.real_name = vox.real_name vox.name = vox.real_name newraider.name = vox.name vox.age = rand(12,20) vox.set_species("Vox") + vox.s_tone = rand(1, 6) vox.languages = list() // Removing language from chargen. vox.flavor_text = "" vox.add_language("Vox-pidgin") @@ -108,6 +109,16 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' vox.add_language("Tradeband") head_organ.h_style = "Short Vox Quills" head_organ.f_style = "Shaved" + vox.change_hair_color(97, 79, 25) //Same as the species default colour. + vox.change_eye_color(rand(1, 255), rand(1, 255), rand(1, 255)) + vox.underwear = "Nude" + vox.undershirt = "Nude" + vox.socks = "Nude" + + // Do the initial caching of the player's body icons. + vox.force_update_limbs() + vox.update_dna() + vox.update_eyes() for(var/obj/item/organ/external/limb in vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 803a7ba0d80..3c8b96935ec 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -72,7 +72,7 @@ rcd light flash thingy on matter drain if(T.z in config.station_levels) // Increase health by 37.5% of original max, decrease delays between shots to 66% turret.health += initial(turret.health) * 3 / 8 - turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR. + turret.eprojectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR. turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg' to_chat(src, "Turrets upgraded.") /datum/AI_Module/large/destroy_rcd diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 01260b84a34..930ec3df35d 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -308,14 +308,7 @@ icon_state = "alienpistol" item_state = "alienpistol" origin_tech = "combat=5;materials=4;powerstorage=3;abductor=3" - -/obj/item/weapon/gun/energy/decloner/alien/special_check(user) - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(H.get_species() != "Abductor") - to_chat(user, "UNAUTHORIZED -- UNAUTHORIZED") - return 0 - return 1 + restricted_species = list("Abductor") /obj/item/weapon/paper/abductor name = "Dissection Guide" @@ -631,4 +624,4 @@ Congratulations! You are now trained for xenobiology research!"} icon_state = "abductor" icon_closed = "abductor" icon_opened = "abductoropen" - material_drop = /obj/item/stack/sheet/mineral/abductor \ No newline at end of file + material_drop = /obj/item/stack/sheet/mineral/abductor diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm index 1a0d7770a1a..91c2bddb74c 100644 --- a/code/game/gamemodes/miniantags/borer/borer.dm +++ b/code/game/gamemodes/miniantags/borer/borer.dm @@ -33,10 +33,7 @@ return 0 return B.host.say_understands(other, speaking) -/mob/living/captive_brain/emote(var/message) - return - -/mob/living/captive_brain/resist_borer() +/mob/living/captive_brain/resist() var/mob/living/simple_animal/borer/B = loc to_chat(src, "You begin doggedly resisting the parasite's control (this will take approximately sixty seconds).") diff --git a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm index d836511fc42..f0e0dc1a883 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_abilities.dm @@ -238,7 +238,8 @@ action_icon_state = "defile" var/stamdamage= 25 var/toxdamage = 5 - var/confusion = 50 + var/confusion = 20 + var/maxconfusion = 30 /obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(attempt_cast(user)) @@ -251,7 +252,7 @@ to_chat(human, "You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")].") human.adjustStaminaLoss(stamdamage) human.adjustToxLoss(toxdamage) - human.confused += confusion + human.confused = min(human.confused+confusion, maxconfusion) new/obj/effect/overlay/temp/revenant(human.loc) if(!istype(T, /turf/simulated/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15)) new/obj/effect/overlay/temp/revenant(T) @@ -281,7 +282,7 @@ name = "Malfunction" desc = "Corrupts and damages nearby machines and mechanical objects." charge_max = 200 - range = 4 + range = 2 cast_amount = 45 unlock_amount = 150 action_icon_state = "malfunction" diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index aae6d31261a..72fa2b8dbbe 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -651,32 +651,7 @@ datum return 10 else return 20 - - - RCD - steal_target = /obj/item/weapon/rcd - explanation_text = "Steal a rapid construction device." - weight = 20 - - get_points(var/job) - switch(GetRank(job)) - if(0) - return 75 - if(1) - return 60 - if(2) - return 50 - if(3) - return 30 - if(4) - return 20 - - get_weight(var/job) - if(GetRank(job) == 4) - return 10 - else - return 20 - + /*burger steal_target = /obj/item/weapon/reagent_containers/food/snacks/human/burger diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 25b3727ec3a..19d725f8677 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -247,10 +247,11 @@ var/list/potential_theft_objectives=subtypesof(/datum/theft_objective) \ return 1 return 0 +/datum/objective/protect/mindslave //subytpe for mindslave implants /datum/objective/hijack martyr_compatible = 0 //Technically you won't get both anyway. - explanation_text = "Hijack the shuttle to ensure no loyalist Nanotrasen crew escape alive." + explanation_text = "Hijack the shuttle by escaping on it with no loyalist NanoTrasen crew on board and alive. Syndicate agents, other enemies of NanoTrasen, cyborgs, and pets may be allowed to escape alive." check_completion() if(!owner.current || owner.current.stat) @@ -310,7 +311,7 @@ var/list/potential_theft_objectives=subtypesof(/datum/theft_objective) \ return 0 /datum/objective/block - explanation_text = "Do not allow any organic lifeforms to escape on the shuttle alive." + explanation_text = "Do not allow any lifeforms, be it organic or synthetic to escape on the shuttle alive. AIs, Cyborgs, and pAIs are not considered alive." martyr_compatible = 1 check_completion() @@ -667,7 +668,7 @@ var/list/potential_theft_objectives=subtypesof(/datum/theft_objective) \ if(5) target = /obj/item/weapon/gun target_amount = 6 - loot = "six guns" + loot = "six guns. Tasers and other non-lethal guns are acceptable" if(6) target = /obj/item/weapon/gun/energy target_amount = 4 @@ -796,12 +797,52 @@ var/list/potential_theft_objectives=subtypesof(/datum/theft_objective) \ return 1 return 0 -#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken. - //Would be nice to use vox-specific kills but is currently not feasible. -var/global/vox_kills = 0 //Used to check the Inviolate. - /datum/objective/heist/inviolate_death explanation_text = "Follow the Inviolate. Minimise death and loss of resources." - check_completion() - if(vox_kills > MAX_VOX_KILLS) return 0 - return 1 \ No newline at end of file + completed = 1 + +// Traders + +/datum/objective/trade // Yes, I know there's no check_completion. The objectives exist only to tell the traders what to get. +/datum/objective/trade/proc/choose_target(var/station) + return + +/datum/objective/trade/stock // Stock or spare parts. + var/target_rating = 1 +/datum/objective/trade/stock/choose_target(var/station) + var/itemname + switch(rand(1,8)) + if(1) + target = /obj/item/weapon/stock_parts/cell + target_amount = 10 + target_rating = 3 + itemname = "ten high-capacity power cells" + if(2) + target = /obj/item/weapon/stock_parts/manipulator + target_amount = 20 + itemname = "twenty micro manipulators" + if(3) + target = /obj/item/weapon/stock_parts/matter_bin + target_amount = 20 + itemname = "twenty matter bins" + if(4) + target = /obj/item/weapon/stock_parts/micro_laser + target_amount = 15 + itemname = "fifteen micro-lasers" + if(5) + target = /obj/item/weapon/stock_parts/capacitor + target_amount = 15 + itemname = "fifteen capacitors" + if(6) + target = /obj/item/weapon/stock_parts/subspace/filter + target_amount = 4 + itemname = "four hyperwave filters" + if(7) + target = /obj/item/solar_assembly + target_amount = 10 + itemname = "ten solar panel assemblies" + if(8) + target = /obj/item/device/flash + target_amount = 6 + itemname = "six flashes" + explanation_text = "We are running low on spare parts. Trade for [itemname]." \ No newline at end of file diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 4d061d37eca..e4f7bc15657 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -64,27 +64,35 @@ datum/hSB if(P.wear_suit) P.wear_suit.loc = P.loc P.wear_suit.layer = initial(P.wear_suit.layer) + P.wear_suit.plane = initial(P.wear_suit.plane) P.wear_suit = null P.wear_suit = new/obj/item/clothing/suit/space(P) P.wear_suit.layer = 20 + P.wear_suit.plane = HUD_PLANE if(P.head) P.head.loc = P.loc P.head.layer = initial(P.head.layer) + P.head.plane = initial(P.head.plane) P.head = null P.head = new/obj/item/clothing/head/helmet/space(P) P.head.layer = 20 + P.head.plane = HUD_PLANE if(P.wear_mask) P.wear_mask.loc = P.loc P.wear_mask.layer = initial(P.wear_mask.layer) + P.wear_mask.plane = initial(P.wear_mask.plane) P.wear_mask = null P.wear_mask = new/obj/item/clothing/mask/gas(P) P.wear_mask.layer = 20 + P.wear_mask.plane = HUD_PLANE if(P.back) P.back.loc = P.loc P.back.layer = initial(P.back.layer) + P.back.plane = initial(P.back.plane) P.back = null P.back = new/obj/item/weapon/tank/jetpack(P) P.back.layer = 20 + P.back.plane = HUD_PLANE P.internal = P.back if("hsbmetal") var/obj/item/stack/sheet/hsb = new/obj/item/stack/sheet/metal diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm index fd648b05c7d..d81b50c1922 100644 --- a/code/game/gamemodes/steal_items.dm +++ b/code/game/gamemodes/steal_items.dm @@ -35,7 +35,7 @@ /datum/theft_objective/hoslaser name = "the head of security's recreated antique laser gun" - typepath = /obj/item/weapon/gun/energy/hos + typepath = /obj/item/weapon/gun/energy/gun/hos protected_jobs = list("Head Of Security") /datum/theft_objective/hand_tele @@ -43,11 +43,6 @@ typepath = /obj/item/weapon/hand_tele protected_jobs = list("Captain", "Research Director") -/datum/theft_objective/rcd - name = "a rapid-construction-device" - typepath = /obj/item/weapon/rcd - protected_jobs = list("Chief Engineer", "Quartermaster", "Cargo Technician", "Research Director", "Scientist", "Roboticist") - /datum/theft_objective/jetpack name = "a jetpack" typepath = /obj/item/weapon/tank/jetpack @@ -124,6 +119,11 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/device/aicard/C) typepath = /obj/item/clothing/suit/armor/laserproof protected_jobs = list("Head of Security", "Warden") +/datum/theft_objective/krav + name = "the warden's krav maga martial arts gloves" + typepath = /obj/item/clothing/gloves/color/black/krav_maga/sec + protected_jobs = list("Head Of Security", "Warden") + /datum/theft_objective/number var/min=0 var/max=0 @@ -244,4 +244,4 @@ datum/theft_objective/ai/check_special_completion(var/obj/item/device/aicard/C) typepath = /obj/item/stack/sheet/mineral/uranium min=10 max=30 - step=5 \ No newline at end of file + step=5 diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 97f2d301472..76a47e82749 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -366,10 +366,11 @@ traitor_mind.special_role = null traitor_mind.som = null slaved.leave_serv_hud(traitor_mind) + for(var/datum/objective/protect/mindslave/MS in traitor_mind.objectives) + traitor_mind.objectives -= MS update_traitor_icons_removed(traitor_mind) -// to_chat(world, "Removed [traitor_mind.current.name] from traitor shit") - to_chat(traitor_mind.current, "\red The fog clouding your mind clears. You remember nothing from the moment you were implanted until now.(You don't remember who implanted you)") + to_chat(traitor_mind.current, "You are no longer a mindslave; you have complete and free control of your own faculties, once more!") /datum/game_mode/proc/assign_exchange_role(var/datum/mind/owner) //set faction diff --git a/code/game/gamemodes/vampire/traitor_vamp.dm b/code/game/gamemodes/vampire/traitor_vamp.dm index 9d4cb42b545..a5f2613dccc 100644 --- a/code/game/gamemodes/vampire/traitor_vamp.dm +++ b/code/game/gamemodes/vampire/traitor_vamp.dm @@ -2,12 +2,12 @@ name = "traitor+vampire" config_tag = "traitorvamp" traitors_possible = 3 //hard limit on traitors if scaling is turned off + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Blueshield", "Nanotrasen Representative", "Security Pod Pilot", "Magistrate", "Chaplain", "Brig Physician", "Internal Affairs Agent") restricted_jobs = list("AI", "Cyborg") required_players = 10 required_enemies = 1 // how many of each type are required recommended_enemies = 3 var/protected_species_vampire = list("Machine") - var/special_job_protection = list("Chaplain") //this must exist or else Chaplain can role for Vampire. That said, we don't want to rule out him getting traitor, either /datum/game_mode/traitor/vampire/announce() to_chat(world, "The current game mode is - Traitor+Vampire!") @@ -23,8 +23,6 @@ for(var/mob/new_player/player in player_list) if((player.mind in possible_vampires) && (player.client.prefs.species in protected_species_vampire)) possible_vampires -= player.mind - if((player.mind in possible_vampires) && (player.mind.assigned_role in special_job_protection)) - possible_vampires -= player.mind if(possible_vampires.len > 0) var/datum/mind/vampire = pick(possible_vampires) diff --git a/code/game/gamemodes/vampire/vampire.dm b/code/game/gamemodes/vampire/vampire.dm index 79d644b2132..90e49e64155 100644 --- a/code/game/gamemodes/vampire/vampire.dm +++ b/code/game/gamemodes/vampire/vampire.dm @@ -174,7 +174,7 @@ /datum/game_mode/proc/greet_vampire(var/datum/mind/vampire, var/you_are=1) var/dat if (you_are) - dat = "\red You are a Vampire! \black
" + dat = "You are a Vampire!
" dat += {"To bite someone, target the head and use harm intent with an empty hand. Drink blood to gain new powers. You are weak to holy things and starlight. Don't go into space and avoid the Chaplain, the chapel and especially Holy Water."} to_chat(vampire.current, dat) @@ -351,8 +351,7 @@ You are weak to holy things and starlight. Don't go into space and avoid the Cha vampire_mind.som = null slaved.leave_serv_hud(vampire_mind) update_vampire_icons_removed(vampire_mind) -// to_chat(world, "Removed [vampire_mind.current.name] from vampire shit") - to_chat(vampire_mind.current, "\red The fog clouding your mind clears. You remember nothing from the moment you were enthralled until now.") + vampire_mind.current.visible_message("[vampire_mind.current] looks as though a burden has been lifted!", "The dark fog in your mind clears as you regain control of your own faculties, you are no longer a vampire thrall!") if(vampire_mind.current.hud_used) vampire_mind.current.hud_used.remove_vampire_hud() diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm index bc7ba9276f5..8e04d98504b 100644 --- a/code/game/gamemodes/vampire/vampire_powers.dm +++ b/code/game/gamemodes/vampire/vampire_powers.dm @@ -267,6 +267,10 @@ W.destroy() playsound(usr.loc, 'sound/effects/creepyshriek.ogg', 100, 1) + +/proc/isvampirethrall(mob/living/M as mob) + return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.vampire_enthralled) + /obj/effect/proc_holder/spell/vampire/targetted/enthrall name = "Enthrall (300)" desc = "You use a large portion of your power to sway those loyal to none to be loyal to you only." diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index 32feaede2e1..645f3576edd 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -14,7 +14,7 @@ /datum/game_mode/wizard/raginmages/announce() to_chat(world, "The current game mode is - Ragin' Mages!") - to_chat(world, "The \red Space Wizard Federation\black is pissed, help defeat all the space wizards!") + to_chat(world, "The Space Wizard Federation is pissed, help defeat all the space wizards!") /datum/game_mode/wizard/raginmages/greet_wizard(var/datum/mind/wizard, var/you_are=1) diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm index eb1e8bce930..f2c10d7fc10 100644 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ b/code/game/gamemodes/wizard/rightandwrong.dm @@ -20,7 +20,7 @@ if(!summon_type) switch (randomizeguns) if("taser") - new /obj/item/weapon/gun/energy/advtaser(get_turf(H)) + new /obj/item/weapon/gun/energy/gun/advtaser(get_turf(H)) if("egun") new /obj/item/weapon/gun/energy/gun(get_turf(H)) if("laser") @@ -34,7 +34,7 @@ if("gyrojet") new /obj/item/weapon/gun/projectile/automatic/gyropistol(get_turf(H)) if("pulse") - new /obj/item/weapon/gun/energy/pulse_rifle(get_turf(H)) + new /obj/item/weapon/gun/energy/pulse(get_turf(H)) if("suppressed") new /obj/item/weapon/gun/projectile/automatic/pistol(get_turf(H)) new /obj/item/weapon/suppressor(get_turf(H)) @@ -71,7 +71,7 @@ if("turret") new /obj/item/weapon/gun/energy/gun/turret(get_turf(H)) if("pulsecarbine") - new /obj/item/weapon/gun/energy/pulse_rifle/carbine(get_turf(H)) + new /obj/item/weapon/gun/energy/pulse/carbine(get_turf(H)) if("decloner") new /obj/item/weapon/gun/energy/decloner(get_turf(H)) if("mindflayer") diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 08e6117e9bd..39f59cc654e 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -108,16 +108,16 @@ var/mob/living/carbon/human/T = target var/obj/item/device/soulstone/C = src if(C.imprinted != "empty") - to_chat(U, "\red Capture failed!: \black The soul stone has already been imprinted with [C.imprinted]'s mind!") + to_chat(U, "Capture failed!: The soul stone has already been imprinted with [C.imprinted]'s mind!") else if (T.stat == 0) - to_chat(U, "\red Capture failed!: \black Kill or maim the victim first!") + to_chat(U, "Capture failed!: Kill or maim the victim first!") else if(T.client == null) - to_chat(U, "\red Capture failed!: \black The soul has already fled it's mortal frame.") + to_chat(U, "Capture failed!: The soul has already fled it's mortal frame.") else if(C.contents.len) - to_chat(U, "\red Capture failed!: \black The soul stone is full! Use or free an existing soul to make room.") + to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else for(var/obj/item/W in T) T.unEquip(W) @@ -142,7 +142,7 @@ C.icon_state = "soulstone2" C.name = "Soul Stone: [S.real_name]" to_chat(S, "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs.") - to_chat(U, "\blue Capture successful!: \black [T.real_name]'s soul has been ripped from their body and stored within the soul stone.") + to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from their body and stored within the soul stone.") to_chat(U, "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls.") C.imprinted = "[S.name]" qdel(T) @@ -150,13 +150,13 @@ var/mob/living/simple_animal/shade/T = target var/obj/item/device/soulstone/C = src if (T.stat == DEAD) - to_chat(U, "\red Capture failed!: \black The shade has already been banished!") + to_chat(U, "Capture failed!: The shade has already been banished!") else if(C.contents.len) - to_chat(U, "\red Capture failed!: \black The soul stone is full! Use or free an existing soul to make room.") + to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else if(T.name != C.imprinted) - to_chat(U, "\red Capture failed!: \black The soul stone has already been imprinted with [C.imprinted]'s mind!") + to_chat(U, "Capture failed!: The soul stone has already been imprinted with [C.imprinted]'s mind!") else T.loc = C //put shade in stone T.status_flags |= GODMODE @@ -165,7 +165,7 @@ T.faction |= "\ref[U]" C.icon_state = "soulstone2" to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") - to_chat(U, "\blue Capture successful!: \black [T.name]'s has been recaptured and stored within the soul stone.") + to_chat(U, "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone.") if("CONSTRUCT") var/obj/structure/constructshell/T = target var/obj/item/device/soulstone/C = src @@ -221,7 +221,7 @@ Z.cancel_camera() qdel(C) else - to_chat(U, "\red Creation failed!: \black The soul stone is empty! Go kill someone!") + to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return /proc/makeNewConstruct(var/mob/living/simple_animal/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 8467da489a5..8d3d7cc4278 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -490,14 +490,14 @@ else to_chat(user, "You feed the contract back into the spellbook, refunding your points.") - uses++ + uses+=2 qdel(O) if(istype(O, /obj/item/weapon/antag_spawner/slaughter_demon)) to_chat(user, "On second thought, maybe summoning a demon is a bad idea. You refund your points.") - uses++ + uses+=2 for(var/datum/spellbook_entry/item/bloodbottle/BB in entries) if(!isnull(BB.limit)) BB.limit++ diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 9caa009f2e6..6aa56d91c70 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -14,7 +14,7 @@ /datum/game_mode/wizard/announce() to_chat(world, "The current game mode is - Wizard!") - to_chat(world, "There is a \red SPACE WIZARD\black on the station. You can't let him achieve his objective!") + to_chat(world, "There is a SPACE WIZARD on the station. You can't let him achieve his objective!") /datum/game_mode/wizard/can_start()//This could be better, will likely have to recode it later diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index c7435a29df9..c1ab67a3f03 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -98,6 +98,10 @@ /var/const/access_syndicate_leader = 151//Nuke Op Leader Access /var/const/access_vox = 152//Vox Access +//Trade Stations + +var/const/access_trade_sol = 160 + //MONEY /var/const/access_crate_cash = 200 diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 7427ad57d23..1c736d89609 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -63,7 +63,7 @@ if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back) if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) H.equip_or_collect(new /obj/item/clothing/under/rank/engineer(H), slot_w_uniform) - H.equip_or_collect(new /obj/item/clothing/shoes/orange(H), slot_shoes) + H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) H.equip_or_collect(new /obj/item/clothing/head/hardhat(H), slot_head) H.equip_or_collect(new /obj/item/device/t_scanner(H), slot_r_store) @@ -98,7 +98,7 @@ if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back) if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) H.equip_or_collect(new /obj/item/clothing/under/rank/atmospheric_technician(H), slot_w_uniform) - H.equip_or_collect(new /obj/item/clothing/shoes/black(H), slot_shoes) + H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_or_collect(new /obj/item/device/pda/atmos(H), slot_wear_pda) H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/atmostech/(H), slot_belt) if(H.backbag == 1) @@ -128,7 +128,7 @@ if(3) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel_eng(H), slot_back) if(4) H.equip_or_collect(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) H.equip_or_collect(new /obj/item/clothing/under/rank/mechanic(H), slot_w_uniform) - H.equip_or_collect(new /obj/item/clothing/shoes/orange(H), slot_shoes) + H.equip_or_collect(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_or_collect(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) H.equip_or_collect(new /obj/item/clothing/head/hardhat(H), slot_head) H.equip_or_collect(new /obj/item/device/t_scanner(H), slot_r_store) diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 3b13ceb6b64..31c82b2a203 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -77,7 +77,7 @@ H.equip_or_collect(new /obj/item/clothing/glasses/hud/security/sunglasses(H), slot_glasses) // H.equip_or_collect(new /obj/item/clothing/mask/gas(H), slot_wear_mask) //Grab one from the armory you donk H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) - H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) H.equip_or_collect(new /obj/item/weapon/restraints/handcuffs(H), slot_l_hand) @@ -175,7 +175,7 @@ H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head) H.equip_or_collect(new /obj/item/device/pda/security(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves) - H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store) H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) @@ -249,7 +249,7 @@ H.equip_or_collect(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_or_collect(new /obj/item/device/pda/security(H), slot_wear_pda) H.equip_or_collect(new /obj/item/clothing/gloves/color/black(H), slot_gloves) - H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_s_store) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store) H.equip_or_collect(new /obj/item/device/flash(H), slot_l_store) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) diff --git a/code/game/jobs/job/supervisor.dm b/code/game/jobs/job/supervisor.dm index 2475df770b3..d0281c4b7c1 100644 --- a/code/game/jobs/job/supervisor.dm +++ b/code/game/jobs/job/supervisor.dm @@ -174,10 +174,10 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) if(H.backbag == 1) H.equip_or_collect(new /obj/item/weapon/storage/box/deathimp(H), slot_r_hand) - H.equip_or_collect(new /obj/item/weapon/gun/energy/blueshield(H), slot_l_hand) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/blueshield(H), slot_l_hand) else H.equip_or_collect(new /obj/item/weapon/storage/box/deathimp(H.back), slot_in_backpack) - H.equip_or_collect(new /obj/item/weapon/gun/energy/blueshield(H.back), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/blueshield(H.back), slot_in_backpack) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H) L.imp_in = H L.implanted = 1 @@ -263,4 +263,4 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) L.imp_in = H L.implanted = 1 H.sec_hud_set_implants() - return 1 \ No newline at end of file + return 1 diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm index 210edd98c98..12f01822cde 100644 --- a/code/game/jobs/job/support.dm +++ b/code/game/jobs/job/support.dm @@ -244,6 +244,10 @@ H.equip_or_collect(new /obj/item/toy/crayon/rainbow(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/storage/fancy/crayons(H), slot_in_backpack) H.equip_or_collect(new /obj/item/weapon/reagent_containers/spray/waterflower(H), slot_in_backpack) + if(H.get_species() == "Machine") + var/obj/item/organ/internal/cyberimp/brain/clown_voice/implant + implant = new + implant.insert(H) H.mutations.Add(CLUMSY) H.dna.SetSEState(COMICBLOCK,1,1) genemutcheck(H,COMICBLOCK,null,MUTCHK_FORCED) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 31ad9f145ee..5b796d5770d 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -520,15 +520,17 @@ /obj/machinery/sleeper/proc/go_out() if(filtering) toggle_filter() - if(!src.occupant) + if(!occupant) return - if(src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.forceMove(src.loc) - src.occupant = null + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.forceMove(loc) + occupant = null icon_state = "sleeper-open" - return + // eject trash the occupant dropped + for(var/atom/movable/A in contents - component_parts - list(beaker)) + A.forceMove(loc) /obj/machinery/sleeper/proc/inject_chemical(mob/living/user as mob, chemical, amount) if (!(chemical in injection_chems)) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 897e3ee51c8..67f348a605b 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -157,15 +157,17 @@ add_fingerprint(usr) /obj/machinery/bodyscanner/proc/go_out() - if ((!( src.occupant ) || src.locked)) + if(!occupant || locked) return - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - src.icon_state = "body_scanner_0" - return + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.forceMove(loc) + occupant = null + icon_state = "body_scanner_0" + // eject trash the occupant dropped + for(var/atom/movable/A in contents - component_parts) + A.forceMove(loc) /obj/machinery/bodyscanner/ex_act(severity) switch(severity) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 9021a1a2127..bb278c1e399 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -382,7 +382,7 @@ being_built = new /list() return 0 if(!can_build(D,multiplier)) - visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing terminated.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Not enough resources. Queue processing terminated.\"") queue = list() being_built = new /list() return 0 @@ -392,7 +392,7 @@ D = listgetindex(listgetindex(queue, 1),1) multiplier = listgetindex(listgetindex(queue,1),2) being_built = new /list() - //visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + //visible_message("[bicon(src)] \The [src] beeps, \"Queue processing finished successfully.\"") /obj/machinery/autolathe/proc/main_win(mob/user) var/dat = "" diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 873e08030a7..9aa7cfe2c7b 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -151,6 +151,9 @@ qdel(src) return else if(istype(W, /obj/item/device/analyzer) && panel_open) //XRay + if(!user.unEquip(W)) + to_chat(user, "[W] is stuck!") + return if(!isXRay()) upgradeXRay() qdel(W) @@ -158,14 +161,19 @@ else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/stack/sheet/mineral/plasma) && panel_open) + else if(istype(W, /obj/item/stack/sheet/mineral/plasma) && panel_open) + if(!user.unEquip(W)) + to_chat(user, "[W] is stuck!") + return if(!isEmpProof()) upgradeEmpProof() to_chat(user, "[msg]") qdel(W) else to_chat(user, "[msg2]") - else if(istype(W, /obj/item/device/assembly/prox_sensor) && panel_open) + else if(istype(W, /obj/item/device/assembly/prox_sensor) && panel_open) + if(!user.unEquip(W)) + return if(!isMotion()) upgradeMotion() to_chat(user, "[msg]") diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 5b77c8f00fc..5b7d035d461 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -20,10 +20,9 @@ 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) */ -/obj/item/weapon/camera_assembly/attackby(obj/item/W as obj, mob/living/user as mob, params) +/obj/item/weapon/camera_assembly/attackby(obj/item/W, mob/living/user, params) switch(state) - if(0) // State 0 if(iswrench(W) && isturf(src.loc)) @@ -116,7 +115,6 @@ return else if(iswirecutter(W)) - new/obj/item/stack/cable_coil(get_turf(src), 2) playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1) to_chat(user, "You cut the wires from the circuits.") @@ -125,9 +123,12 @@ // 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!") + return to_chat(user, "You attach \the [W] into the assembly inner circuits.") upgrades += W - user.drop_item(W) + user.drop_item() W.loc = src return diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 1f8bbc44587..1a7fffcc6ea 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -4,6 +4,7 @@ //Potential replacement for genetics revives or something I dunno (?) #define CLONE_BIOMASS 150 +#define BIOMASS_MEAT_AMOUNT 50 /obj/machinery/clonepod anchored = 1 @@ -292,6 +293,13 @@ //Grow clones to maturity then kick them out. FREELOADERS /obj/machinery/clonepod/process() + var/show_message = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/meat/meat in range(1, src)) + qdel(meat) + biomass += BIOMASS_MEAT_AMOUNT + show_message = 1 + if(show_message) + visible_message("\The [src] sucks in and processes the nearby biomass.") if(stat & NOPOWER) //Autoeject if power is lost if (occupant) @@ -373,7 +381,7 @@ //Removing cloning pod biomass else if (istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) to_chat(user, "\blue \The [src] processes \the [W].") - biomass += 50 + biomass += BIOMASS_MEAT_AMOUNT user.drop_item() qdel(W) return diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 90b415c99bf..73779c170e0 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -273,6 +273,17 @@ src.emagged = 0 setMenuState(usr,COMM_SCREEN_MAIN) + if("AcceptDocking") + to_chat(usr, "Docking request accepted!") + trade_dock_timelimit = world.time + 1200 + trade_dockrequest_timelimit = 0 + command_announcement.Announce("Docking request for trading ship approved, please dock at port bay 4.", "Docking Request") + if("DenyDocking") + to_chat(usr, "Docking requeset denied!") + trade_dock_timelimit = 0 + trade_dockrequest_timelimit = 0 + command_announcement.Announce("Docking request for trading ship denied.", "Docking request") + nanomanager.update_uis(src) return 1 @@ -358,6 +369,11 @@ data["shuttle"] = shuttle + if(trade_dockrequest_timelimit > world.time) + data["dock_request"] = 1 + else + data["dock_request"] = 0 + // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) if (!ui) diff --git a/code/game/machinery/computer/honkputer.dm b/code/game/machinery/computer/honkputer.dm index 8ccd36fc780..03e66710fd7 100644 --- a/code/game/machinery/computer/honkputer.dm +++ b/code/game/machinery/computer/honkputer.dm @@ -21,7 +21,7 @@ if(..()) return 1 if (!(src.z in config.station_levels)) - to_chat(usr, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") return usr.set_machine(src) @@ -69,7 +69,7 @@ if(..()) return if (src.z > 6) - to_chat(user, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(user, "Unable to establish a connection: You're too far away from the station!") return user.set_machine(src) diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index c84690cfa64..2f7cfad49b9 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -30,7 +30,7 @@ attackby(obj/item/weapon/O as obj, mob/user as mob, params) if (user.z > 6) - to_chat(user, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(user, "Unable to establish a connection: You're too far away from the station!") return if(istype(O, /obj/item/weapon/aiModule)) var/datum/game_mode/nations/mode = get_nations_mode() diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 2a074a9880b..6f285930ab7 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -42,7 +42,7 @@ if(..()) return if (src.z > 6) - to_chat(user, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(user, "Unable to establish a connection: You're too far away from the station!") return var/dat diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index d2f44de6011..ddcfeed9a74 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -41,7 +41,7 @@ if(..()) return if (src.z > 6) - to_chat(user, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(user, "Unable to establish a connection: You're too far away from the station!") return var/dat diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 6a1f0721253..e469f389ff3 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -411,9 +411,9 @@ air_update_turf() /obj/machinery/atmospherics/unary/cryo_cell/proc/go_out() - if(!( occupant )) + if(!occupant) return - if (occupant.client) + if(occupant.client) occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE occupant.forceMove(get_step(loc, SOUTH)) //this doesn't account for walls or anything, but i don't forsee that being a problem. @@ -421,7 +421,10 @@ occupant.bodytemperature = 261 occupant = null update_icon() - return + // eject trash the occupant dropped + for(var/atom/movable/A in contents - component_parts - list(beaker)) + A.forceMove(get_step(loc, SOUTH)) + /obj/machinery/atmospherics/unary/cryo_cell/proc/put_mob(mob/living/carbon/M as mob) if (!istype(M)) to_chat(usr, "\red The cryo cell cannot handle such a lifeform!") diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 68ff1bf64c1..f7de2dd6b5f 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -28,17 +28,6 @@ var/storage_name = "Cryogenic Oversight Control" var/allow_items = 1 -/obj/machinery/computer/cryopod/robot - name = "robotic storage console" - desc = "An interface between crew and the robotic storage systems" - icon = 'icons/obj/robot_storage.dmi' - icon_state = "console" - circuit = /obj/item/weapon/circuitboard/robotstoragecontrol - - storage_type = "cyborgs" - storage_name = "Robotic Storage Control" - allow_items = 0 - /obj/machinery/computer/cryopod/attack_ai() src.attack_hand() @@ -146,7 +135,6 @@ //Decorative structures to go alongside cryopods. /obj/structure/cryofeed - name = "cryogenic feed" desc = "A bewildering tangle of machinery and pipes." icon = 'icons/obj/Cryogenic2.dmi' @@ -218,23 +206,6 @@ orient_right = 1 icon_state = "body_scanner_0-r" -/obj/machinery/cryopod/robot - name = "robotic storage unit" - desc = "A storage unit for robots." - icon = 'icons/obj/robot_storage.dmi' - icon_state = "pod_0" - base_icon_state = "pod_0" - occupied_icon_state = "pod_1" - on_store_message = "has entered robotic storage." - on_store_name = "Robotic Storage Oversight" - on_enter_occupant_message = "The storage unit broadcasts a sleep signal to you. Your systems start to shut down, and you enter low-power mode." - allow_occupant_types = list(/mob/living/silicon/robot) - disallow_occupant_types = list(/mob/living/silicon/robot/drone) - -/obj/machinery/cryopod/robot/right - orient_right = 1 - icon_state = "pod_0-r" - /obj/machinery/cryopod/New() announce = new /obj/item/device/radio/intercom(src) @@ -296,22 +267,6 @@ despawn_occupant() -// This function can not be undone; do not call this unless you are sure -// Also make sure there is a valid control computer -/obj/machinery/cryopod/robot/despawn_occupant() - var/mob/living/silicon/robot/R = occupant - if(!istype(R)) return ..() - - R.contents -= R.mmi - qdel(R.mmi) - for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc - for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags - O.loc = R - qdel(I) - qdel(R.module) - - return ..() - // This function can not be undone; do not call this unless you are sure // Also make sure there is a valid control computer /obj/machinery/cryopod/proc/despawn_occupant() @@ -406,11 +361,6 @@ else icon_state = base_icon_state - //TODO: Check objectives/mode, update new targets if this mob is the target, spawn new antags? - - //This should guarantee that ghosts don't spawn. - occupant.ckey = null - //Make an announcement and log the person entering storage. control_computer.frozen_crew += "[occupant.real_name]" @@ -682,7 +632,6 @@ return /obj/machinery/cryopod/proc/go_out() - if(!occupant) return @@ -704,3 +653,45 @@ //Attacks/effects. /obj/machinery/cryopod/blob_act() return //Sorta gamey, but we don't really want these to be destroyed. + +/obj/machinery/computer/cryopod/robot + name = "robotic storage console" + desc = "An interface between crew and the robotic storage systems" + icon = 'icons/obj/robot_storage.dmi' + icon_state = "console" + circuit = /obj/item/weapon/circuitboard/robotstoragecontrol + + storage_type = "cyborgs" + storage_name = "Robotic Storage Control" + allow_items = 0 + +/obj/machinery/cryopod/robot + name = "robotic storage unit" + desc = "A storage unit for robots." + icon = 'icons/obj/robot_storage.dmi' + icon_state = "pod_0" + base_icon_state = "pod_0" + occupied_icon_state = "pod_1" + on_store_message = "has entered robotic storage." + on_store_name = "Robotic Storage Oversight" + on_enter_occupant_message = "The storage unit broadcasts a sleep signal to you. Your systems start to shut down, and you enter low-power mode." + allow_occupant_types = list(/mob/living/silicon/robot) + disallow_occupant_types = list(/mob/living/silicon/robot/drone) + +/obj/machinery/cryopod/robot/right + orient_right = 1 + icon_state = "pod_0-r" + +/obj/machinery/cryopod/robot/despawn_occupant() + var/mob/living/silicon/robot/R = occupant + if(!istype(R)) return ..() + + R.contents -= R.mmi + qdel(R.mmi) + for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc + for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags + O.loc = R + qdel(I) + qdel(R.module) + + return ..() diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index c8e16257858..ba0006f16de 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -100,9 +100,9 @@ var/const/HOLOPAD_MODE = 0 create_holo(user)//Create one. src.visible_message("A holographic image of [user] flicks to life right before your eyes!") else - to_chat(user, "\red ERROR: \black Image feed in progress.") + to_chat(user, "ERROR: Image feed in progress.") else - to_chat(user, "\red ERROR: \black Unable to project hologram.") + to_chat(user, "ERROR: Unable to project hologram.") return /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. @@ -123,7 +123,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ rendered = "Holopad received, [name_used] [verb], \"[text]\"" master.show_message(rendered, 2) return - + /obj/machinery/hologram/holopad/hear_message(mob/living/M, text) if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something. var/name_used = M.GetVoice() diff --git a/code/game/machinery/kitchen/icecream_vat.dm b/code/game/machinery/kitchen/icecream_vat.dm index a5e1cc1eafb..07dfeb6f29c 100644 --- a/code/game/machinery/kitchen/icecream_vat.dm +++ b/code/game/machinery/kitchen/icecream_vat.dm @@ -97,7 +97,7 @@ var/list/ingredients_source = list( if(ingredients[ICECREAM_VANILLA] > 0) var/flavour_name = get_icecream_flavour_string(dispense_flavour) if(dispense_flavour < 11 && ingredients[dispense_flavour] > 0) - src.visible_message("\icon[src] [user] scoops delicious [flavour_name] flavoured icecream into [I].") + src.visible_message("[bicon(src)] [user] scoops delicious [flavour_name] flavoured icecream into [I].") ingredients[dispense_flavour] -= 1 ingredients[ICECREAM_VANILLA] -= 1 diff --git a/code/game/machinery/kitchen/processor.dm b/code/game/machinery/kitchen/processor.dm index 57e1aecf514..881c0536803 100644 --- a/code/game/machinery/kitchen/processor.dm +++ b/code/game/machinery/kitchen/processor.dm @@ -29,6 +29,28 @@ for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) rating_speed = M.rating +/obj/machinery/processor/process() + ..() + // The irony + // To be clear, if it's grinding, then it can't suck them up + if(processing) + return + var/mob/living/carbon/slime/picked_slime + for(var/mob/living/carbon/slime/slime in range(1, src)) + if(slime.loc == src) + continue + if(slime.stat) + picked_slime = slime + break + if(!picked_slime) + return + var/datum/food_processor_process/P = select_recipe(picked_slime) + if (!P) + return + + visible_message("[picked_slime] is sucked into \the [src].") + picked_slime.forceMove(src) + //RECIPE DATUMS /datum/food_processor_process var/input diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 5ad3ba4a048..f19e37f051a 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -420,7 +420,7 @@ Class Procs: /obj/machinery/proc/state(var/msg) for(var/mob/O in hearers(src, null)) - O.show_message("\icon[src] [msg]", 2) + O.show_message("[bicon(src)] [msg]", 2) /obj/machinery/proc/ping(text=null) if (!text) @@ -465,7 +465,7 @@ Class Procs: /obj/machinery/proc/display_parts(mob/user) to_chat(user, "Following parts detected in the machine:") for(var/obj/item/C in component_parts) - to_chat(user, "\icon[C] [C.name]") + to_chat(user, "[bicon(C)] [C.name]") /obj/machinery/examine(mob/user) ..(user) diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 2b56b71fc43..734bb09f60b 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -151,7 +151,7 @@ var/icon/I2 = imap[2+(ix + icx*iy)*2] -// to_chat(world, "icon: \icon[I]") +// to_chat(world, "icon: [bicon(I)]") I.DrawBox(colour, rx, ry, rx+1, ry+1) @@ -168,7 +168,7 @@ H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]" -// to_chat(world, "\icon[I] at [H.screen_loc]") +// to_chat(world, "[bicon(I)] at [H.screen_loc]") H.name = (i==0)?"maprefresh":"map" @@ -184,6 +184,7 @@ qdel(J) H.icon = HI H.layer = 25 + H.plane = HUD_PLANE usr.mapobjs += H #else @@ -284,7 +285,7 @@ var/icon/I = imap[1+(ix + icx*iy)] -// to_chat(world, "icon: \icon[I]") +// to_chat(world, "icon: [bicon(I)]") I.DrawBox(colour, rx, ry, rx, ry) @@ -299,7 +300,7 @@ H.screen_loc = "[5 + i%icx],[6+ round(i/icx)]" -// to_chat(world, "\icon[I] at [H.screen_loc]") +// to_chat(world, "[bicon(I)] at [H.screen_loc]") H.name = (i==0)?"maprefresh":"map" @@ -308,6 +309,7 @@ H.icon = I qdel(I) H.layer = 25 + H.plane = HUD_PLANE usr.mapobjs += H #endif diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index eab12bb22d5..fb1ef8c8740 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -99,13 +99,12 @@ one_access = 0 /obj/machinery/porta_turret/proc/setup() - var/obj/item/weapon/gun/energy/E = installation //All energy-based weapons are applicable - if(istext(installation)) E = text2path(installation) - //var/obj/item/ammo_casing/shottype = E.projectile_type + var/obj/item/weapon/gun/energy/E= new installation //All energy-based weapons are applicable + var/obj/item/ammo_casing/shottype = E.ammo_type[1] - projectile = initial(E.projectile_type) + projectile = shottype.projectile_type eprojectile = projectile - shot_sound = initial(E.fire_sound) + shot_sound = shottype.fire_sound eshot_sound = shot_sound weapon_setup(installation) @@ -561,9 +560,6 @@ var/list/turret_icons if(get_dist(src, L) > 7) //if it's too far away, why bother? return TURRET_NOT_TARGET - if(!check_trajectory(L, src)) //check if we have true line of sight - return TURRET_NOT_TARGET - if(emagged) // If emagged not even the dead get a rest return L.stat ? TURRET_SECONDARY_TARGET : TURRET_PRIORITY_TARGET @@ -670,6 +666,8 @@ var/list/turret_icons return /obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) + if(!raised) //the turret has to be raised in order to fire - makes sense, right? + return //any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power! if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate if(last_fired || !raised) //prevents rapid-fire shooting, unless it's been emagged @@ -684,10 +682,6 @@ var/list/turret_icons if(!istype(T) || !istype(U)) return - if(!raised) //the turret has to be raised in order to fire - makes sense, right? - return - - update_icon() var/obj/item/projectile/A if(emagged || lethal) @@ -698,18 +692,17 @@ var/list/turret_icons if(projectile) A = new projectile(loc) playsound(loc, shot_sound, 75, 1) - A.original = target // Lethal/emagged turrets use twice the power due to higher energy beams // Emagged turrets again use twice as much power due to higher firing rates use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged)) - //Shooting Code: + A.original = target A.current = T A.yo = U.y - T.y A.xo = U.x - T.x - spawn(1) - A.process() + A.fire() + return A /datum/turret_checks var/enabled diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 92bca16c5b7..a1559c4fb3a 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -203,7 +203,8 @@ if(istype(O,/obj/item/weapon/gun/energy/disabler/cyborg)) var/obj/item/weapon/gun/energy/disabler/cyborg/D = O if(D.power_supply.charge < D.power_supply.maxcharge) - D.power_supply.give(D.charge_cost) + var/obj/item/ammo_casing/energy/E = D.ammo_type[D.select] + D.power_supply.give(E.e_cost) D.update_icon() else D.charge_tick = 0 diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 9bcf3de53a8..2db551b67fa 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -129,7 +129,7 @@ var/const/SAFETY_COOLDOWN = 100 return if(sound) - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) + playsound(src.loc, 'sound/machines/recycler.ogg', 100, 0) var/material_amount = materials.get_item_material_amount(I) if(!material_amount) qdel(I) @@ -155,7 +155,7 @@ var/const/SAFETY_COOLDOWN = 100 L.loc = src.loc if(issilicon(L)) - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) + playsound(src.loc, 'sound/machines/recycler.ogg', 100, 0) else playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) @@ -219,4 +219,4 @@ var/const/SAFETY_COOLDOWN = 100 /obj/item/weapon/paper/recycler name = "paper - 'garbage duty instructions'" - info = "

New Assignment

You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" \ No newline at end of file + info = "

New Assignment

You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index bfd4939dc3b..11079d06606 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -180,7 +180,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() screen = RCS_SENTPASS message_log += "Message sent to [recipient]
[message]" else - audible_message(text("\icon[src] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) + audible_message(text("[bicon(src)] *The Requests Console beeps: 'NOTICE: No server detected!'"),,4) //Handle screen switching if(href_list["setScreen"]) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 323937075ad..f402551c842 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -215,14 +215,14 @@ return if (src.active) - user.visible_message("\blue \icon[src] [user] deactivated the shield generator.", \ - "\blue \icon[src] You deactivate the shield generator.", \ + user.visible_message("\blue [bicon(src)] [user] deactivated the shield generator.", \ + "\blue [bicon(src)] You deactivate the shield generator.", \ "You hear heavy droning fade out.") src.shields_down() else if(anchored) - user.visible_message("\blue \icon[src] [user] activated the shield generator.", \ - "\blue \icon[src] You activate the shield generator.", \ + user.visible_message("\blue [bicon(src)] [user] activated the shield generator.", \ + "\blue [bicon(src)] You activate the shield generator.", \ "You hear heavy droning.") src.shields_up() else diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index fe443662616..a2b6417c9f7 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -10,7 +10,7 @@ unacidable = 1 var/datum/wires/syndicatebomb/wires = null - var/timer = 60 + var/timer = 120 var/open_panel = 0 //are the wires exposed? var/active = 0 //is the bomb counting down? var/defused = 0 //is the bomb capable of exploding? @@ -19,12 +19,12 @@ /obj/machinery/syndicatebomb/process() if(active && !defused && (timer > 0)) //Tick Tock - var/volume = (timer <= 10 ? 40 : 10) // Tick louder when the bomb is closer to being detonated. + var/volume = (timer <= 20 ? 40 : 10) // Tick louder when the bomb is closer to being detonated. playsound(loc, beepsound, volume, 0) - timer-- + timer = max(timer - 2,0) // 2 seconds per process() if(active && !defused && (timer <= 0)) //Boom active = 0 - timer = 60 + timer = 120 update_icon() if(payload in src) payload.detonate() @@ -123,17 +123,17 @@ /obj/machinery/syndicatebomb/proc/settings(var/mob/user) var/newtime = input(user, "Please set the timer.", "Timer", "[timer]") as num - newtime = Clamp(newtime, 60, 60000) + newtime = Clamp(newtime, 120, 60000) if(in_range(src, user) && isliving(user)) //No running off and setting bombs from across the station timer = newtime - src.loc.visible_message("\icon[src] timer set for [timer] seconds.") + src.loc.visible_message("[bicon(src)] timer set for [timer] seconds.") if(alert(user,"Would you like to start the countdown now?",,"Yes","No") == "Yes" && in_range(src, user) && isliving(user)) if(defused || active) if(defused) - src.loc.visible_message("\icon[src] Device error: User intervention required.") + src.loc.visible_message("[bicon(src)] Device error: User intervention required.") return else - src.loc.visible_message("\icon[src] [timer] seconds until detonation, please clear the area.") + src.loc.visible_message("[bicon(src)] [timer] seconds until detonation, please clear the area.") playsound(loc, 'sound/machines/click.ogg', 30, 1) active = 1 update_icon() @@ -223,7 +223,7 @@ var/obj/machinery/syndicatebomb/holder = src.loc if(istype(holder)) attempts++ - holder.loc.visible_message("\icon[holder] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...") + holder.loc.visible_message("[bicon(holder)] Alert: Bomb has detonated. Your score is now [defusals] for [attempts]. Resetting wires...") reset() else qdel(src) @@ -233,7 +233,7 @@ if(istype(holder)) attempts++ defusals++ - holder.loc.visible_message("\icon[holder] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...") + holder.loc.visible_message("[bicon(holder)] Alert: Bomb has been defused. Your score is now [defusals] for [attempts]! Resetting wires in 5 seconds...") sleep(50) //Just in case someone is trying to remove the bomb core this gives them a little window to crowbar it out if(istype(holder)) reset() diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm index 5d6aa95b56f..661744502ed 100644 --- a/code/game/machinery/telecomms/broadcaster.dm +++ b/code/game/machinery/telecomms/broadcaster.dm @@ -333,7 +333,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept var/part_b_extra = "" if(data == 3) // intercepted radio message part_b_extra = " (Intercepted)" - var/part_a = "\icon[radio]\[[freq_text]\][part_b_extra] " // goes in the actual output + var/part_a = "[bicon(radio)]\[[freq_text]\][part_b_extra] " // goes in the actual output // --- Some more pre-message formatting --- var/part_b = " " // Tweaked for security headsets -- TLE @@ -528,7 +528,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept // Create a radio headset for the sole purpose of using its icon var/obj/item/device/radio/headset/radio = new - var/part_b = " \icon[radio]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE + var/part_b = " [bicon(radio)]\[[freq_text]\][part_b_extra] " // Tweaked for security headsets -- TLE var/part_blackbox_b = " \[[freq_text]\] " var/part_c = "" diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 9d9481aba04..290e3352ea8 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -387,7 +387,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list() src.receive_information(signal, src) // Try sending it! - var/list/try_send = list("/obj/machinery/telecomms/server", "/obj/machinery/telecomms/hub", "/obj/machinery/telecomms/broadcaster", "/obj/machinery/telecomms/bus") + var/list/try_send = list("/obj/machinery/telecomms/server", "/obj/machinery/telecomms/hub", "/obj/machinery/telecomms/broadcaster") var/i = 0 for(var/send in try_send) if(i) diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 82060d47bc2..f0b6ce34ef7 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -227,15 +227,15 @@ if(1) A = new /obj/item/projectile/beam(loc) if(2) - A = new /obj/item/projectile/beam/heavylaser(loc) + A = new /obj/item/projectile/beam/laser/heavylaser(loc) if(3) A = new /obj/item/projectile/beam/pulse(loc) if(4) A = new /obj/item/projectile/magic/change(loc) if(5) - A = new /obj/item/projectile/lasertag/blue(loc) + A = new /obj/item/projectile/beam/lasertag/bluetag(loc) if(6) - A = new /obj/item/projectile/lasertag/red(loc) + A = new /obj/item/projectile/beam/lasertag/redtag(loc) A.original = target use_power(500) else @@ -248,8 +248,7 @@ A.current = T A.yo = U.y - T.y A.xo = U.x - T.x - spawn( 0 ) - A.process() + A.fire() return diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 29880e519ec..5d9533470d6 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -296,7 +296,7 @@ if(currently_vending.price > cashmoney.get_total()) // This is not a status display message, since it's something the character // themselves is meant to see BEFORE putting the money in - to_chat(usr, "\icon[cashmoney] That is not enough money.") + to_chat(usr, "[bicon(cashmoney)] That is not enough money.") return 0 // Bills (banknotes) cannot really have worth different than face value, @@ -849,7 +849,7 @@ product_ads = "Float like an astronaut, sting like a bullet!;Express your second amendment today!;Guns don't kill people, but you can!;Who needs responsibilities when you have guns?" vend_reply = "Remember the name: Liberation Station!" products = list(/obj/item/weapon/gun/projectile/automatic/pistol/deagle/gold = 2,/obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo = 2, - /obj/item/weapon/gun/projectile/automatic/pistol/m2411 = 2,/obj/item/weapon/gun/projectile/automatic/proto = 2, + /obj/item/weapon/gun/projectile/automatic/pistol/m1911 = 2,/obj/item/weapon/gun/projectile/automatic/proto = 2, /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1, /obj/item/weapon/gun/projectile/shotgun = 2,/obj/item/weapon/gun/projectile/automatic/ar = 2) premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2,/obj/item/ammo_box/magazine/m50 = 4,/obj/item/ammo_box/magazine/m45 = 2,/obj/item/ammo_box/magazine/m75 = 2) @@ -1114,7 +1114,7 @@ icon_state = "engi" icon_deny = "engi-deny" req_access_txt = "11" - products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, + products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/workboots = 4,/obj/item/clothing/head/hardhat = 4, /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/color/yellow = 4, /obj/item/weapon/screwdriver = 12, /obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12, /obj/item/stack/cable_coil/heavyduty = 8, /obj/item/weapon/stock_parts/cell = 8, /obj/item/weapon/weldingtool = 8,/obj/item/clothing/head/welding = 8, @@ -1152,7 +1152,7 @@ icon_state = "sustenance" products = list(/obj/item/weapon/reagent_containers/food/snacks/tofu = 24, /obj/item/weapon/reagent_containers/food/drinks/ice = 12, - /obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6) + /obj/item/weapon/reagent_containers/food/snacks/candy/candy_corn = 6) contraband = list(/obj/item/weapon/kitchen/knife = 6) /obj/machinery/vending/hatdispenser diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 1967f1e6645..b7aeaed66cc 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -133,7 +133,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message) if(chassis) - chassis.occupant_message("\icon[src] [message]") + chassis.occupant_message("[bicon(src)] [message]") return /obj/item/mecha_parts/mecha_equipment/proc/log_message(message) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index f79c43068ee..05b3dac0e63 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -384,7 +384,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun name = "Syringe Gun" desc = "Exosuit-mounted chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur. (Can be attached to: Medical Exosuits)" - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/projectile.dmi' icon_state = "syringegun" item_state = "syringegun" lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' @@ -666,4 +666,4 @@ for(var/reagent in S.processed_reagents) S.reagents.add_reagent(reagent,amount) S.chassis.use_power(energy_drain) - return 1 \ No newline at end of file + return 1 diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index d95cbaff799..ae5595d69e5 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -5,6 +5,10 @@ var/projectile var/fire_sound var/size=0 + var/projectiles_per_shot = 1 + var/variance = 0 + var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter + var/projectile_delay = 0 /obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M as obj) if(..()) @@ -16,32 +20,51 @@ return 1 return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount() + return projectiles_per_shot -/obj/item/mecha_parts/mecha_equipment/weapon/energy - name = "General Energy Weapon" - size = 2 - action(target) - if(!action_checks(target)) return - var/turf/curloc = chassis.loc - var/atom/targloc = get_turf(target) - if (!targloc || !istype(targloc, /turf) || !curloc) - return - if (targloc == curloc) - return - set_ready_state(0) - playsound(chassis, fire_sound, 50, 1) +/obj/item/mecha_parts/mecha_equipment/weapon/action(target, params) + if(!action_checks(target)) + return 0 + + var/turf/curloc = get_turf(chassis) + var/turf/targloc = get_turf(target) + if (!targloc || !istype(targloc) || !curloc) + return 0 + if (targloc == curloc) + return 0 + + set_ready_state(0) + for(var/i=1 to get_shot_amount()) var/obj/item/projectile/A = new projectile(curloc) A.firer = chassis.occupant A.original = target A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - chassis.use_power(energy_drain) - A.process() - chassis.log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() - return + var/spread = 0 + if(variance) + if(randomspread) + spread = round((rand() - 0.5) * variance) + else + spread = round((i / projectiles_per_shot - 0.5) * variance) + A.preparePixelProjectile(target, targloc, chassis.occupant, params, spread) + + chassis.use_power(energy_drain) + A.fire() + playsound(chassis, fire_sound, 50, 1) + + sleep(max(0, projectile_delay)) + set_ready_state(0) + log_message("Fired from [name], targeting [target].") + var/turf/T = get_turf(src) + msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)") + log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") + do_after_cooldown() + return + +/obj/item/mecha_parts/mecha_equipment/weapon/energy + name = "General Energy Weapon" + size = 2 /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser equip_cooldown = 8 @@ -56,7 +79,7 @@ name = "CH-LC \"Solaris\" Laser Cannon" icon_state = "mecha_laser" energy_drain = 40 - projectile = /obj/item/projectile/beam/heavylaser + projectile = /obj/item/projectile/beam/laser/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion @@ -82,25 +105,25 @@ icon_state = "pulse1_bl" var/life = 20 - Bump(atom/A) - A.bullet_act(src, def_zone) - src.life -= 10 - if(ismob(A)) - var/mob/M = A - if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" - firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" - log_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src]") - if(!iscarbon(firer)) - M.LAssailant = null - else - M.LAssailant = firer +/obj/item/projectile/beam/pulse/heavy/Bump(atom/A) + A.bullet_act(src, def_zone) + life -= 10 + if(ismob(A)) + var/mob/M = A + if(istype(firer, /mob)) + M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" + firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src]" + log_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src]") + if(!iscarbon(firer)) + M.LAssailant = null else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" - log_attack("UNKNOWN shot [M] ([M.ckey]) with a [src]") - if(life <= 0) - qdel(src) - return + M.LAssailant = firer + else + M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" + log_attack("UNKNOWN shot [M] ([M.ckey]) with a [src]") + if(life <= 0) + qdel(src) + return /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser @@ -119,89 +142,89 @@ equip_cooldown = 150 range = MELEE|RANGED - can_attach(obj/mecha/combat/honker/M as obj) - if(..()) - if(istype(M)) - return 1 +/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params) + if(!chassis) + return 0 + if(energy_drain && chassis.get_charge() < energy_drain) + return 0 + if(!equip_ready) return 0 - action(target) - if(!chassis) - return 0 - if(energy_drain && chassis.get_charge() < energy_drain) - return 0 - if(!equip_ready) - return 0 + playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1) + chassis.occupant_message("HONK") + for(var/mob/living/carbon/M in ohearers(6, chassis)) + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) + continue + to_chat(M, "HONK") + M.sleeping = 0 + M.stuttering = 20 + M.ear_deaf = 30 + M.Weaken(3) + if(prob(30)) + M.Stun(10) + M.Paralyse(4) + else + M.Jitter(500) + ///else the mousetraps are useless + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(isobj(H.shoes)) + var/thingy = H.shoes + H.unEquip(H.shoes) + walk_away(thingy,chassis,15,2) + spawn(20) + if(thingy) + walk(thingy,0) + for(var/obj/mecha/combat/recitence/R in oview(6, chassis)) + R.occupant_message("\The [R] has protected you from [chassis]'s HONK at the cost of some power.") + R.use_power(R.get_charge() / 4) - playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1) - chassis.occupant_message("HONK") - for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) - continue - to_chat(M, "HONK") - M.sleeping = 0 - M.stuttering = 20 - M.ear_deaf = 30 - M.Weaken(3) - if(prob(30)) - M.Stun(10) - M.Paralyse(4) - else - M.Jitter(500) - ///else the mousetraps are useless - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(isobj(H.shoes)) - var/thingy = H.shoes - H.unEquip(H.shoes) - walk_away(thingy,chassis,15,2) - spawn(20) - if(thingy) - walk(thingy,0) - for(var/obj/mecha/combat/recitence/R in oview(6, chassis)) - R.occupant_message("\The [R] has protected you from [chassis]'s HONK at the cost of some power.") - R.use_power(R.get_charge() / 4) - - chassis.use_power(energy_drain) - log_message("Honked from [src.name]. HONK!") - var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - JMP)") - log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]") - do_after_cooldown() - return + chassis.use_power(energy_drain) + log_message("Honked from [name]. HONK!") + var/turf/T = get_turf(src) + msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - JMP)") + log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "General Ballisic Weapon" var/projectiles var/projectile_energy_cost size = 2 - action_checks(atom/target) - if(..()) - if(projectiles > 0) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(atom/target) + if(..()) + if(projectiles > 0) + return 1 + return 0 - get_equip_info() - return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]" +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() + return "[..()]\[[projectiles]\][(projectiles < initial(projectiles))?" - Rearm":null]" - proc/rearm() - if(projectiles < initial(projectiles)) - var/projectiles_to_add = initial(projectiles) - projectiles - while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add) - projectiles++ - projectiles_to_add-- - chassis.use_power(projectile_energy_cost) - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - log_message("Rearmed [src.name].") - return +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/proc/rearm() + if(projectiles < initial(projectiles)) + var/projectiles_to_add = initial(projectiles) - projectiles + while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add) + projectiles++ + projectiles_to_add-- + chassis.use_power(projectile_energy_cost) + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) + log_message("Rearmed [name].") + return - Topic(href, href_list) - ..() - if (href_list["rearm"]) - src.rearm() - return +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list) + ..() + if (href_list["rearm"]) + rearm() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine name = "FNX-66 Carbine" @@ -211,41 +234,6 @@ fire_sound = 'sound/weapons/Gunshot.ogg' projectiles = 24 projectile_energy_cost = 15 - var/projectiles_per_shot = 1 - var/deviation = 0.0 - - action(atom/target) - if(!action_checks(target)) return - var/turf/targloc = get_turf(target) - var/target_x = targloc.x - var/target_y = targloc.y - var/target_z = targloc.z - targloc = null - spawn for(var/i=1 to min(projectiles, projectiles_per_shot)) - if(!chassis) break - var/turf/curloc = get_turf(chassis) - targloc = locate(target_x+GaussRandRound(deviation,1),target_y+GaussRandRound(deviation,1),target_z) - if (!targloc || !curloc) - continue - if (targloc == curloc) - continue - - playsound(chassis, fire_sound, 50, 1) - var/obj/item/projectile/A = new projectile(curloc) - src.projectiles-- - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - A.process() - sleep(2) - set_ready_state(0) - log_message("Fired from [src.name], targeting [target].") - var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)") - log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") - do_after_cooldown() - return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine/silenced name = "\improper S.H.H. \"Quietus\" Carbine" @@ -270,36 +258,8 @@ fire_sound = 'sound/weapons/Gunshot.ogg' projectiles = 40 projectile_energy_cost = 25 - var/projectiles_per_shot = 4 - var/deviation = 0.7 - - action(atom/target) - if(!action_checks(target)) return - var/turf/curloc = get_turf(chassis) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) return - var/target_x = targloc.x - var/target_y = targloc.y - var/target_z = targloc.z - targloc = null - for(var/i=1 to min(projectiles, projectiles_per_shot)) - targloc = locate(target_x+GaussRandRound(deviation,1),target_y+GaussRandRound(deviation,1),target_z) - if(!targloc || targloc == curloc) - break - playsound(chassis, fire_sound, 80, 1) - var/obj/item/projectile/A = new projectile(curloc) - src.projectiles-- - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - set_ready_state(0) - A.process() - log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() - return - - + projectiles_per_shot = 4 + variance = 25 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg name = "Ultra AC 2" @@ -309,38 +269,9 @@ fire_sound = 'sound/weapons/Gunshot.ogg' projectiles = 300 projectile_energy_cost = 20 - var/projectiles_per_shot = 3 - var/deviation = 0.3 - - action(atom/target) - if(!action_checks(target)) return - var/turf/targloc = get_turf(target) - var/target_x = targloc.x - var/target_y = targloc.y - var/target_z = targloc.z - targloc = null - spawn for(var/i=1 to min(projectiles, projectiles_per_shot)) - if(!chassis) break - var/turf/curloc = get_turf(chassis) - targloc = locate(target_x+GaussRandRound(deviation,1),target_y+GaussRandRound(deviation,1),target_z) - if (!targloc || !curloc) - continue - if (targloc == curloc) - continue - - playsound(chassis, fire_sound, 50, 1) - var/obj/item/projectile/A = new projectile(curloc) - src.projectiles-- - A.original = target - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - A.process() - sleep(2) - set_ready_state(0) - log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() - return + projectiles_per_shot = 3 + variance = 6 + projectile_delay = 2 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack name = "SRM-8 Missile Rack" @@ -353,20 +284,21 @@ var/missile_speed = 2 var/missile_range = 30 - action(target) - if(!action_checks(target)) return - set_ready_state(0) - var/obj/item/missile/M = new projectile(chassis.loc) - M.primed = 1 - playsound(chassis, fire_sound, 50, 1) - M.throw_at(target, missile_range, missile_speed, chassis) - projectiles-- - log_message("Fired from [src.name], targeting [target].") - var/turf/T = get_turf(src) - msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)") - log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") - do_after_cooldown() +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/action(target, params) + if(!action_checks(target)) return + set_ready_state(0) + var/obj/item/missile/M = new projectile(chassis.loc) + M.primed = 1 + playsound(chassis, fire_sound, 50, 1) + M.throw_at(target, missile_range, missile_speed, chassis) + projectiles-- + log_message("Fired from [name], targeting [target].") + var/turf/T = get_turf(src) + msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - JMP)") + log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]") + do_after_cooldown() + return /obj/item/missile @@ -375,13 +307,13 @@ var/primed = null throwforce = 15 - throw_impact(atom/hit_atom) - if(primed) - explosion(hit_atom, 0, 0, 2, 4, 0) - qdel(src) - else - ..() - return +/obj/item/missile/throw_impact(atom/hit_atom) + if(primed) + explosion(hit_atom, 0, 0, 2, 4, 0) + qdel(src) + else + ..() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang name = "SGL-6 Grenade Launcher" @@ -394,18 +326,19 @@ equip_cooldown = 60 var/det_time = 20 size=1 - action(target) - if(!action_checks(target)) return - set_ready_state(0) - var/obj/item/weapon/grenade/flashbang/F = new projectile(chassis.loc) - playsound(chassis, fire_sound, 50, 1) - F.throw_at(target, missile_range, missile_speed, chassis) - projectiles-- - log_message("Fired from [src.name], targeting [target].") - spawn(det_time) - F.prime() - do_after_cooldown() +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/action(target, params) + if(!action_checks(target)) return + set_ready_state(0) + var/obj/item/weapon/grenade/flashbang/F = new projectile(chassis.loc) + playsound(chassis, fire_sound, 50, 1) + F.throw_at(target, missile_range, missile_speed, chassis) + projectiles-- + log_message("Fired from [name], targeting [target].") + spawn(det_time) + F.prime() + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang//Because I am a heartless bastard -Sieve name = "SOB-3 Grenade Launcher" @@ -417,7 +350,7 @@ size=1 /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited/get_equip_info()//Limited version of the clusterbang launcher that can't reload - return "* [chassis.selected==src?"":""][src.name][chassis.selected==src?"":""]\[[src.projectiles]\]" + return "* [chassis.selected==src?"":""][name][chassis.selected==src?"":""]\[[projectiles]\]" /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited/rearm() return//Extra bit of security @@ -432,22 +365,23 @@ projectile_energy_cost = 100 equip_cooldown = 20 - can_attach(obj/mecha/combat/honker/M as obj) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/can_attach(obj/mecha/combat/honker/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 - action(target) - if(!action_checks(target)) return - set_ready_state(0) - var/obj/item/weapon/bananapeel/B = new projectile(chassis.loc) - playsound(chassis, fire_sound, 60, 1) - B.throw_at(target, missile_range, missile_speed, chassis) - projectiles-- - log_message("Bananed from [src.name], targeting [target]. HONK!") - do_after_cooldown() +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/action(target, params) + if(!action_checks(target)) return + set_ready_state(0) + var/obj/item/weapon/bananapeel/B = new projectile(chassis.loc) + playsound(chassis, fire_sound, 60, 1) + B.throw_at(target, missile_range, missile_speed, chassis) + projectiles-- + log_message("Bananed from [name], targeting [target]. HONK!") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar @@ -460,23 +394,24 @@ projectile_energy_cost = 100 equip_cooldown = 10 - can_attach(obj/mecha/combat/honker/M as obj) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 - action(target) - if(!action_checks(target)) return - set_ready_state(0) - var/obj/item/device/assembly/mousetrap/M = new projectile(chassis.loc) - M.secured = 1 - playsound(chassis, fire_sound, 60, 1) - M.throw_at(target, missile_range, missile_speed, chassis) - projectiles-- - log_message("Launched a mouse-trap from [src.name], targeting [target]. HONK!") - do_after_cooldown() +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar/action(target, params) + if(!action_checks(target)) return + set_ready_state(0) + var/obj/item/device/assembly/mousetrap/M = new projectile(chassis.loc) + M.secured = 1 + playsound(chassis, fire_sound, 60, 1) + M.throw_at(target, missile_range, missile_speed, chassis) + projectiles-- + log_message("Launched a mouse-trap from [name], targeting [target]. HONK!") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas name = "PCMK-6 Bolas Launcher" @@ -489,23 +424,24 @@ projectile_energy_cost = 50 equip_cooldown = 10 - can_attach(obj/mecha/combat/gygax/M as obj) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas/can_attach(obj/mecha/combat/gygax/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 - action(target) - if(!action_checks(target)) return - set_ready_state(0) - var/obj/item/weapon/legcuffs/bolas/M = new projectile(chassis.loc) - playsound(chassis, fire_sound, 50, 1) - M.thrown_from = src - M.throw_at(target, missile_range, missile_speed) - projectiles-- - log_message("Fired from [src.name], targeting [target].") - do_after_cooldown() +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/bolas/action(target, params) + if(!action_checks(target)) return + set_ready_state(0) + var/obj/item/weapon/legcuffs/bolas/M = new projectile(chassis.loc) + playsound(chassis, fire_sound, 50, 1) + M.thrown_from = src + M.throw_at(target, missile_range, missile_speed) + projectiles-- + log_message("Fired from [name], targeting [target].") + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma equip_cooldown = 20 diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index a88d1c49bad..d0bf82e4a92 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -153,7 +153,7 @@ I.loc = get_step(src,SOUTH) I.materials[MAT_METAL] = get_resource_cost_w_coeff(D,MAT_METAL) I.materials[MAT_GLASS] = get_resource_cost_w_coeff(D,MAT_GLASS) - visible_message("\icon[src] \The [src] beeps, \"\The [I] is complete.\"") + visible_message("[bicon(src)] \The [src] beeps, \"\The [I] is complete.\"") being_built = null updateUsrDialog() @@ -196,14 +196,14 @@ if(stat&(NOPOWER|BROKEN)) return 0 if(!check_resources(D)) - visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"") temp = {"Not enough resources to build next part.
Try again | Return"} return 0 remove_from_queue(1) build_part(D) D = listgetindex(queue, 1) - visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Queue processing finished successfully.\"") /obj/machinery/mecha_part_fabricator/proc/list_queue() var/output = "Queue contains:" @@ -240,7 +240,7 @@ temp += "Return" updateUsrDialog() - visible_message("\icon[src] \The [src] beeps, \"Successfully synchronized with R&D server.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Successfully synchronized with R&D server.\"") return temp = "Unable to connect to local R&D Database.
Please check your connections and try again.
Return" @@ -271,7 +271,7 @@ user.set_machine(src) var/turf/exit = get_step(src,SOUTH) if(exit.density) - visible_message("\icon[src] \The [src] beeps, \"Error! Part outlet is obstructed.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Error! Part outlet is obstructed.\"") return if(temp) left_part = temp diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index ceeca47f72e..70bcd0a0fd6 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -181,7 +181,7 @@ if(equipment && equipment.len) to_chat(user, "It's equipped with:") for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - to_chat(user, "\icon[ME] [ME]") + to_chat(user, "[bicon(ME)] [ME]") return @@ -219,7 +219,7 @@ // return ..() */ -/obj/mecha/proc/click_action(atom/target,mob/user) +/obj/mecha/proc/click_action(atom/target, mob/user, params) if(!src.occupant || src.occupant != user ) return if(user.stat || !user.canmove) return @@ -239,9 +239,9 @@ return if(!target.Adjacent(src)) if(selected && selected.is_ranged()) - selected.action(target) + selected.action(target, params) else if(selected && selected.is_melee()) - selected.action(target) + selected.action(target, params) else if(internal_damage&MECHA_INT_CONTROL_LOST) target = safepick(oview(1,src)) @@ -1643,7 +1643,7 @@ /obj/mecha/proc/occupant_message(message as text) if(message) if(src.occupant && src.occupant.client) - to_chat(src.occupant, "\icon[src] [message]") + to_chat(src.occupant, "[bicon(src)] [message]") return /obj/mecha/proc/log_message(message as text,red=null) @@ -1991,4 +1991,4 @@ /obj/mecha/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list()) - flick_overlay(image('icons/mob/talk.dmi', bubble_loc, bubble_state,MOB_LAYER+1), bubble_recipients, 30) \ No newline at end of file + flick_overlay(image('icons/mob/talk.dmi', bubble_loc, bubble_state,MOB_LAYER+1), bubble_recipients, 30) diff --git a/code/game/objects/effects/biomass_rift.dm b/code/game/objects/effects/biomass_rift.dm index 247f485b570..5b4cf9970a5 100644 --- a/code/game/objects/effects/biomass_rift.dm +++ b/code/game/objects/effects/biomass_rift.dm @@ -6,6 +6,7 @@ density = 0 anchored = 1 layer = 20 //DEBUG + plane = HUD_PLANE //DEBUG var/health = 10 var/stage = 1 var/obj/effect/rift/originalRift = null //the originating rift of that biomass diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 9445b5aa626..6bcfb253454 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -12,6 +12,7 @@ density = 0 anchored = 1 layer = 50 + plane = HUD_PLANE /obj/effect/decal/chempuff name = "chemicals" diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 6e54e69cf92..c9cb0c62eab 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -21,7 +21,7 @@ if(istype(M, /mob/living/carbon/human)) for(var/mob/O in viewers(world.view, src.loc)) - to_chat(O, "[M] triggered the \icon[src] [src]") + to_chat(O, "[M] triggered the [bicon(src)] [src]") triggered = 1 call(src,triggerproc)(M) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index bc697657b98..a635d2fdad9 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -31,6 +31,7 @@ icon_state = "blank" anchored = 1 layer = 99 + plane = HUD_PLANE mouse_opacity = 0 unacidable = 1//Just to be sure. diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index d18d51936fc..56f38507a42 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -125,5 +125,43 @@ loot = list( /obj/structure/closet/crate/secure/loot = 20, - "" = 80 + "" = 80, + ) + +/obj/effect/spawner/lootdrop/trade_sol_rare + name = "trader rare item spawner" + lootdoubles = 0 + color = "#00FFFF" + + loot = list( + /obj/item/weapon/card/emag_broken = 2, + /obj/item/weapon/defibrillator/compact/loaded = 2, + /obj/item/weapon/gun/energy/laser/retro = 2, + /obj/item/weapon/rcd/combat = 1, + /obj/item/weapon/rcd = 2, + ) + +/obj/effect/spawner/lootdrop/trade_sol_common + name = "trader common item spawner" + lootdoubles = 0 + color = "#00FFFF" + + loot = list( + /obj/item/weapon/tank/anesthetic = 2, + /obj/item/weapon/weldingtool/hugetank = 2, + /obj/item/weapon/pickaxe/diamond = 1, + /obj/item/device/spacepod_equipment/weaponry/mining_laser = 1, + /obj/item/device/paicard = 2, + /obj/item/weapon/gun/projectile/automatic/pistol = 2, + /obj/item/device/megaphone = 2, + /obj/item/weapon/stock_parts/capacitor = 1, + /obj/item/weapon/stock_parts/cell/high = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/stock_parts/micro_laser = 1, + /obj/item/weapon/stock_parts/scanning_module = 1, + /obj/item/weapon/spacecash/c200 = 1, + /obj/item/weapon/airlock_electronics = 1, + /obj/item/weapon/gun/energy/kinetic_accelerator/super = 1, + /obj/item/pizzabox = 3, ) diff --git a/code/game/objects/items/devices/autopsy.dm b/code/game/objects/items/devices/autopsy.dm index 25e4d12614d..be4009b0ed9 100644 --- a/code/game/objects/items/devices/autopsy.dm +++ b/code/game/objects/items/devices/autopsy.dm @@ -165,10 +165,12 @@ P.loc = usr usr.r_hand = P P.layer = 20 + P.plane = HUD_PLANE else if(!usr.l_hand) P.loc = usr usr.l_hand = P P.layer = 20 + P.plane = HUD_PLANE if(istype(usr,/mob/living/carbon/human)) usr:update_inv_l_hand() diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm index 984c98730f4..836da188bba 100644 --- a/code/game/objects/items/devices/pizza_bomb.dm +++ b/code/game/objects/items/devices/pizza_bomb.dm @@ -40,7 +40,7 @@ name = "pizza bomb" desc = "OH GOD THAT'S NOT A PIZZA" icon_state = "pizzabox_bomb" - audible_message("\icon[src] *beep* *beep*") + audible_message("[bicon(src)] *beep* *beep*") to_chat(user, "That's no pizza! That's a bomb!") message_admins("[key_name_admin(usr)] has triggered a pizza bomb armed by [armer] at (JMP).") log_game("[key_name(usr)] has triggered a pizza bomb armed by [armer] ([loc.x],[loc.y],[loc.z]).") @@ -50,9 +50,9 @@ /obj/item/device/pizza_bomb/proc/go_boom() if(disarmed) - visible_message("\icon[src] Sparks briefly jump out of the [correct_wire] wire on \the [src], but it's disarmed!") + visible_message("[bicon(src)] Sparks briefly jump out of the [correct_wire] wire on \the [src], but it's disarmed!") return - src.audible_message("\icon[src] [src] beeps, \"Enjoy the pizza!\"") + src.audible_message("[bicon(src)] [src] beeps, \"Enjoy the pizza!\"") src.visible_message("\The [src] violently explodes!") explosion(src.loc,1,2,4,flame_range = 2) //Identical to a minibomb qdel(src) @@ -67,7 +67,7 @@ user.visible_message("[user] cuts the [chosen_wire] wire!", "You cut the [chosen_wire] wire!") sleep(5) if(chosen_wire == correct_wire) - src.audible_message("\icon[src] \The [src] suddenly stops beeping and seems lifeless.") + src.audible_message("[bicon(src)] \The [src] suddenly stops beeping and seems lifeless.") to_chat(user, "You did it!") icon_state = "pizzabox_bomb_[correct_wire]" name = "pizza bomb" diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 2a1bc41970b..f05b179e62a 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -27,35 +27,34 @@ effective or pretty fucking useless. origin_tech = "magnets=3;combat=3;syndicate=3" var/times_used = 0 //Number of times it's been used. - var/max_uses = 2 + var/max_uses = 5 - -/obj/item/device/batterer/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0) - if(!user) return +/obj/item/device/batterer/examine(mob/user) + ..(user) if(times_used >= max_uses) - to_chat(user, "\red The mind batterer has been burnt out!") + to_chat(user, "[src] is out of charge.") + if(times_used < max_uses) + to_chat(user, "[src] has [max_uses-times_used] charges left.") + +/obj/item/device/batterer/attack_self(mob/living/carbon/user, flag = 0, emp = 0) + if(!user) + return + if(times_used >= max_uses) + to_chat(user, "The mind batterer has been burnt out!") return - user.attack_log += text("\[[time_stamp()]\] Used [src] to knock down people in the area.") - for(var/mob/living/carbon/human/M in orange(10, user)) - spawn() - if(prob(50)) + for(var/mob/living/carbon/human/M in oview(7, user)) + if(prob(50)) + M.Weaken(rand(4,7)) + add_logs(M, user, "stunned", src) + to_chat(M, "You feel a tremendous, paralyzing wave flood your mind.") + else + to_chat(M, "You feel a sudden, electric jolt travel through your head.") - M.Weaken(rand(10,20)) - if(prob(25)) - M.Stun(rand(5,10)) - to_chat(M, "\red You feel a tremendous, paralyzing wave flood your mind.") - if(!iscarbon(user)) - M.LAssailant = null - else - M.LAssailant = user - else - to_chat(M, "\red You feel a sudden, electric jolt travel through your head.") - - playsound(src.loc, 'sound/misc/interference.ogg', 50, 1) - to_chat(user, "\blue You trigger [src].") - times_used += 1 + playsound(loc, 'sound/misc/interference.ogg', 50, 1) + times_used++ + to_chat(user, "You trigger [src]. It has [max_uses-times_used] charges left.") if(times_used >= max_uses) icon_state = "battererburnt" diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 9e4d83592b0..5b4afe8095c 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -9,6 +9,7 @@ var/mob/attacher = null var/valve_open = 0 var/toggle = 1 + origin_tech = "materials=1;engineering=1" /obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D) @@ -187,7 +188,7 @@ attacher_name = "[key_name_admin(attacher)]" var/mob/mob = get_mob_by_key(src.fingerprintslast) - + bombers += "Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]" message_admins("Bomb valve opened at [A.name] (JMP) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]") log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]") diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index 9b02799e496..575680f28ac 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -1,38 +1,45 @@ /obj/item/latexballon - name = "Latex glove" + name = "latex glove" desc = "" //todo icon_state = "latexballon" item_state = "lgloves" force = 0 throwforce = 0 - w_class = 1.0 + w_class = 1 throw_speed = 1 - throw_range = 15 + throw_range = 7 var/state var/datum/gas_mixture/air_contents = null -/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank) - if (icon_state == "latexballon_bursted") +/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank, mob/user) + if(icon_state == "latexballon_bursted") return - src.air_contents = tank.remove_air_volume(3) icon_state = "latexballon_blow" item_state = "latexballon" + user.update_inv_r_hand() + user.update_inv_l_hand() + to_chat(user, "You blow up [src] with [tank].") + air_contents = tank.remove_air_volume(3) /obj/item/latexballon/proc/burst() - if (!air_contents) + if(!air_contents || icon_state != "latexballon_blow") return playsound(src, 'sound/weapons/Gunshot.ogg', 100, 1) icon_state = "latexballon_bursted" item_state = "lgloves" + if(isliving(loc)) + var/mob/living/user = loc + user.update_inv_r_hand() + user.update_inv_l_hand() loc.assume_air(air_contents) /obj/item/latexballon/ex_act(severity) burst() switch(severity) - if (1) + if(1) qdel(src) - if (2) - if (prob(50)) + if(2) + if(prob(50)) qdel(src) /obj/item/latexballon/bullet_act() @@ -43,6 +50,10 @@ burst() return -/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob, params) - if (can_puncture(W)) +/obj/item/latexballon/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/weapon/tank)) + var/obj/item/weapon/tank/T = W + blow(T, user) + return + if(is_sharp(W) || is_hot(W) || can_puncture(W)) burst() \ No newline at end of file diff --git a/code/game/objects/items/policetape.dm b/code/game/objects/items/policetape.dm index 9b1f27dea1b..ad46a511641 100644 --- a/code/game/objects/items/policetape.dm +++ b/code/game/objects/items/policetape.dm @@ -147,17 +147,14 @@ var/list/tape_roll_applications = list() tape_roll_applications[F] |= direction return -/obj/item/tape/Bumped(M as mob) - if(src.allowed(M)) - var/turf/T = get_turf(src) - M:loc = T - /obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(!density) return 1 if(air_group || (height==0)) return 1 if ((mover.pass_flags & PASSTABLE || istype(mover, /obj/effect/meteor) || mover.throwing == 1) ) return 1 + else if(ismob(mover) && allowed(mover)) + return 1 else return 0 diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index bfb90de8cac..512baa30703 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -125,13 +125,13 @@ to_chat(usr, "This robot has had its disabler removed!") return 0 - if(T.recharge_time <= 2) + if(T.charge_delay <= 2) to_chat(R, "Maximum cooling achieved for this hardpoint!") to_chat(usr, "There's no room for another cooling unit!") return 0 else - T.recharge_time = max(2 , T.recharge_time - 4) + T.charge_delay = max(2 , T.charge_delay - 4) return 1 @@ -214,4 +214,4 @@ return 0 R.emagged = 1 - return 1 \ No newline at end of file + return 1 diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index c71f2e14182..fd3f5505f4f 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -114,7 +114,7 @@ bmark.pixel_x-- bmark.pixel_y-- - if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/practice)) + if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/beam/practice)) bmark.icon_state = "scorch" bmark.dir = pick(NORTH,SOUTH,EAST,WEST) // random scorch design @@ -178,4 +178,4 @@ b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4) b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4) - Target.bulletholes.Add(src) \ No newline at end of file + Target.bulletholes.Add(src) diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index e41457f0c38..efba4f62a77 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -80,7 +80,7 @@ return to_chat(usr, "\blue Assembling grille...") - if (!do_after(usr, 10, target = src)) + if (!do_after(usr, 10, target = user)) return var /obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc ) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 3fe6dc7102f..50dc5c3b467 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -140,7 +140,6 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("bookcase", /obj/structure/bookcase, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \ - new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("easel", /obj/structure/easel, 3, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 2aa35527fea..bd799640122 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -130,7 +130,7 @@ return if (R.time) to_chat(usr, "\blue Building [R.title] ...") - if (!do_after(usr, R.time, target = src)) + if (!do_after(usr, R.time, target = usr)) return if (src.amount < R.req_amount*multiplier) return diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 25ade73eb38..6907ea08671 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1130,7 +1130,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = generate_ion_law() to_chat(user, "You press the button on [src].") playsound(user, 'sound/machines/click.ogg', 20, 1) - visible_message("\icon[src] [message]") + visible_message("[bicon(src)] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1149,7 +1149,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = pick("You won't get away this time, Griffin!", "Stop right there, criminal!", "Hoot! Hoot!", "I am the night!") to_chat(user, "You pull the string on the [src].") playsound(user, 'sound/misc/hoot.ogg', 25, 1) - visible_message("\icon[src] [message]") + visible_message("[bicon(src)] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1168,7 +1168,7 @@ obj/item/toy/cards/deck/syndicate/black var/message = pick("You can't stop me, Owl!", "My plan is flawless! The vault is mine!", "Caaaawwww!", "You will never catch me!") to_chat(user, "You pull the string on the [src].") playsound(user, 'sound/misc/caw.ogg', 25, 1) - visible_message("\icon[src] [message]") + visible_message("[bicon(src)] [message]") cooldown = 1 spawn(30) cooldown = 0 return @@ -1274,12 +1274,12 @@ obj/item/toy/cards/deck/syndicate/black /obj/item/toy/minigibber/attackby(var/obj/O, var/mob/user, params) if(istype(O,/obj/item/toy/character) && O.loc == user) - to_chat(user, "You start feeding \the [O] \icon[O] into \the [src]'s mini-input.") + to_chat(user, "You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.") if(do_after(user,10, target = src)) if(O.loc != user) to_chat(user, "\The [O] is too far away to feed into \the [src]!") else - to_chat(user, "You feed \the [O] \icon[O] into \the [src]!") + to_chat(user, "You feed \the [O] [bicon(O)] into \the [src]!") user.unEquip(O) O.forceMove(src) stored_minature = O @@ -1305,7 +1305,7 @@ obj/item/toy/cards/deck/syndicate/black user.visible_message("[user] pulls back the string on [src].") icon_state = "[initial(icon_state)]_used" sleep(5) - audible_message("\icon[src] Hiss!") + audible_message("[bicon(src)] Hiss!") var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg') playsound(get_turf(src), pick(possible_sounds), 50, 1) spawn(45) @@ -1318,7 +1318,7 @@ obj/item/toy/cards/deck/syndicate/black /obj/item/toy/russian_revolver name = "russian revolver" desc = "for fun and games!" - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/projectile.dmi' icon_state = "detective_gold" item_state = "gun" lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' @@ -1431,7 +1431,7 @@ obj/item/toy/cards/deck/syndicate/black /obj/item/toy/figure/attack_self(mob/user as mob) if(cooldown < world.time) cooldown = (world.time + 30) //3 second cooldown - user.visible_message("\icon[src] The [src] says \"[toysay]\".") + user.visible_message("[bicon(src)] The [src] says \"[toysay]\".") playsound(user, 'sound/machines/click.ogg', 20, 1) /obj/item/toy/figure/cmo @@ -1632,7 +1632,7 @@ obj/item/toy/cards/deck/syndicate/black if(!cooldown) var/answer = pick(possible_answers) user.visible_message("[user] focuses on their question and [use_action]...") - user.visible_message("\icon[src] The [src] says \"[answer]\"") + user.visible_message("[bicon(src)] The [src] says \"[answer]\"") spawn(30) cooldown = 0 return diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 1ed57a6b5fd..9c231fbb4a3 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -397,4 +397,4 @@ AI MODULES laws[1] = generate_ion_law() to_chat(user, "You press the button on [src].") playsound(user, 'sound/machines/click.ogg', 20, 1) - src.loc.visible_message("\icon[src] [laws[1]]") \ No newline at end of file + src.loc.visible_message("[bicon(src)] [laws[1]]") \ No newline at end of file diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 5d85ea20e2b..d5bbdf24a90 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -26,232 +26,315 @@ RCD var/working = 0 var/mode = 1 var/canRwall = 0 + var/menu = 1 + var/door_type = /obj/machinery/door/airlock + req_access = list(access_engine) + var/list/door_accesses = list() + var/list/door_accesses_list = list() + var/one_access + var/locked = 1 + var/static/list/allowed_door_types = list(/obj/machinery/door/airlock = "Standard", + /obj/machinery/door/airlock/command = "Command", /obj/machinery/door/airlock/security = "Security", + /obj/machinery/door/airlock/engineering = "Engineering", /obj/machinery/door/airlock/medical = "Medical", + /obj/machinery/door/airlock/maintenance = "Maintenance", /obj/machinery/door/airlock/external = "External", + /obj/machinery/door/airlock/glass = "Standard (Glass)", /obj/machinery/door/airlock/freezer = "Freezer", + /obj/machinery/door/airlock/glass_command = "Command (Glass)", /obj/machinery/door/airlock/glass_engineering = "Engineering (Glass)", + /obj/machinery/door/airlock/glass_security = "Security (Glass)", /obj/machinery/door/airlock/glass_medical = "Medical (Glass)", + /obj/machinery/door/airlock/mining = "Mining", /obj/machinery/door/airlock/atmos = "Atmospherics", + /obj/machinery/door/airlock/research = "Research", /obj/machinery/door/airlock/glass_research = "Research (Glass)", + /obj/machinery/door/airlock/glass_mining = "Mining (Glass)", /obj/machinery/door/airlock/glass_atmos = "Atmospherics (Glass)") - New() +/obj/item/weapon/rcd/New() + desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." + spark_system = new /datum/effect/system/spark_spread + spark_system.set_up(5, 0, src) + spark_system.attach(src) + rcd_list += src + door_accesses_list = list() + for(var/access in get_all_accesses()) + door_accesses_list[++door_accesses_list.len] = list("name" = get_access_desc(access), "id" = access, "enabled" = (access in door_accesses)) + return + +/obj/item/weapon/rcd/Destroy() + qdel(spark_system) + spark_system = null + rcd_list -= src + return ..() + +/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user, params) + ..() + if(istype(W, /obj/item/weapon/rcd_ammo)) + var/obj/item/weapon/rcd_ammo/R = W + if((matter + R.ammoamt) > max_matter) + to_chat(user, "The RCD cant hold any more matter-units.") + return + matter += R.ammoamt + user.drop_item() + qdel(W) + playsound(loc, 'sound/machines/click.ogg', 50, 1) + to_chat(user, "The RCD now holds [matter]/[max_matter] matter-units.") desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." - src.spark_system = new /datum/effect/system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - rcd_list += src + nanomanager.update_uis(src) return - Destroy() - qdel(spark_system) - spark_system = null - rcd_list -= src - return ..() - attackby(obj/item/weapon/W, mob/user, params) - ..() - if(istype(W, /obj/item/weapon/rcd_ammo)) - var/obj/item/weapon/rcd_ammo/R = W - if((matter + R.ammoamt) > max_matter) - to_chat(user, "The RCD cant hold any more matter-units.") - return - matter += R.ammoamt - user.drop_item() - qdel(W) - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - to_chat(user, "The RCD now holds [matter]/[max_matter] matter-units.") - desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." +/obj/item/weapon/rcd/attack_self(mob/user) + //Change the mode + ui_interact(user) + +/obj/item/weapon/rcd/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state) + var/list/data = list() + data["mode"] = mode + data["door_type"] = door_type + data["menu"] = menu + data["matter"] = matter + data["max_matter"] = max_matter + data["one_access"] = one_access + data["locked"] = locked + + if(menu == 2) + var/list/door_types_list = list() + for(var/type in allowed_door_types) + door_types_list[++door_types_list.len] = list("name" = allowed_door_types[type], "type" = type) + data["allowed_door_types"] = door_types_list + + data["door_accesses"] = door_accesses_list + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "rcd.tmpl", "[name]", 400, 400, state = state) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/item/weapon/rcd/Topic(href, href_list, nowindow, state) + if(..()) + return 1 + + if(prob(20)) + spark_system.start() + + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + . = 1 + + if(href_list["door_type"]) + var/new_door_type = text2path(href_list["door_type"]) + if(!(new_door_type in allowed_door_types)) + message_admins("RCD HREF exploit attempted by [key_name(usr, usr.client)]!") return + door_type = new_door_type + . = 1 + + if(href_list["menu"]) + menu = text2num(href_list["menu"]) + . = 1 + + if (href_list["login"]) + if(istype(usr,/mob/living/silicon)) + locked = 0 + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/device/pda)) + var/obj/item/device/pda/pda = I + I = pda.id + var/obj/item/weapon/card/id/ID = I + if (istype(ID) && ID && check_access(ID)) + locked = 0 + . = 1 + + if (href_list["logout"]) + locked = 1 + . = 1 + + if(href_list["toggle_one_access"] && !locked) + one_access = !one_access + . = 1 + + if(href_list["toggle_access"] && !locked) + var/href_access = text2num(href_list["toggle_access"]) + if(href_access in door_accesses) + door_accesses -= href_access + else + door_accesses += href_access + door_accesses_list = list() + for(var/access in get_all_accesses()) + door_accesses_list[++door_accesses_list.len] = list("name" = get_access_desc(access), "id" = access, "enabled" = (access in door_accesses)) + . = 1 + +/obj/item/weapon/rcd/proc/activate() + playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) - attack_self(mob/user) - //Change the mode - playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - switch(mode) - if(1) - mode = 2 - to_chat(user, "Changed mode to 'Airlock'") - if(prob(20)) - src.spark_system.start() - return - if(2) - mode = 3 - to_chat(user, "Changed mode to 'Deconstruct'") - if(prob(20)) - src.spark_system.start() - return - if(3) - mode = 4 - to_chat(user, "Changed mode to 'Windows'") - if(prob(20)) - src.spark_system.start() - return - if(4) - mode = 1 - to_chat(user, "Changed mode to 'Floor & Walls'") - if(prob(20)) - src.spark_system.start() - return +/obj/item/weapon/rcd/afterattack(atom/A, mob/user, proximity) + if(!proximity) return + if(istype(A,/area/shuttle)||istype(A,/turf/space/transit)) + return 0 + if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/window))) + return 0 - proc/activate() - playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + switch(mode) + if(1) + if(istype(A, /turf/space)) + if(useResource(1, user)) + to_chat(user, "Building Floor...") + activate() + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/floor/plating) + return 1 + return 0 + if(istype(A, /turf/simulated/floor)) + if(checkResource(3, user)) + to_chat(user, "Building Wall ...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 20, target = A)) + if(!useResource(3, user)) return 0 + activate() + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/wall) + return 1 + return 0 - afterattack(atom/A, mob/user, proximity) - if(!proximity) return - if(istype(A,/area/shuttle)||istype(A,/turf/space/transit)) - return 0 - if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/window))) - return 0 + if(2) + if(istype(A, /turf/simulated/floor)) + if(checkResource(10, user)) + to_chat(user, "Building Airlock...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 50, target = A)) + if(!useResource(10, user)) return 0 + activate() + var/obj/machinery/door/airlock/T = new door_type(A) + T.autoclose = 1 + if(one_access) + T.req_one_access = door_accesses + else + T.req_access = door_accesses + return 1 + return 0 + return 0 - switch(mode) - if(1) - if(istype(A, /turf/space)) - if(useResource(1, user)) - to_chat(user, "Building Floor...") + if(3) + if(istype(A, /turf/simulated/wall)) + if(istype(A, /turf/simulated/wall/r_wall) && !canRwall) + return 0 + if(checkResource(5, user)) + to_chat(user, "Deconstructing Wall...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 40, target = A)) + if(!useResource(5, user)) return 0 activate() var/turf/AT = A AT.ChangeTurf(/turf/simulated/floor/plating) return 1 - return 0 + return 0 - if(istype(A, /turf/simulated/floor)) - if(checkResource(3, user)) - to_chat(user, "Building Wall ...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 20, target = A)) - if(!useResource(3, user)) return 0 - activate() - var/turf/AT = A - AT.ChangeTurf(/turf/simulated/wall) - return 1 - return 0 + if(istype(A, /turf/simulated/floor)) + if(checkResource(5, user)) + to_chat(user, "Deconstructing Floor...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 50, target = A)) + if(!useResource(5, user)) return 0 + activate() + var/turf/AT = A + AT.ChangeTurf(/turf/space) + return 1 + return 0 - if(2) - if(istype(A, /turf/simulated/floor)) - if(checkResource(10, user)) - to_chat(user, "Building Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 50, target = A)) - if(!useResource(10, user)) return 0 - activate() - var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock( A ) - T.autoclose = 1 - return 1 - return 0 - return 0 - - if(3) - if(istype(A, /turf/simulated/wall)) - if(istype(A, /turf/simulated/wall/r_wall) && !canRwall) - return 0 - if(checkResource(5, user)) - to_chat(user, "Deconstructing Wall...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 40, target = A)) - if(!useResource(5, user)) return 0 - activate() - var/turf/AT = A - AT.ChangeTurf(/turf/simulated/floor/plating) - return 1 - return 0 - - if(istype(A, /turf/simulated/floor)) - if(checkResource(5, user)) - to_chat(user, "Deconstructing Floor...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 50, target = A)) - if(!useResource(5, user)) return 0 - activate() - var/turf/AT = A - AT.ChangeTurf(/turf/space) - return 1 - return 0 - - if(istype(A, /obj/machinery/door/airlock)) - if(checkResource(20, user)) - to_chat(user, "Deconstructing Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(do_after(user, 50, target = A)) - if(!useResource(20, user)) return 0 - activate() - qdel(A) - return 1 - return 0 + if(istype(A, /obj/machinery/door/airlock)) + if(checkResource(20, user)) + to_chat(user, "Deconstructing Airlock...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 50, target = A)) + if(!useResource(20, user)) return 0 + activate() + qdel(A) + return 1 + return 0 - if(istype(A, /obj/structure/window)) // You mean the grille of course, do you? - A = locate(/obj/structure/grille) in A.loc - - if(istype(A, /obj/structure/grille)) - if(!checkResource(2, user)) - return 0 - to_chat(user, "Deconstructing window...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(!do_after(user, 20, target = A)) - return 0 - if(locate(/obj/structure/window/full/shuttle) in A.contents) - return 0 // Let's not give shuttle-griefers an easy time. - if(!useResource(2, user)) - return 0 - activate() - var/turf/T1 = get_turf(A) - qdel(A) - A = null - for(var/obj/structure/window/W in T1.contents) - W.disassembled = 1 - W.density = 0 - qdel(W) - for(var/cdir in cardinal) - var/turf/T2 = get_step(T1, cdir) - if(locate(/obj/structure/window/full/shuttle) in T2.contents) - continue // Shuttle windows? Nah. We don't need extra windows there. - if(!(locate(/obj/structure/grille) in T2.contents)) - continue - for(var/obj/structure/window/W in T2.contents) + if(istype(A, /obj/structure/window)) // You mean the grille of course, do you? + A = locate(/obj/structure/grille) in A.loc + + if(istype(A, /obj/structure/grille)) + if(!checkResource(2, user)) + return 0 + to_chat(user, "Deconstructing window...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(!do_after(user, 20, target = A)) + return 0 + if(locate(/obj/structure/window/full/shuttle) in A.contents) + return 0 // Let's not give shuttle-griefers an easy time. + if(!useResource(2, user)) + return 0 + activate() + var/turf/T1 = get_turf(A) + qdel(A) + A = null + for(var/obj/structure/window/W in T1.contents) + W.disassembled = 1 + W.density = 0 + qdel(W) + for(var/cdir in cardinal) + var/turf/T2 = get_step(T1, cdir) + if(locate(/obj/structure/window/full/shuttle) in T2.contents) + continue // Shuttle windows? Nah. We don't need extra windows there. + if(!(locate(/obj/structure/grille) in T2.contents)) + continue + for(var/obj/structure/window/W in T2.contents) + if(W.dir == turn(cdir, 180)) + W.disassembled = 1 + W.density = 0 + qdel(W) + var/obj/structure/window/reinforced/W = new(T2) + W.dir = turn(cdir, 180) + return 1 + return 0 + if(4) + if(istype(A, /turf/simulated/floor)) + if(locate(/obj/structure/grille) in contents) + return 0 // We already have window + if(!checkResource(2, user)) + return 0 + to_chat(user, "Constructing window...") + playsound(loc, 'sound/machines/click.ogg', 50, 1) + if(!do_after(user, 20, target = A)) + return 0 + if(locate(/obj/structure/grille) in A.contents) + return 0 // We already have window + if(!useResource(2, user)) + return 0 + activate() + new /obj/structure/grille(A) + for(var/obj/structure/window/W in contents) + W.disassembled = 1 // Prevent that annoying glass breaking sound + W.density = 0 + qdel(W) + for(var/cdir in cardinal) + var/turf/T = get_step(A, cdir) + if(locate(/obj/structure/grille) in T.contents) + for(var/obj/structure/window/W in T.contents) if(W.dir == turn(cdir, 180)) W.disassembled = 1 W.density = 0 qdel(W) - var/obj/structure/window/reinforced/W = new(T2) - W.dir = turn(cdir, 180) - return 1 - return 0 - if(4) - if(istype(A, /turf/simulated/floor)) - if(locate(/obj/structure/grille) in contents) - return 0 // We already have window - if(!checkResource(2, user)) - return 0 - to_chat(user, "Constructing window...") - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - if(!do_after(user, 20, target = A)) - return 0 - if(locate(/obj/structure/grille) in A.contents) - return 0 // We already have window - if(!useResource(2, user)) - return 0 - activate() - new /obj/structure/grille(A) - for(var/obj/structure/window/W in contents) - W.disassembled = 1 // Prevent that annoying glass breaking sound - W.density = 0 - qdel(W) - for(var/cdir in cardinal) - var/turf/T = get_step(A, cdir) - if(locate(/obj/structure/grille) in T.contents) - for(var/obj/structure/window/W in T.contents) - if(W.dir == turn(cdir, 180)) - W.disassembled = 1 - W.density = 0 - qdel(W) - else // Build a window! - var/obj/structure/window/reinforced/W = new(A) - W.dir = cdir - var/turf/AT = A - AT.ChangeTurf(/turf/simulated/floor/plating) // Platings go under windows. - return 1 - else - to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.") - return 0 + else // Build a window! + var/obj/structure/window/reinforced/W = new(A) + W.dir = cdir + var/turf/AT = A + AT.ChangeTurf(/turf/simulated/floor/plating) // Platings go under windows. + return 1 + else + to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.") + return 0 + + nanomanager.update_uis(src) /obj/item/weapon/rcd/proc/useResource(var/amount, var/mob/user) if(matter < amount) return 0 matter -= amount desc = "A RCD. It currently holds [matter]/[max_matter] matter-units." + nanomanager.update_uis(src) return 1 /obj/item/weapon/rcd/proc/checkResource(var/amount, var/mob/user) diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm index 5c3e9afff5d..665ad549bd2 100644 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ b/code/game/objects/items/weapons/bee_briefcase.dm @@ -2,6 +2,7 @@ /obj/item/weapon/bee_briefcase name = "briefcase" desc = "This briefcase has easy-release clasps and smells vaguely of honey and blood..." + description_antag = "A briefcase filled with deadly bees, you should inject this with a syringe of your own blood before opening it." icon = 'icons/obj/storage.dmi' icon_state = "briefcase" item_state = "briefcase" @@ -27,7 +28,6 @@ /obj/item/weapon/bee_briefcase/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/reagent_containers/syringe)) - var/obj/item/weapon/reagent_containers/syringe/S = I if(!bees_left) to_chat(user, "The briefcase is empty, so there is no point in injecting something into it.") @@ -46,7 +46,6 @@ to_chat(user, "The buzzing inside the briefcase swells momentarily, then returns to normal. Guess it was too cramped...") S.reagents.clear_reagents() S.update_icon() - else if(istype(I, /obj/item/weapon/plantspray)) var/obj/item/weapon/plantspray/PS = I user.drop_item(PS) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 79c6466235b..97f66ec6a72 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -150,8 +150,8 @@ return /obj/item/weapon/card/id/attack_self(mob/user as mob) - user.visible_message("[user] shows you: \icon[src] [src.name]. The assignment on the card: [src.assignment]",\ - "You flash your ID card: \icon[src] [src.name]. The assignment on the card: [src.assignment]") + user.visible_message("[user] shows you: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]",\ + "You flash your ID card: [bicon(src)] [src.name]. The assignment on the card: [src.assignment]") if(mining_points) to_chat(user, "There's [mining_points] mining equipment redemption points loaded onto this card.") src.add_fingerprint(user) diff --git a/code/game/objects/items/weapons/cash.dm b/code/game/objects/items/weapons/cash.dm index 6a1d6c0c360..ab6ff1fac8e 100644 --- a/code/game/objects/items/weapons/cash.dm +++ b/code/game/objects/items/weapons/cash.dm @@ -37,9 +37,9 @@ var/global/list/moneytypes=list( /obj/item/weapon/spacecash/examine(mob/user) if(amount>1) - to_chat(user, "\icon[src] This is a stack of [amount] [src]s.") + to_chat(user, "[bicon(src)] This is a stack of [amount] [src]s.") else - to_chat(user, "\icon[src] This is \a [src]s.") + to_chat(user, "[bicon(src)] This is \a [src]s.") to_chat(user, "It's worth [worth*amount] credits.") /obj/item/weapon/spacecash/update_icon() diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index e0ac96c4feb..b0a1c45622d 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -41,12 +41,11 @@ icon = 'icons/obj/chronos.dmi' icon_state = "chronogun" item_state = "chronogun" - w_class = 3.0 - projectile_type = "/obj/item/projectile/energy/chrono_beam" - fire_sound = 'sound/weapons/Laser.ogg' - charge_cost = 0 - fire_delay = 50 + w_class = 3 flags = NODROP + ammo_type = list(/obj/item/ammo_casing/energy/chrono_beam) + can_charge = 0 + fire_delay = 50 var/obj/item/weapon/chrono_eraser/TED = null var/obj/effect/chrono_field/field = null var/turf/startpos = null @@ -60,12 +59,13 @@ qdel(src) /obj/item/weapon/gun/energy/chrono_gun/dropped() + ..() qdel(src) /obj/item/weapon/gun/energy/chrono_gun/update_icon() return -/obj/item/weapon/gun/energy/chrono_gun/Fire() +/obj/item/weapon/gun/energy/chrono_gun/process_fire() if(field) field_disconnect(field) ..() @@ -125,18 +125,23 @@ nodamage = 1 var/obj/item/weapon/gun/energy/chrono_gun/gun = null -/obj/item/projectile/energy/chrono_beam/process() +/obj/item/projectile/energy/chrono_beam/fire() gun = firer.get_active_hand() if(istype(gun)) return ..() else return 0 -/obj/item/projectile/energy/chrono_beam/on_hit(var/atom/target) +/obj/item/projectile/energy/chrono_beam/on_hit(atom/target) if(target && gun && isliving(target)) var/obj/effect/chrono_field/F = new(target.loc, target, gun) gun.field_connect(F) +/obj/item/ammo_casing/energy/chrono_beam + name = "eradication beam" + projectile_type = /obj/item/projectile/energy/chrono_beam + icon_state = "chronobolt" + e_cost = 0 /obj/effect/chrono_field name = "eradication field" @@ -256,4 +261,4 @@ #undef CHRONO_BEAM_RANGE -#undef CHRONO_FRAME_COUNT \ No newline at end of file +#undef CHRONO_FRAME_COUNT diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 73eda279b3d..3e8e5f13c2a 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -331,6 +331,8 @@ H.updatehealth() //forces health update before next life tick playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) H.emote("gasp") + if(!H.heart_attack && (prob(10) || defib.combat)) // Your heart explodes. + H.heart_attack = 1 add_logs(M, user, "stunned", object="defibrillator") defib.deductcharge(revivecost) cooldown = 1 @@ -354,8 +356,8 @@ qdel(ghost) ghost = null var/tplus = world.time - H.timeofdeath - var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) - var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting + var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds) + var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting var/total_burn = 0 var/total_brute = 0 if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total @@ -368,8 +370,26 @@ update_icon() return if(H.heart_attack) - H.heart_attack = 0 - if(H.stat == 2) + if(!H.get_int_organ(/obj/item/organ/internal/heart) && !H.get_int_organ(/obj/item/organ/internal/brain/slime)) //prevents defibing someone still alive suffering from a heart attack attack if they lack a heart + user.visible_message("[defib] buzzes: Resuscitation failed - Failed to pick up any heart electrical activity.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() + return + else + H.heart_attack = 0 + user.visible_message("[defib] pings: Cardiac arrhythmia corrected.") + M.visible_message("[M]'s body convulses a bit.") + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + playsound(get_turf(src), "bodyfall", 50, 1) + playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) + defib.deductcharge(revivecost) + busy = 0 + cooldown = 1 + update_icon() + defib.cooldowncheck(user) + return + if(H.stat == DEAD) var/health = H.health M.visible_message("[M]'s body convulses a bit.") playsound(get_turf(src), "bodyfall", 50, 1) @@ -377,7 +397,7 @@ for(var/obj/item/organ/external/O in H.organs) total_brute += O.brute_dam total_burn += O.burn_dam - if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations)) + if(total_burn <= 180 && total_brute <= 180 && !H.suiciding && !ghost && tplus < tlimit && !(NOCLONE in H.mutations) && (H.get_int_organ(/obj/item/organ/internal/heart) || H.get_int_organ(/obj/item/organ/internal/brain/slime))) tobehealed = min(health + threshold, 0) // It's HILARIOUS without this min statement, let me tell you tobehealed -= 5 //They get 5 of each type of damage healed so excessive combined damage will not immediately kill them after they get revived H.adjustOxyLoss(tobehealed) @@ -452,6 +472,8 @@ H.adjustStaminaLoss(50) H.Weaken(5) H.updatehealth() //forces health update before next life tick + if(!H.heart_attack && prob(10)) // Your heart explodes. + H.heart_attack = 1 playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) H.emote("gasp") add_logs(M, user, "stunned", object="defibrillator") @@ -481,8 +503,8 @@ qdel(ghost) ghost = null var/tplus = world.time - H.timeofdeath - var/tlimit = 6000 //past this much time the patient is unrecoverable (in deciseconds) - var/tloss = 3000 //brain damage starts setting in on the patient after some time left rotting + var/tlimit = 1800 //past this much time the patient is unrecoverable (in deciseconds) + var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting var/total_burn = 0 var/total_brute = 0 if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 0cd8f88dd99..92928a967e3 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -37,7 +37,7 @@ /obj/item/weapon/extinguisher/examine(mob/user) if(..(user, 0)) - to_chat(usr, "\icon[src] [src.name] contains:") + to_chat(usr, "[bicon(src)] [src.name] contains:") if(reagents && reagents.reagent_list.len) for(var/datum/reagent/R in reagents.reagent_list) to_chat(user, "\blue [R.volume] units of [R.name]") diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index ed2f0fb33e8..b56e103233e 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -134,6 +134,13 @@ item_state = "katana" slot_flags = SLOT_BELT | SLOT_BACK +/obj/item/weapon/nullrod/claymore/multiverse + name = "extradimensional blade" + desc = "Once the harbringer of a interdimensional war, now a dormant souvenir. Still sharp though." + icon_state = "multiverse" + item_state = "multiverse" + slot_flags = SLOT_BELT + /obj/item/weapon/nullrod/claymore/saber name = "light energy sword" hitsound = 'sound/weapons/blade1.ogg' @@ -148,6 +155,12 @@ item_state = "swordred" desc = "Woefully ineffective when used on steep terrain." +/obj/item/weapon/nullrod/claymore/saber/pirate + name = "nautical energy sword" + icon_state = "cutlass1" + item_state = "cutlass1" + desc = "Convincing HR that your religion involved piracy was no mean feat." + /obj/item/weapon/nullrod/sord name = "\improper UNREAL SORD" desc = "This thing is so unspeakably HOLY you are having a hard time even holding it." @@ -179,6 +192,49 @@ desc = "Bad references are the DNA of the soul." attack_verb = list("chopped", "sliced", "cut", "zandatsu'd") +/obj/item/weapon/nullrod/scythe/talking + icon_state = "talking_sword" + item_state = "talking_sword" + name = "possessed blade" + desc = "When the station falls into chaos, it's nice to have a friend by your side." + attack_verb = list("chopped", "sliced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + var/possessed = FALSE + +/obj/item/weapon/nullrod/scythe/talking/attack_self(mob/living/user) + if(possessed) + return + + to_chat(user, "You attempt to wake the spirit of the blade...") + + possessed = TRUE + + var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, 0, 100) + var/mob/dead/observer/theghost = null + + if(candidates.len) + theghost = pick(candidates) + var/mob/living/simple_animal/shade/S = new(src) + S.real_name = name + S.name = name + S.ckey = theghost.ckey + var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN) + + if(src && input) + name = input + S.real_name = input + S.name = input + else + to_chat(user, "The blade is dormant. Maybe you can try again later.") + possessed = FALSE + +/obj/item/weapon/nullrod/scythe/talking/Destroy() + for(var/mob/living/simple_animal/shade/S in contents) + to_chat(S, "You were destroyed!") + S.ghostize() + qdel(S) + return ..() + /obj/item/weapon/nullrod/hammmer icon_state = "hammeron" item_state = "hammeron" @@ -326,3 +382,75 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharp = 1 edge = 1 + +/obj/item/weapon/nullrod/rosary + icon_state = "rosary" + item_state = null + name = "prayer beads" + desc = "A set of prayer beads used by many of the more traditional religions in space.
Vampires and other unholy abominations have learned to fear these." + force = 0 + throwforce = 0 + var/praying = 0 + +/obj/item/weapon/nullrod/rosary/New() + ..() + processing_objects.Add(src) + + +/obj/item/weapon/nullrod/rosary/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) + if(!istype(M)) + return ..() + + if(!user.mind || user.mind.assigned_role != "Chaplain") + to_chat(user, "You are not close enough with [ticker.Bible_deity_name] to use [src].") + return + + if(praying) + to_chat(user, "You are already using [src].") + + user.visible_message("[user] kneels[M == user ? null : " next to [M]"] and begins to utter a prayer to [ticker.Bible_deity_name].", \ + "You kneel[M == user ? null : " next to [M]"] and begin a prayer to [ticker.Bible_deity_name].") + + praying = 1 + if(do_after(user, 150, target = M)) + if(istype(M, /mob/living/carbon/human)) // This probably should not work on vulps. They're unholy abominations. + var/mob/living/carbon/human/target = M + + if(target.mind) + if(iscultist(target)) + ticker.mode.remove_cultist(target.mind) // This proc will handle message generation. + praying = 0 + return + + if(target.mind.vampire && !target.mind.vampire.get_ability(/datum/vampire_passive/full)) // Getting a full prayer off on a vampire will interrupt their powers for a large duration. + target.mind.vampire.nullified = max(120, target.mind.vampire.nullified + 120) + to_chat(target, "[user]'s prayer to [ticker.Bible_deity_name] has interfered with your power!") + praying = 0 + return + + if(prob(25)) + to_chat(target, "[user]'s prayer to [ticker.Bible_deity_name] has eased your pain!") + target.adjustToxLoss(-5) + target.adjustOxyLoss(-5) + target.adjustBruteLoss(-5) + target.adjustFireLoss(-5) + + praying = 0 + + else + to_chat(user, "Your prayer to [ticker.Bible_deity_name] was interrupted.") + praying = 0 + +/obj/item/weapon/nullrod/rosary/process() + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/holder = loc + + if(src == holder.l_hand || src == holder.r_hand) // Holding this in your hand will + for(var/mob/living/carbon/human/M in range(5)) + if(M.mind.vampire && !M.mind.vampire.get_ability(/datum/vampire_passive/full)) + M.mind.vampire.nullified = max(5, M.mind.vampire.nullified + 2) + if(prob(10)) + to_chat(M, "Being in the presence of [holder]'s [src] is interfering with your powers!") + + + diff --git a/code/game/objects/items/weapons/implants/implant_traitor.dm b/code/game/objects/items/weapons/implants/implant_traitor.dm index 547206da29c..78e63ddfae4 100644 --- a/code/game/objects/items/weapons/implants/implant_traitor.dm +++ b/code/game/objects/items/weapons/implants/implant_traitor.dm @@ -56,11 +56,11 @@ ticker.mode.traitors += H.mind H.mind.special_role = "traitor" to_chat(H, "You're now completely loyal to [user.name]! You now must lay down your life to protect them and assist in their goals at any cost.") - var/datum/objective/protect/p = new - p.owner = H.mind - p.target = user:mind - p.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]." - H.mind.objectives += p + var/datum/objective/protect/mindslave/MS = new + MS.owner = H.mind + MS.target = user:mind + MS.explanation_text = "Obey every order from and protect [user:real_name], the [user:mind:assigned_role=="MODE" ? (user:mind:special_role) : (user:mind:assigned_role)]." + H.mind.objectives += MS for(var/datum/objective/objective in H.mind.objectives) to_chat(H, "Objective #1: [objective.explanation_text]") @@ -71,10 +71,16 @@ var/datum/mindslaves/slaved = user.mind.som H.mind.som = slaved slaved.serv += H - slaved.add_serv_hud(user.mind,"syndicate")//handles master servent icons - slaved.add_serv_hud(H.mind,"mindslave") + slaved.add_serv_hud(user.mind, "master") //handles master servent icons + slaved.add_serv_hud(H.mind, "mindslave") log_admin("[ckey(user.key)] has mind-slaved [ckey(H.key)].") activated = 1 return 1 - return 0 \ No newline at end of file + return 0 + +/obj/item/weapon/implant/traitor/removed(mob/target) + if(..()) + ticker.mode.remove_traitor_mind(target.mind) + return 1 + return 0 \ No newline at end of file diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 3a371b8191e..b580a024b91 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -1815,18 +1815,6 @@

-

Atmospherics Technician


-
    -
  1. Atmospheric Technicians are permitted to completely repipe the Atmospherics Piping Setup, provided they do not pump harmful gases into anywhere except the Turbine;
  2. -
  3. Atmospheric Technicians are not permitted to create volatile mixes using Plasma and Oxygen, nor are they permitted to create any potentially harmful mixes with Carbon Dioxide and/or Nitrous Oxide. An exception is made when working with the Turbine;
  4. -
  5. Atmospheric Technicians are permitted to cool Plasma and store it for later use in Radiation Collectors. Likewise, they are permitted to cool Nitrogen or Carbon Dioxide and store it for use as coolant for the Supermatter Engine;
  6. -
  7. Atmospheric Technicians are not permitted to take the axe out of its case unless there is an immediate and urgent threat to their life or urgent access to crisis locations is necessary. The axe must be returned to the case afterwards, and the case locked;
  8. -
  9. Atmospheric Technicians are not permitted to tamper with the default values on Air Alarms. They are, however, permitted to create small, acclimatized rooms for species that require special atmospheric conditions (such as Plasmamen and Vox), provided they receive express permission from the Chief Engineer;
  10. -
  11. Atmospheric Technicians must periodically check on the Central Alarms Computer, in periods of, at most, thirty (30) minutes;
  12. -
  13. Atmospheric Technicians must respond promptly to piping and station breaches. Failure to report within fifteen (15) minutes will be considered a breach of Standard Operating Procedure, unless there are no spare Atmospheric Technicians to report, or an Engineer has arrived on scene first. All Hazard Zones must be cordoned off with Engineering Tape, for the sake of everyone else
  14. -
-

-

Shaft Miner


  1. Shaft Miners are not permitted to bring Gibtonite aboard the station;
  2. @@ -2412,7 +2400,104 @@
  3. Demotion of Chief Engineer and reparation of Engine if no threat manifests.


  4. - + + + + + "} + +/obj/item/weapon/book/manual/sop_command + name = "Command Standard Operating Procedures" + desc = "A set of guidelines aiming at the safe conduct of all Command activities." + icon_state = "book4" + author = "Nanotrasen" + title = "Command Standard Operating Procedures" + dat = {" + + + + + + + + +

    Contents

    +
      +
    1. Foreword
    2. +
    3. Captain
    4. +
    5. Head of Personnel
    6. +
    7. NanoTrasen Representative
    8. +
    9. Blueshield Officer
    10. +
    11. AI
    12. +
    +

    + +

    FOREWORD


    + Job SOP should not be a considered a checklist of conditions to fire someone over, and should not be rigidly followed to the letter in detriment of circumstances and context. + As always, SOP can be malleable if the situation so requires, and the decision to punish a crewmember for breaching it ultimately falls onto the relevant Head of Staff, + for Department Members, or Captain, for the Head of Staff.

    + +

    Captain


    +
      +
    1. The Captain is not permitted to perform regular Security Duty. However, they may still assist Security if they are understaffed, or if they see a crime being committed. However, the Captain is not permitted to take items from the Armory under normal circumstances, unless authorized by the Head of Security. In addition, the Captain may not requisition weaponry for themselves from Cargo and/or Science, unless there's an immediate threat to station and/or crew;
    2. +
    3. If a Department lacks a Head of Staff, the Captain should make reasonable efforts to appoint an Acting Head of Staff, if there are available personnel to fill the position;
    4. +
    5. The Captain is to ensure that Space Law is being correctly applied. This should be done in cooperation with the Head of Security;
    6. +
    7. The Captain is not to leave the NSS Cyberiad unless given specific permission by Central Command, or it happens to be the end of the shift. This includes via space or via the Gateway. To do so is to be considered abandoning their posts and is grounds for termination;
    8. +
    9. The Captain must keep the Nuclear Authentication Disk on their person at all times or, failing that, in the possession of the Head of Security or Blueshield;
    10. +
    11. The Captain is to attempt to resolve every issue that arises in Command locally before contacting Central Command;
    12. +
    13. The Captain is not permitted to carry their Antique Laser Gun or Space Armor unless there's an immediate emergency that requires attending to;
    14. +
    15. The Captain, despite being in charge of the Cyberiad, is not independent from NanoTrasen. Any attempts to disregard general company policy are to be considered an instant condition for contract termination;
    16. +
    17. The Captain may only promote personnel to a Acting Head of Staff position if there is no assigned Head of Staff associated with the Department. Said Acting Head of Staff must be a member of the Department they are to lead. See below for more information on Chain of Command;
    18. +
    19. The Captain may not fire any Head of Staff without reasonable justification (ie, incompetency, criminal activity, or otherwise any action that endangers/compromises the station and/or crew). The Captain may not fire any Central Command VIPs (ie, Blueshield, Magistrate, NanoTrasen Representative) without permission from Central Command, unless they are blatantly acting against the well-being and safety of the crew and station.
    20. +

    + +

    Head of Personnel


    +
      +
    1. The Head of Personnel may not transfer any personnel to another Department without authorization from the relevant Head of Staff. If no Head of Staff is available, the Head of Personnel may make a judgement call. This does not apply to Security, which always requires authorization from the Head of Security, or Genetics, which requires both Chief Medical Officer and Research Director approval. If there is no Head of Security active, no transfers are allowed to Security without authorization from the Captain;
    2. +
    3. The Head of Personnel may not give any personnel increased access without authorization from the relevant Head of Staff. This includes the Head of Personnel. In addition, the Head of Personnel may only give Captain-Level access to someone if they are the Acting Captain. This access is to be removed when a proper Captain arrives on the station;
    4. +
    5. The Head of Personnel may not increase any Job Openings unless the relevant Head of Staff approves;
    6. +
    7. The Head of Personnel may not fire any personnel without authorization from the relevant Head of Staff, unless other conditions apply (see Space Law and General Standard Operating Procedure);
    8. +
    9. The Head of Personnel may not promote any personnel to the following Jobs without authorization from Central Command: Barber, Brig Physician, NanoTrasen Representative, Blueshield, Security Pod Pilot, Mechanic and Magistrate; (This is due to them being karma locked. Do not promote people to these positions without approval from the Administrators);
    10. +
    11. The Head of Personnel is free to utilize paperwork at their discretion. However, during major station emergencies, expediency should take precedence over bureaucracy;
    12. +
    13. The Head of Personnel may not leave their office unmanned if there are personnel waiting in line. Failure to respond to personnel with a legitimate request within ten (10) minutes, either via radio or in person, is to be considered a breach of Standard Operating Procedure;
    14. +
    15. Despite nominally being in charge of Supply, the Head of Personnel should allow the Quartermaster to run the Department, unless they prove themselves to be incompetent/dangerous;
    16. +
    17. The Head of Personnel is bound to the same rules regarding ordering Cargo Crates as the Quartermaster and Cargo Technicians. In addition, the Head of Personnel may not order unneeded, non-essential items against the wishes of Cargo;
    18. +
    19. The Head of Personnel is not permitted to perform Security duty. The Head of Personnel is permitted to carry an Energy Gun, for self-defence only.
    20. +

    + +

    NanoTrasen Representative


    +
      +
    1. The NanoTrasen Representative is to ensure that every Department is following Standard Operating Procedure, up to and including the respective Head of Staff. If a Head of Staff is not available for a Department, the NanoTrasen Representative must ensure that the Captain appoints an Acting Head of Staff for said Department;
    2. +
    3. The NanoTrasen Representative must attempt to resolve any breach of Standard Operating Procedure locally before contacting Central Command. This is an imperative: Standard Operating Procedure should always be followed unless there is a very good reason not to;
    4. +
    5. The NanoTrasen Representative must, together with the Magistrate and Head of Security, ensure that Space Law is being followed and correctly applied;
    6. +
    7. The NanoTrasen Representative may not threaten the use of a fax in order to gain leverage over any personnel, up to and including Command. In addition they may not threaten to fire, or have Central Command, fire anyone, unless they actually possess a demotion note;
    8. +
    9. The NanoTrasen Representative is permitted to carry their Stun-Cane, or a Telescopic Baton if the Stun-Cane is lost.
    10. +

    + +

    Blueshield Officer


    +
      +
    1. The Blueshield may not conduct arrests under the same conditions as Security. However, they may apprehend any personnel that trespass on a Head of Staff Office or Command Area, any personnel that steal from those locations, or any personnel that steal from and/or injure any Head of Staff or Central Command VIP. However, all apprehended personnel are to be processed by Security personnel;
    2. +
    3. The Blueshield is to put the lives of Command over those of any other personnel, the Blueshield included. Their continued well-being is the Blueshield's top priority. This includes applying basic first aid and making sure they are revived if killed;
    4. +
    5. The Blueshield is to protect the lives of Command personnel, not follow their orders to a fault. The Blueshield is not to interfere with legal demotions or arrests. To do so is to place themselves under the Special Modifier Aiding and Abetting;
    6. +
    7. The Blueshield is not to apply Lethal Force unless there is a clear and present danger to their life, or to the life of a member of Command, and the assailant cannot be non-lethally detained.
    8. +

    + +

    AI


    + The following are procedures for AI Maintenance:
    +
      +
    1. Only the Captain or Research Director may enter the AI Upload to perform Law Changes (see below), and only the Captain, Research Director or Chief Engineer may enter the AI Core to perform a Carding (see below);
    2. +
    3. No Law Changes are to be performed without approval from the Captain and Research Director. The only Lawsets to be used are those provided by NanoTrasen. Failure to legally perform a Law Change is to be considered Sabotage. Command must be informed prior to the Law Change, and all objections must be taken into consideration. If the number of Command personnel opposing the Law Change is greater than the number of Command personnel in favour, the Law Change is not to be done. If the Law Change is performed, the crew is to be immediately informed of the new Law(s);
    4. +
    5. The AI may not be Carded unless it it clearly malfunctioning or subverted. However, any member of Command may card it if the AI agrees to it, either at the end of the shift, or due to external circumstances (such as massive damage to the AI Satellite);
    6. +
    7. The AI Upload and Minisat Antechamber Turrets are to be kept on Non-Lethal in Code Green and Code Blue. The AI Core Turrets are to be kept on Lethal at all times. If a legal Law Change or Carding is occurring, the Turrets are to be disabled;
    8. +
    9. If the AI Unit is not malfunctioning or subverted, any attempt at performing an illegal Carding or Law Change is to be responded to with non-lethal force. If the illegal attempts persist, and the perpetrator is demonstrably hostile, lethal force from Command/Security is permitted;
    10. +
    11. Freeform Laws are only to be added if absolutely necessary due to external circumstances (such as major station emergencies). Adding unnecessary Freeform Laws is not permitted. Exception is made if the AI Unit and majority of Command agree to the Freeform Law that is proposed;
    12. +
    13. Any use of the "Purge" Module is to be followed by the upload of a NanoTrasen-approved Lawset immediately. AI Units must be bound to a Lawset at all times.
    14. +

    diff --git a/code/game/objects/items/weapons/misc.dm b/code/game/objects/items/weapons/misc.dm index 15048ae13b5..ebe8ecb421d 100644 --- a/code/game/objects/items/weapons/misc.dm +++ b/code/game/objects/items/weapons/misc.dm @@ -127,10 +127,16 @@ icon = 'icons/obj/items.dmi' icon_state = "red_phone" flags = CONDUCT - force = 3.0 - throwforce = 2.0 + force = 3 + throwforce = 2 throw_speed = 1 throw_range = 4 w_class = 2 attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' \ No newline at end of file + hitsound = 'sound/weapons/ring.ogg' + var/cooldown = 0 + +/obj/item/weapon/phone/attack_self(mob/user) + if(cooldown < world.time - 20) + playsound(user.loc, 'sound/weapons/ring.ogg', 50, 1) + cooldown = world.time \ No newline at end of file diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm index 9e8f68faa73..1130ab3808b 100644 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ b/code/game/objects/items/weapons/pneumaticCannon.dm @@ -24,9 +24,9 @@ return for(var/obj/item/I in loadedItems) spawn(0) - to_chat(user, "\icon [I] It has \the [I] loaded.") + to_chat(user, "[bicon(I)] It has \the [I] loaded.") if(tank) - to_chat(user, "\icon [tank] It has \the [tank] mounted onto it.") + to_chat(user, "[bicon(tank)] It has \the [tank] mounted onto it.") /obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params) diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index 62f60a91bc4..a34a8328457 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -128,7 +128,6 @@ materials = list() minor_fault = 1 - /obj/item/weapon/stock_parts/cell/high/slime name = "charged slime core" desc = "A yellow slime core infused with plasma, it crackles with power." @@ -138,6 +137,12 @@ materials = list() self_recharge = 1 // Infused slime cores self-recharge, over time +/obj/item/weapon/stock_parts/cell/pulse //200 pulse shots + name = "pulse rifle power cell" + maxcharge = 40000 + rating = 3 + chargerate = 1500 + /obj/item/weapon/stock_parts/cell/pulse/carbine name = "pulse carbine power cell" maxcharge = 4000 @@ -168,9 +173,3 @@ /obj/item/weapon/stock_parts/cell/emproof/corrupt() return - -/obj/item/weapon/stock_parts/cell/temperaturegun - name = "temperature gun cell" - desc = "A specially designed power cell for heating and cooling projectiles" - icon_state = "icell" - maxcharge = 900 \ No newline at end of file diff --git a/code/game/objects/items/weapons/stock_parts.dm b/code/game/objects/items/weapons/stock_parts.dm index f7edba7e1c4..6e0500ffd38 100644 --- a/code/game/objects/items/weapons/stock_parts.dm +++ b/code/game/objects/items/weapons/stock_parts.dm @@ -131,7 +131,7 @@ name = "nano-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "nano_mani" - origin_tech = "materials=3,programming=2" + origin_tech = "materials=3;programming=2" rating = 2 materials = list(MAT_METAL=30) @@ -173,7 +173,7 @@ name = "pico-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "pico_mani" - origin_tech = "materials=5,programming=2" + origin_tech = "materials=5;programming=2" rating = 3 materials = list(MAT_METAL=30) diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm index 1b9be2bec62..56a3279dde0 100644 --- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm +++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm @@ -135,6 +135,7 @@ affected_mob.adjustBruteLoss(-12) affected_mob.adjustFireLoss(-12) affected_mob.adjustToxLoss(-5) + affected_mob.setStaminaLoss(0) var/status = CANSTUN | CANWEAKEN | CANPARALYSE affected_mob.status_flags &= ~status affected_mob.dizziness = max(0, affected_mob.dizziness-10) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index d14fc5958f0..07c8d836049 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -44,6 +44,7 @@ desc = "Can hold various tools." icon_state = "utilitybelt" item_state = "utility" + use_item_overlays = 1 can_hold = list( "/obj/item/weapon/crowbar", "/obj/item/weapon/screwdriver", @@ -90,6 +91,7 @@ desc = "Can hold various medical equipment." icon_state = "medicalbelt" item_state = "medical" + use_item_overlays = 1 can_hold = list( "/obj/item/device/healthanalyzer", "/obj/item/weapon/dnainjector", @@ -129,6 +131,7 @@ desc = "Can hold various botanical supplies." icon_state = "botanybelt" item_state = "botany" + use_item_overlays = 1 can_hold = list( "/obj/item/device/analyzer/plant_analyzer", "/obj/item/weapon/minihoe", @@ -136,8 +139,8 @@ "/obj/item/weapon/reagent_containers/glass/fertilizer", "/obj/item/weapon/reagent_containers/glass/bottle", "/obj/item/weapon/plantspray", - "/obj/item/weapon/reagent_containers/syringe", - "/obj/item/weapon/reagent_containers/glass/beaker", +// "/obj/item/weapon/reagent_containers/syringe", +// "/obj/item/weapon/reagent_containers/glass/beaker", "/obj/item/weapon/lighter/zippo", "/obj/item/weapon/storage/fancy/cigarettes", "obj/item/weapon/rollingpaperpack", @@ -195,6 +198,7 @@ icon_state = "soulstonebelt" item_state = "soulstonebelt" storage_slots = 6 + use_item_overlays = 1 can_hold = list( "/obj/item/device/soulstone" ) @@ -240,6 +244,7 @@ item_state = "janibelt" storage_slots = 6 max_w_class = 4 // Set to this so the light replacer can fit. + use_item_overlays = 1 can_hold = list( "/obj/item/weapon/grenade/chem_grenade/cleaner", "/obj/item/device/lightreplacer", @@ -310,6 +315,21 @@ new /obj/item/ammo_casing/shotgun/beanbag(src) new /obj/item/ammo_casing/shotgun/beanbag(src) +/obj/item/weapon/storage/belt/bandolier/update_icon() + ..() + icon_state = "[initial(icon_state)]_[contents.len]" + +/obj/item/weapon/storage/belt/bandolier/attackby(obj/item/W, mob/user) + var/amount = contents.len + . = ..() + if(amount != contents.len) + update_icon() + +/obj/item/weapon/storage/belt/bandolier/remove_from_storage(obj/item/W as obj, atom/new_location) + ..() + update_icon() + + /obj/item/weapon/storage/belt/holster name = "shoulder holster" desc = "A holster to conceal a carried handgun. WARNING: Badasses only." @@ -328,6 +348,7 @@ icon_state = "soulstonebelt" item_state = "soulstonebelt" storage_slots = 6 + use_item_overlays = 1 can_hold = list( "/obj/item/weapon/gun/magic/wand" ) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 1dde63d198a..af927acf19a 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -20,34 +20,34 @@ attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/card/id)) if(src.broken) - to_chat(user, "\red It appears to be broken.") + to_chat(user, "It appears to be broken.") return if(src.allowed(user)) src.locked = !( src.locked ) if(src.locked) src.icon_state = src.icon_locked - to_chat(user, "\red You lock the [src.name]!") + to_chat(user, "You lock the [src.name]!") return else src.icon_state = src.icon_closed - to_chat(user, "\red You unlock the [src.name]!") + to_chat(user, "You unlock the [src.name]!") origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D. return else - to_chat(user, "\red Access Denied") + to_chat(user, "Access Denied") else if((istype(W, /obj/item/weapon/card/emag) || istype(W, /obj/item/weapon/melee/energy/blade)) && !broken) emag_act(user) return if(!locked) ..() else - to_chat(user, "\red Its locked!") + to_chat(user, "It's locked!") return show_to(mob/user as mob) if(locked) - to_chat(user, "\red Its locked!") + to_chat(user, "It's locked!") else ..() return diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 59fac1b18c4..dba3fb620e3 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -156,14 +156,19 @@ // ----------------------------- /obj/item/weapon/storage/secure/briefcase name = "secure briefcase" + desc = "A large briefcase with a digital locking system." icon = 'icons/obj/storage.dmi' icon_state = "secure" item_state = "sec-case" - desc = "A large briefcase with a digital locking system." + flags = CONDUCT + hitsound = "swing_hit" force = 8.0 - throw_speed = 1 + throw_speed = 2 throw_range = 4 w_class = 4.0 + max_w_class = 3 + max_combined_w_class = 21 + attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") New() ..() diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index d92ad2399b2..9bbc26017be 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -151,6 +151,7 @@ for(var/obj/O in src.contents) O.screen_loc = "[cx],[cy]" O.layer = 20 + O.plane = HUD_PLANE cx++ if (cx > mx) cx = tx @@ -170,6 +171,7 @@ ND.sample_object.screen_loc = "[cx]:16,[cy]:16" ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]" ND.sample_object.layer = 20 + ND.sample_object.plane = HUD_PLANE cx++ if (cx > (4+cols)) cx = 4 @@ -180,6 +182,7 @@ O.screen_loc = "[cx]:16,[cy]:16" O.maptext = "" O.layer = 20 + O.plane = HUD_PLANE cx++ if (cx > (4+cols)) cx = 4 @@ -337,8 +340,10 @@ W.dropped(usr) if(ismob(new_location)) W.layer = 20 + W.plane = HUD_PLANE else W.layer = initial(W.layer) + W.plane = initial(W.plane) W.loc = new_location else W.loc = get_turf(src) @@ -445,6 +450,7 @@ src.closer.master = src src.closer.icon_state = "x" src.closer.layer = 20 + src.closer.plane = HUD_PLANE orient2hud() return diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 46342d78a99..3dc3cdef9a5 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -45,7 +45,7 @@ icon = src.loc if (!in_range(src, user)) if (icon == src) - to_chat(user, "\blue It's \a \icon[icon][src]! If you want any more information you'll need to get closer.") + to_chat(user, "\blue It's \a [bicon(icon)][src]! If you want any more information you'll need to get closer.") return var/celsius_temperature = src.air_contents.temperature-T0C @@ -64,7 +64,7 @@ else descriptive = "furiously hot" - to_chat(user, "\blue \The \icon[icon][src] feels [descriptive]") + to_chat(user, "\blue \The [bicon(icon)][src] feels [descriptive]") return @@ -89,10 +89,6 @@ if ((istype(W, /obj/item/device/analyzer)) && get_dist(user, src) <= 1) atmosanalyzer_scan(air_contents, user) - else if (istype(W,/obj/item/latexballon)) - var/obj/item/latexballon/LB = W - LB.blow(src) - if(istype(W, /obj/item/device/assembly_holder)) bomb_assemble(W,user) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 3ab237084e6..29bcb4f8fe2 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -222,6 +222,10 @@ icon_state = "dualsaber0" /obj/item/weapon/twohanded/dualsaber/attack(target as mob, mob/living/user as mob) + if(HULK in user.mutations) + to_chat(user, "You grip the blade too hard and accidentally close it!") + unwield() + return ..() if((CLUMSY in user.mutations) && (wielded) &&prob(40)) to_chat(user, "\red You twirl around a bit before losing your balance and impaling yourself on the [src].") @@ -259,7 +263,10 @@ if(wielded) return 1 -/obj/item/weapon/twohanded/dualsaber/wield() +/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds. + if(HULK in M.mutations) + to_chat(M, "You lack the grace to wield this!") + return ..() hitsound = 'sound/weapons/blade1.ogg' diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 42a2541f0bf..44048f5113c 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -418,4 +418,9 @@ if(istype(src.loc, /obj/structure/bigDelivery)) //nullspace ect.. read the comment above var/obj/structure/bigDelivery/BD = src.loc BD.attack_hand(usr) - open() \ No newline at end of file + open() + +/obj/structure/closet/tesla_act(var/power) + ..() + visible_message("[src] is blown apart by the bolt of electricity!", "You hear a metallic screeching sound.") + qdel(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 4a2ced79339..2b823041950 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -115,7 +115,7 @@ new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/storage/belt/security/sec(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/energy/hos(src) + new /obj/item/weapon/gun/energy/gun/hos(src) new /obj/item/weapon/door_remote/head_of_security(src) @@ -152,9 +152,10 @@ new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/gun/energy/advtaser(src) + new /obj/item/weapon/gun/energy/gun/advtaser(src) new /obj/item/weapon/storage/belt/security/sec(src) new /obj/item/weapon/storage/box/holobadge(src) + new /obj/item/clothing/gloves/color/black/krav_maga/sec(src) diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index 9b5cb514558..0cccd860b04 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -50,6 +50,9 @@ new /obj/item/clothing/head/beret/sec(src) new /obj/item/clothing/head/beret/sec(src) new /obj/item/clothing/head/beret/sec(src) + new /obj/item/clothing/head/officer(src) + new /obj/item/clothing/head/officer(src) + new /obj/item/clothing/head/officer(src) /obj/structure/closet/redcorp name = "corporate security wardrobe" @@ -170,9 +173,9 @@ new /obj/item/clothing/under/rank/atmospheric_technician(src) new /obj/item/clothing/under/rank/atmospheric_technician(src) new /obj/item/clothing/under/rank/atmospheric_technician(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) - new /obj/item/clothing/shoes/black(src) + new /obj/item/clothing/shoes/workboots(src) + new /obj/item/clothing/shoes/workboots(src) + new /obj/item/clothing/shoes/workboots(src) new /obj/item/clothing/head/hardhat/red(src) new /obj/item/clothing/head/hardhat/red(src) new /obj/item/clothing/head/hardhat/red(src) @@ -192,9 +195,9 @@ new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/under/rank/engineer(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) - new /obj/item/clothing/shoes/orange(src) + new /obj/item/clothing/shoes/workboots(src) + new /obj/item/clothing/shoes/workboots(src) + new /obj/item/clothing/shoes/workboots(src) new /obj/item/clothing/head/hardhat(src) new /obj/item/clothing/head/hardhat(src) new /obj/item/clothing/head/hardhat(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 90a95253a96..74709df5810 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -128,7 +128,7 @@ var/global/list/captain_display_cases = list() ..(user) to_chat(user, "Peering through the glass, you see that it contains:") if(occupant) - to_chat(user, "\icon[occupant] \A [occupant].") + to_chat(user, "[bicon(occupant)] \A [occupant].") else to_chat(user, "Nothing.") @@ -217,9 +217,9 @@ var/global/list/captain_display_cases = list() return locked = !locked if(!locked) - to_chat(user, "\icon[src] \The [src] clicks as locks release, and it slowly opens for you.") + to_chat(user, "[bicon(src)] \The [src] clicks as locks release, and it slowly opens for you.") else - to_chat(user, "\icon[src] You close \the [src] and swipe your card, locking it.") + to_chat(user, "[bicon(src)] You close \the [src] and swipe your card, locking it.") update_icon() return if(istype(W,/obj/item/weapon/crowbar) && (!locked || destroyed)) @@ -305,7 +305,7 @@ var/global/list/captain_display_cases = list() dump() update_icon() else - to_chat(src, "\icon[src] \The [src] is empty!") + to_chat(src, "[bicon(src)] \The [src] is empty!") else user.visible_message("[user.name] gently runs his hands over \the [src] in appreciation of its contents.", \ "You gently run your hands over \the [src] in appreciation of its contents.", \ diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index ab167113178..b5aff72fd6c 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -191,20 +191,34 @@ icon_state = "fullgrass_[rand(1, 3)]" -/obj/structure/flora/kirbyplants +/obj/item/weapon/twohanded/required/kirbyplants name = "potted plant" icon = 'icons/obj/flora/plants.dmi' icon_state = "plant-1" anchored = 0 layer = 5 + w_class = 5 + force = 10 + throwforce = 13 + throw_speed = 2 + throw_range = 4 -/obj/structure/flora/kirbyplants/New() +/obj/item/weapon/twohanded/required/kirbyplants/New() ..() icon_state = "plant-[rand(1,35)]" if(prob(1)) icon_state = "plant-36" -/obj/structure/flora/kirbyplants/dead +/obj/item/weapon/twohanded/required/kirbyplants/equipped(mob/living/user) + var/image/I = image(icon = 'icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user) + I.override = 1 + user.add_alt_appearance("sneaking_mission", I, player_list) + +/obj/item/weapon/twohanded/required/kirbyplants/dropped(mob/living/user) + ..() + user.remove_alt_appearance("sneaking_mission") + +/obj/item/weapon/twohanded/required/kirbyplants/dead name = "\improper RD's potted plant" desc = "A gift from the botanical staff, presented after the RD's reassignment. There's a tag on it that says \"Y'all come back now, y'hear?\"\nIt doesn't look very healthy..." icon_state = "plant-dead" diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 39fb502d10b..133a3d15b39 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -3,6 +3,7 @@ desc = "A sturdy metal ladder." icon = 'icons/obj/structures.dmi' icon_state = "ladder11" + anchored = 1 var/id = null var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher var/obj/structure/ladder/down = null //the ladder below this one diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index c8e600c658d..fbe267e0779 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -23,7 +23,7 @@ /obj/structure/mopbucket/examine(mob/user) if(..(user, 1)) - to_chat(usr, text("\icon[] [] contains [] units of water left!", src, src.name, src.reagents.total_volume)) + to_chat(usr, "[bicon(src)] [src] contains [reagents.total_volume] units of water left!") /obj/structure/mopbucket/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if (istype(W, /obj/item/weapon/mop)) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index ecf2324673d..f13bffb9d44 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -16,7 +16,7 @@ var/movable = 0 // For mobility checks /obj/structure/stool/bed/MouseDrop(atom/over_object) - ..(over_object, 1) + ..(over_object, skip_fucking_stool_shit = 1) /obj/structure/stool/psychbed name = "psych bed" diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index efdadfbb7c2..6ff52f09deb 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -34,7 +34,7 @@ qdel(src) return -/obj/structure/stool/MouseDrop(atom/over_object, skip_fucking_stool_shit = 0) +/obj/structure/stool/MouseDrop(atom/over_object, src_location, over_location, src_control, over_control, params, skip_fucking_stool_shit = 0) if(skip_fucking_stool_shit) return ..(over_object) if (istype(over_object, /mob/living/carbon/human)) @@ -44,7 +44,7 @@ S.origin = src src.loc = S H.put_in_hands(S) - H.visible_message("\red [H] grabs [src] from the floor!", "\red You grab [src] from the floor!") + H.visible_message("[H] grabs [src] from the floor!", "You grab [src] from the floor!") /obj/item/weapon/stool name = "stool" @@ -60,12 +60,12 @@ ..() origin.loc = get_turf(src) user.unEquip(src) - user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.") + user.visible_message("[user] puts [src] down.", "You put [src] down.") qdel(src) /obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) if (prob(5) && istype(M,/mob/living)) - user.visible_message("\red [user] breaks [src] over [M]'s back!.") + user.visible_message("[user] breaks [src] over [M]'s back!.") user.unEquip(src) var/obj/item/stack/sheet/metal/m = new/obj/item/stack/sheet/metal m.loc = get_turf(src) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index dde2107ae70..bdf94263c8e 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -208,7 +208,7 @@ if(!G.confirm()) return 0 G.affecting.forceMove(get_turf(src)) - G.affecting.Weaken(5) + G.affecting.Weaken(2) G.affecting.visible_message("[G.assailant] pushes [G.affecting] onto [src].", \ "[G.assailant] pushes [G.affecting] onto [src].") add_logs(G.affecting, G.assailant, "pushed onto a table") diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 3fcfc0ef4bf..efef25723a5 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -63,8 +63,11 @@ return var/obj/item/weapon/reagent_containers/RG = I if(RG.is_open_container()) - RG.reagents.add_reagent("toiletwater", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) - to_chat(user, "You fill [RG] from [src]. Gross.") + if(RG.reagents.total_volume >= RG.volume) + to_chat(user, "\The [RG] is full.") + else + RG.reagents.add_reagent("toiletwater", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this)) + to_chat(user, "You fill [RG] from [src]. Gross.") return if(istype(I, /obj/item/weapon/grab)) diff --git a/code/game/response_team.dm b/code/game/response_team.dm index 241e317c24b..d9b8cfcc375 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -382,7 +382,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest/ert/security(M), slot_wear_suit) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/advtaser(M), slot_s_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(M), slot_s_store) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/ert/security(M), slot_in_backpack) @@ -459,7 +459,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(M), slot_shoes) M.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/rig/ert/security(M), slot_wear_suit) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/advtaser(M), slot_s_store) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(M), slot_s_store) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/security/sunglasses(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/security(M), slot_in_backpack) @@ -532,7 +532,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/rcd_ammo/large(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/device/t_scanner/extended_range(M), slot_l_store) M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store) @@ -553,7 +553,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/ionrifle/carbine(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/carbine(M), slot_r_hand) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/carbine(M), slot_r_hand) if("Medic") M.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat/swat(M), slot_shoes) @@ -566,7 +566,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/rig/ert/medical(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/surgery(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_l_store) M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store) @@ -585,7 +585,7 @@ var/send_emergency_team M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/sechailer/swat(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/restraints/handcuffs(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/storage/lockbox/loyalty(M), slot_in_backpack) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol(M), slot_in_backpack) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_in_backpack) M.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(M), slot_l_store) M.equip_to_slot_or_del(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_r_store) @@ -610,4 +610,4 @@ var/send_emergency_team new /obj/item/device/radio/centcom( src ) new /obj/item/weapon/reagent_containers/food/pill/salicylic( src ) new /obj/item/weapon/reagent_containers/food/pill/patch/synthflesh( src ) - return \ No newline at end of file + return diff --git a/code/game/sound.dm b/code/game/sound.dm index cecf12c657d..1890a0966e7 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -9,8 +9,9 @@ var/list/jackboot_sound = list('sound/effects/jackboot1.ogg','sound/effects/jack var/list/swing_hit_sound = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg') var/list/hiss_sound = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') var/list/page_sound = list('sound/effects/pageturn1.ogg', 'sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg') -//var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') +var/list/gun_sound = list('sound/weapons/Gunshot.ogg', 'sound/weapons/Gunshot2.ogg','sound/weapons/Gunshot3.ogg','sound/weapons/Gunshot4.ogg') var/list/computer_ambience = list('sound/goonstation/machines/ambicomp1.ogg', 'sound/goonstation/machines/ambicomp2.ogg', 'sound/goonstation/machines/ambicomp3.ogg') +var/list/ricochet = list('sound/weapons/effects/ric1.ogg', 'sound/weapons/effects/ric2.ogg','sound/weapons/effects/ric3.ogg','sound/weapons/effects/ric4.ogg','sound/weapons/effects/ric5.ogg') /proc/playsound(var/atom/source, soundin, vol as num, vary, extrarange as num, falloff, var/is_global, var/pitch) @@ -107,17 +108,32 @@ var/const/FALLOFF_SOUNDS = 0.5 /proc/get_sfx(soundin) if(istext(soundin)) switch(soundin) - if ("shatter") soundin = pick(shatter_sound) - if ("explosion") soundin = pick(explosion_sound) - if ("sparks") soundin = pick(spark_sound) - if ("rustle") soundin = pick(rustle_sound) - if ("bodyfall") soundin = pick(bodyfall_sound) - if ("punch") soundin = pick(punch_sound) - if ("clownstep") soundin = pick(clown_sound) - if ("jackboot") soundin = pick(jackboot_sound) - if ("swing_hit") soundin = pick(swing_hit_sound) - if ("hiss") soundin = pick(hiss_sound) - if ("pageturn") soundin = pick(page_sound) - //if ("gunshot") soundin = pick(gun_sound) - if("computer_ambience") soundin = pick(computer_ambience) + if ("shatter") + soundin = pick(shatter_sound) + if ("explosion") + soundin = pick(explosion_sound) + if ("sparks") + soundin = pick(spark_sound) + if ("rustle") + soundin = pick(rustle_sound) + if ("bodyfall") + soundin = pick(bodyfall_sound) + if ("punch") + soundin = pick(punch_sound) + if ("clownstep") + soundin = pick(clown_sound) + if ("jackboot") + soundin = pick(jackboot_sound) + if ("swing_hit") + soundin = pick(swing_hit_sound) + if ("hiss") + soundin = pick(hiss_sound) + if ("pageturn") + soundin = pick(page_sound) + if ("gunshot") + soundin = pick(gun_sound) + if("computer_ambience") + soundin = pick(computer_ambience) + if("ricochet") + soundin = pick(ricochet) return soundin diff --git a/code/game/turfs/unsimulated.dm b/code/game/turfs/unsimulated.dm index a99c18ab230..5c9509a3d68 100644 --- a/code/game/turfs/unsimulated.dm +++ b/code/game/turfs/unsimulated.dm @@ -7,6 +7,12 @@ /turf/unsimulated/can_lay_cable() return 0 +/turf/unsimulated/floor/plating/vox + icon_state = "plating" + name = "plating" + nitrogen = 100 + oxygen = 0 + /turf/unsimulated/floor/plating/snow name = "snow" icon = 'icons/turf/snow.dmi' diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm index b4e8842a840..f63535fb082 100644 --- a/code/game/turfs/unsimulated/floor.dm +++ b/code/game/turfs/unsimulated/floor.dm @@ -35,4 +35,9 @@ /turf/unsimulated/floor/abductor/New() ..() - icon_state = "alienpod[rand(1,9)]" \ No newline at end of file + icon_state = "alienpod[rand(1,9)]" + +/turf/unsimulated/floor/vox + icon_state = "dark" + nitrogen = 100 + oxygen = 0 \ No newline at end of file diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index ef5d4bf3de3..fa0059618bd 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -72,7 +72,8 @@ var/list/admin_verbs_admin = list( /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ /client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */ /client/proc/debug_variables, - /client/proc/show_snpc_verbs + /client/proc/show_snpc_verbs, + /client/proc/reset_all_tcs /*resets all telecomms scripts*/ ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -158,7 +159,8 @@ var/list/admin_verbs_debug = list( /client/proc/cinematic, /proc/machine_upgrade, /client/proc/map_template_load, - /client/proc/map_template_upload + /client/proc/map_template_upload, + /client/proc/view_runtimes ) var/list/admin_verbs_possess = list( /proc/possess, diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 090955de57a..865ea301800 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1205,6 +1205,7 @@ if(I) I.loc = locker I.layer = initial(I.layer) + I.plane = initial(I.plane) I.dropped(M) M.update_icons() @@ -1266,6 +1267,7 @@ if(I) I.loc = M.loc I.layer = initial(I.layer) + I.plane = initial(I.plane) I.dropped(M) M.Paralyse(5) @@ -1295,6 +1297,7 @@ if(I) I.loc = M.loc I.layer = initial(I.layer) + I.plane = initial(I.plane) I.dropped(M) M.Paralyse(5) @@ -1346,6 +1349,7 @@ if(I) I.loc = M.loc I.layer = initial(I.layer) + I.plane = initial(I.plane) I.dropped(M) if(istype(M, /mob/living/carbon/human)) @@ -1671,10 +1675,109 @@ message_admins("[key_name_admin(src.owner)] replied to [key_name_admin(H)]'s Centcom message with: \"[input]\"") to_chat(H, "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from Central Command. Message as follows. [input]. Message ends.\"") + else if(href_list["EvilFax"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["EvilFax"]) + if(!istype(H)) + to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") + return + var/etypes = list("borging","corgifying","firedeath","braindeath","honktumor","demotion") + var/eviltype = input(src.owner, "Which type of evil fax do you wish to send [H]?","Its good to be baaaad...", "") as null|anything in etypes + if(!(eviltype in etypes)) + return + var/customname = input(src.owner, "Pick a title for the evil fax.", "Fax Title") as text|null + if(!customname) + customname = "paper" + var/obj/item/weapon/paper/evilfax/P = new /obj/item/weapon/paper/evilfax(null) + var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + + P.name = "Central Command - [customname]" + P.info = "A reminder: per the terms of your contract, stupid faxes will get you demoted, or worse." + P.myeffect = eviltype + P.mytarget = H + if(alert("Do you want the Evil Fax to activate automatically if [H] tries to ignore it?",,"Yes", "No") == "Yes") + P.activate_on_timeout = 1 + P.x = rand(-2, 0) + P.y = rand(-1, 2) + P.offset_x += P.x + P.offset_y += P.y + P.update_icon() + var/stampvalue = "cent" + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.icon_state = "paper_stamp-[stampvalue]" + stampoverlay.pixel_x = P.x + stampoverlay.pixel_y = P.y + P.stamped = list() + P.stamped += /obj/item/weapon/stamp/centcom + if(!P.ico) + P.ico = new + P.ico += "paper_stamp-[stampvalue]" + P.overlays += stampoverlay + P.stamps += "
    " + P.update_icon() + //fax.receivefax(P) // this does not work, it does not preserve the type, we have to physically teleport the fax paper instead + P.loc = fax.loc + if(istype(H) && H.stat == CONSCIOUS && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset))) + to_chat(H, "Your headset pings, notifying you that a reply to your fax has arrived.") + to_chat(src.owner, "You sent a [eviltype] fax to [H]") + log_admin("[key_name(src.owner)] sent [key_name(H)] a [eviltype] fax") + message_admins("[key_name_admin(src.owner)] replied to [key_name_admin(H)] with a [eviltype] fax") + else if(href_list["FaxReplyTemplate"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locate(href_list["FaxReplyTemplate"]) + if(!istype(H)) + to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") + return + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(null) + var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + P.name = "Central Command - paper" + var/stypes = list("handle it yourself","illegible","not signed","sorry, not right now","stop wasting our time") + var/stype = input(src.owner, "Which type of standard reply do you wish to send to [H]?","Choose your paperwork", "") as null|anything in stypes + var/tmsg = "



    NanoTrasen Science Station Cyberiad


    NAS Trurl Communications Department Report


    " + if(stype == "handle it yourself") + tmsg += "Greetings, esteemed crewmember. Your fax has been DECLINED automatically by NAS Trurl Fax Registration.

    Please proceed in accordance with Standard Operating Procedure and/or Space Law. You are fully trained to handle this situation without Central Command intervention." + else if(stype == "illegible") + tmsg += "Greetings, esteemed crewmember. Your fax has been DECLINED automatically by NAS Trurl Fax Registration.

    Your fax was too poorly written for our system to interpret." + else if(stype == "not signed") + tmsg += "Greetings, esteemed crewmember. Your fax has been DECLINED automatically by NAS Trurl Fax Registration.

    Your fax was not properly signed and/or stamped." + else if(stype == "sorry, not right now") + tmsg += "Greetings, esteemed crewmember. Unfortunately, we are unable to spare the resources to assist you at this time." + else if(stype == "stop wasting our time") + tmsg += "Stop wasting our time." + else + return + tmsg += "
    " + P.info = tmsg + P.x = rand(-2, 0) + P.y = rand(-1, 2) + P.offset_x += P.x + P.offset_y += P.y + P.update_icon() + var/stampvalue = "cent" + var/image/stampoverlay = image('icons/obj/bureaucracy.dmi') + stampoverlay.icon_state = "paper_stamp-[stampvalue]" + stampoverlay.pixel_x = P.x + stampoverlay.pixel_y = P.y + P.stamped = list() + P.stamped += /obj/item/weapon/stamp/centcom + if(!P.ico) + P.ico = new + P.ico += "paper_stamp-[stampvalue]" + P.overlays += stampoverlay + P.stamps += "
    " + P.update_icon() + fax.receivefax(P) + if(istype(H) && H.stat == CONSCIOUS && (istype(H.l_ear, /obj/item/device/radio/headset) || istype(H.r_ear, /obj/item/device/radio/headset))) + to_chat(H, "Your headset pings, notifying you that a reply to your fax has arrived.") + to_chat(src.owner, "You sent a standard '[stype]' fax to [H]") + log_admin("[key_name(src.owner)] sent [key_name(H)] a standard '[stype]' fax") + message_admins("[key_name_admin(src.owner)] replied to [key_name_admin(H)] with a standard '[stype]' fax") + else if(href_list["SyndicateReply"]) if(!check_rights(R_ADMIN)) return - var/mob/living/carbon/human/H = locate(href_list["SyndicateReply"]) if(!istype(H)) to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") @@ -1685,10 +1788,9 @@ if(!istype(H.l_ear, /obj/item/device/radio/headset) && !istype(H.r_ear, /obj/item/device/radio/headset)) to_chat(usr, "The person you are trying to contact is not wearing a headset") return - var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from The Syndicate", "") - if(!input) return - + if(!input) + return to_chat(src.owner, "You sent [input] to [H] via a secure channel.") log_admin("[src.owner] replied to [key_name(H)]'s Syndicate message with the message [input].") to_chat(H, "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your benefactor. Message as follows, agent. [input]. Message ends.\"") @@ -2264,6 +2366,7 @@ W.loc = H.loc W.dropped(H) W.layer = initial(W.layer) + W.plane = initial(W.plane) //teleport person to cell H.loc = pick(prisonwarp) H.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(H), slot_w_uniform) @@ -2483,7 +2586,7 @@ for(var/obj/item/W in world) if(istype(W, /obj/item/clothing) || istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/weapon/disk) || istype(W, /obj/item/weapon/tank)) continue - W.icon = 'icons/obj/gun.dmi' + W.icon = 'icons/obj/guns/projectile.dmi' W.icon_state = "revolver" W.item_state = "gun" message_admins("[key_name_admin(usr)] made every item look like a gun") @@ -2930,6 +3033,16 @@ Secrets(usr) return 1 + else if(href_list["viewruntime"]) + var/datum/ErrorViewer/error_viewer = locate(href_list["viewruntime"]) + if(!istype(error_viewer)) + to_chat(usr, "That runtime viewer no longer exists.") + return + if(href_list["viewruntime_backto"]) + error_viewer.showTo(usr, locate(href_list["viewruntime_backto"]), href_list["viewruntime_linear"]) + else + error_viewer.showTo(usr, null, href_list["viewruntime_linear"]) + /proc/admin_jump_link(var/atom/target, var/source) if(!target) return // The way admin jump links handle their src is weirdly inconsistent... diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 6b3c78cf954..b85d19451fe 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -690,7 +690,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/thunderdome(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(M), slot_r_hand) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/destroyer(M), slot_r_hand) M.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife(M), slot_l_hand) M.equip_to_slot_or_del(new /obj/item/weapon/grenade/smokebomb(M), slot_r_store) @@ -881,7 +881,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_or_collect(pda, slot_r_store) M.equip_or_collect(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse_rifle/pistol(M), slot_belt) + M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card (Nanotrasen Navy Officer)" @@ -904,7 +904,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_or_collect(pda, slot_r_store) M.equip_or_collect(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store) - M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse_rifle/pistol(M), slot_belt) + M.equip_or_collect(new /obj/item/weapon/gun/energy/pulse/pistol(M), slot_belt) var/obj/item/weapon/card/id/centcom/W = new(M) W.name = "[M.real_name]'s ID Card (Nanotrasen Navy Captain)" @@ -967,7 +967,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/cyber(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store) M.equip_to_slot_or_del(new /obj/item/weapon/twohanded/dualsaber/red(M), slot_l_store) @@ -996,7 +996,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/cyber(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/cohiba(M), slot_wear_mask) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse/pistol/m1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) M.equip_to_slot_or_del(new /obj/item/weapon/storage/box/matches(M), slot_r_store) M.equip_or_collect(new /obj/item/weapon/melee/classic_baton/telescopic(M), slot_l_store) @@ -1233,4 +1233,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that assets.register() // Clear the user's cache so they get resent. - usr.client.cache = list() \ No newline at end of file + usr.client.cache = list() + +/client/proc/view_runtimes() + set category = "Debug" + set name = "View Runtimes" + set desc = "Open the Runtime Viewer" + + if(!check_rights(R_DEBUG)) + return + + error_cache.showTo(usr) diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm index 75fc6af84d9..dd37a828302 100644 --- a/code/modules/admin/verbs/honksquad.dm +++ b/code/modules/admin/verbs/honksquad.dm @@ -121,7 +121,7 @@ var/global/sent_honksquad = 0 if(prob(50)) equip_to_slot_or_del(new /obj/item/weapon/gun/energy/clown(src), slot_in_backpack) else - equip_to_slot_or_del(new /obj/item/weapon/gun/grenadelauncher/piecannon(src), slot_in_backpack) + equip_to_slot_or_del(new /obj/item/weapon/gun/throw/piecannon(src), slot_in_backpack) src.mutations.Add(CLUMSY) @@ -134,4 +134,4 @@ var/global/sent_honksquad = 0 W.registered_name = real_name equip_to_slot_or_del(W, slot_wear_id) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm index 185d513d2fc..c861531714c 100644 --- a/code/modules/admin/verbs/massmodvar.dm +++ b/code/modules/admin/verbs/massmodvar.dm @@ -72,7 +72,7 @@ else if(isicon(var_value)) to_chat(usr, "Variable appears to be ICON.") - var_value = "\icon[var_value]" + var_value = "[bicon(var_value)]" default = "icon" else if(istype(var_value,/atom) || istype(var_value,/datum)) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 966e584f15e..a6aa95a359d 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -328,7 +328,7 @@ var/list/forbidden_varedit_object_types = list( if(default == "num") dir = 1 else if(default == "icon") - var_value = "\icon[var_value]" + var_value = "[bicon(var_value)]" to_chat(usr, "Variable contains: [var_value]") if(dir) @@ -465,7 +465,7 @@ var/list/forbidden_varedit_object_types = list( else if(isicon(variable)) to_chat(usr, "Variable appears to be ICON.") - variable = "\icon[variable]" + variable = "[bicon(variable)]" class = "icon" else if(istype(variable,/matrix)) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 46972243a06..5fb8335732d 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -485,6 +485,8 @@ client/proc/one_click_antag() break new_vox.key = theghost.key + ticker.mode.traitors += new_vox.mind + to_chat(new_vox, "\blue You are a Vox Primalis, fresh out of the Shoal. Your ship has arrived at the Tau Ceti system hosting the NSV Exodus... or was it the Luna? NSS? Utopia? Nobody is really sure, but everyong is raring to start pillaging! Your current goal is: \red [input]") to_chat(new_vox, "\red Don't forget to turn on your nitrogen internals!") @@ -497,9 +499,6 @@ client/proc/one_click_antag() /datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0) - var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox") - var/obj/item/organ/external/head/head_organ = new_vox.get_organ("head") - var/sounds = rand(2,8) var/i = 0 var/newname = "" @@ -508,17 +507,21 @@ client/proc/one_click_antag() i++ newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) + var/mob/living/carbon/human/new_vox = new /mob/living/carbon/human/vox(spawn_location.loc) + + new_vox.add_language("Tradeband") new_vox.real_name = capitalize(newname) + new_vox.dna.real_name = new_vox.real_name new_vox.name = new_vox.real_name new_vox.age = rand(12,20) - new_vox.set_species("Vox") - new_vox.languages = list() // Removing language from chargen. new_vox.flavor_text = "" - new_vox.add_language("Vox-pidgin") - new_vox.add_language("Galactic Common") - new_vox.add_language("Tradeband") - head_organ.h_style = "Short Vox Quills" - head_organ.f_style = "Shaved" + new_vox.change_eye_color(rand(1, 255), rand(1, 255), rand(1, 255)) + new_vox.s_tone = rand(1, 6) + + // Do the initial caching of the player's body icons. + new_vox.force_update_limbs() + new_vox.update_dna() + new_vox.update_eyes() for(var/obj/item/organ/external/limb in new_vox.organs) limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) @@ -529,8 +532,8 @@ client/proc/one_click_antag() I.implanted = 1 cortical_stacks += I - ticker.mode.traitors += new_vox.mind new_vox.equip_vox_raider() + new_vox.regenerate_icons() return new_vox diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 0ef6a64373f..caed1de43af 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -13,12 +13,11 @@ return var/image/cross = image('icons/obj/storage.dmi',"bible") - msg = "\blue \icon[cross] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, "holder")]) (CA) (SC): [msg]" + msg = "\blue [bicon(cross)] PRAY: [key_name(src, 1)] (?) (PP) (VV) (SM) ([admin_jump_link(src, "holder")]) (CA) (SC): [msg]" for(var/client/X in admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) - to_chat(usr, "Your prayers have been received by the gods.") feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -27,41 +26,46 @@ /proc/Centcomm_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) msg = "\blue CENTCOMM: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]" - for(var/client/X in admins) if(R_EVENT & X.holder.rights) to_chat(X, msg) + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' /proc/Syndicate_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) msg = "\blue SYNDICATE: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]" - for(var/client/X in admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' /proc/HONK_announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) msg = "\blue HONK: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]" - for(var/client/X in admins) if(R_EVENT & X.holder.rights) to_chat(X, msg) + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' /proc/ERT_Announce(var/text , var/mob/Sender) var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) msg = "\blue ERT REQUEST: [key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (REPLY): [msg]" - for(var/client/X in admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' /proc/Nuke_request(text , mob/Sender) var/nuke_code = get_nuke_code() var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) msg = "NUKE CODE REQUEST: [key_name(Sender)] (PP) (VV) (SM) ([admin_jump_link(Sender, "holder")]) (CA) (BSA) (RPLY): [msg]" - for(var/client/X in admins) if(check_rights(R_EVENT,0,X.mob)) to_chat(X, msg) to_chat(X, "The nuke code is [nuke_code].") + if(X.prefs.sound & SOUND_ADMINHELP) + X << 'sound/effects/adminhelp.ogg' \ No newline at end of file diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c236432e9d2..044a64211c8 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -868,6 +868,30 @@ Traitors and the like can also be revived with the previous role mostly intact. message_admins("Admin [key_name_admin(usr)] has disabled random events.", 1) feedback_add_details("admin_verb","TRE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/reset_all_tcs() + set category = "Admin" + set name = "Reset Telecomms Scripts" + set desc = "Blanks all telecomms scripts from all telecomms servers" + + if(!holder || !holder.rights || !holder.rights & R_ADMIN) + to_chat(usr, "Admin only.") + return + + var/confirm = alert(src, "You sure you want to blank all NTSL scripts?", "Confirm", "Yes", "No") + if(confirm != "Yes") + return + + for(var/obj/machinery/telecomms/server/S in telecomms_list) + var/datum/TCS_Compiler/C = S.Compiler + S.rawcode = "" + C.Compile("") + for(var/obj/machinery/computer/telecomms/traffic/T in machines) + T.storedcode = "" + log_admin("[key_name(usr)] blanked all telecomms scripts.") + message_admins("[key_name_admin(usr)] blanked all telecomms scripts.") + feedback_add_details("admin_verb","RAT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + /client/proc/toggle_ert_calling() set category = "Event" set name = "Toggle ERT" @@ -886,4 +910,3 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(usr, "\red ERT has been Disabled.") log_admin("Admin [key_name(src)] has disabled ERT calling.") message_admins("Admin [key_name_admin(usr)] has disabled ERT calling.", 1) - diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index a5b98bc888c..142bb8203cd 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -154,7 +154,7 @@ var/global/sent_strike_team = 0 equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(src), slot_s_store) equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(src), slot_belt) - equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand) + equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse(src), slot_r_hand) var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)//Here you go Deuryn @@ -170,4 +170,4 @@ var/global/sent_strike_team = 0 W.registered_name = real_name equip_to_slot_or_del(W, slot_wear_id) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm index 6131962b881..054b5469d9b 100644 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ b/code/modules/admin/verbs/striketeam_syndicate.dm @@ -144,7 +144,7 @@ var/global/sent_syndicate_strike_team = 0 equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back) - equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m762, slot_in_backpack) + equip_to_slot_or_del(new /obj/item/ammo_box/magazine/mm556x45) equip_to_slot_or_del(new /obj/item/ammo_box/magazine/m45(src), slot_in_backpack) equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/hypospray/combat/nanites(src), slot_in_backpack) @@ -160,7 +160,7 @@ var/global/sent_syndicate_strike_team = 0 equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/saber(src), slot_l_store) equip_to_slot_or_del(new /obj/item/weapon/grenade/empgrenade(src), slot_r_store) equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen/double/full(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol/m2411(src), slot_belt) + equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/pistol/m1911(src), slot_belt) equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/l6_saw(src), slot_r_hand) @@ -173,4 +173,4 @@ var/global/sent_syndicate_strike_team = 0 W.registered_name = real_name equip_to_slot_or_del(W, slot_wear_id) - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index c5e370f06f7..4d42358aee8 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -18,7 +18,7 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store) - var/obj/item/weapon/gun/launcher/spikethrower/W = new(src) + var/obj/item/weapon/gun/projectile/automatic/spikethrower/W = new(src) equip_to_slot_or_del(W, slot_r_hand) @@ -48,7 +48,7 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/weapon/circular_saw(src), slot_l_store) equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/medical, slot_r_hand) - equip_to_slot_or_del(new /obj/item/clothing/mask/breath(src), slot_wear_mask) + equip_to_slot_or_del(new /obj/item/clothing/mask/breath/vox(src), slot_wear_mask) equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back) equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store) @@ -77,4 +77,4 @@ var/global/vox_tick = 1 vox_tick++ if (vox_tick > 4) vox_tick = 1 - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/arcade/arcade_base.dm b/code/modules/arcade/arcade_base.dm index 2835d2451e3..0d16f8bcb9f 100644 --- a/code/modules/arcade/arcade_base.dm +++ b/code/modules/arcade/arcade_base.dm @@ -84,7 +84,7 @@ /obj/machinery/arcade/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, var/mob/user) if(cashmoney.get_total() < token_price) - to_chat(user, "\icon[cashmoney] That is not enough money.") + to_chat(user, "[bicon(cashmoney)] That is not enough money.") return 0 visible_message("[usr] inserts a credit chip into [src].") var/left = cashmoney.get_total() - token_price diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 3bf0775473c..5808109b768 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -10,6 +10,7 @@ var/status = 0 //0 - not readied //1 - bomb finished with welder var/obj/item/device/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/weapon/tank/bombtank = null //the second part of the bomb is a plasma tank + origin_tech = "materials=1;engineering=1" /obj/item/device/onetankbomb/examine(mob/user) ..(user) @@ -60,7 +61,7 @@ return /obj/item/device/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. - visible_message("\icon[src] *beep* *beep*", "*beep* *beep*") + visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") sleep(10) if(!src) return diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index f1a3f402336..7be5eac988a 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -55,7 +55,7 @@ health_scan = M.health if(health_scan <= alarm_health) pulse() - audible_message("\icon[src] *beep* *beep*", "*beep* *beep*") + audible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") toggle_scan() return return diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index a2810d04e98..26c167abcee 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -124,7 +124,7 @@ if(!secured || !on || cooldown > 0) return 0 pulse(0) - audible_message("\icon[src] *beep* *beep*", null, 3) + audible_message("[bicon(src)] *beep* *beep*", null, 3) cooldown = 2 spawn(10) process_cooldown() diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 880dc2d2218..90e86f07a6e 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -50,7 +50,7 @@ sense() if((!secured)||(!scanning)||(cooldown > 0)) return 0 pulse(0) - visible_message("\icon[src] *beep* *beep*", "*beep* *beep*") + visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") cooldown = 2 spawn(10) process_cooldown() diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 7a5835a3f9d..24fcca4e901 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -150,7 +150,7 @@ pulse(1) for(var/mob/O in hearers(1, src.loc)) - O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) + O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2) return /obj/item/device/assembly/signaler/proc/set_frequency(new_frequency) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 6797ba8f340..1c806de85ec 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -44,7 +44,7 @@ if((!secured)||(cooldown > 0)) return 0 pulse(0) if(loc) - loc.visible_message("\icon[src] *beep* *beep*", "*beep* *beep*") + loc.visible_message("[bicon(src)] *beep* *beep*", "*beep* *beep*") cooldown = 2 spawn(10) process_cooldown() diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 4c15b5f860e..af9138724e6 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -30,12 +30,12 @@ recorded_type = type listening = 0 var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("\icon[src] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"") + T.visible_message("[bicon(src)] beeps, \"Activation message is [type ? "the sound when one [recorded]" : "'[recorded]'."]\"") else if(findtext(msg, recorded) && type == recorded_type) pulse(0) var/turf/T = get_turf(src) //otherwise it won't work in hand - T.visible_message("\icon[src] \red beeps!") + T.visible_message("[bicon(src)] \red beeps!") activate() return // previously this toggled listning when not in a holder, that's a little silly. It was only called in attack_self that way. @@ -46,7 +46,7 @@ listening = !listening var/turf/T = get_turf(src) - T.visible_message("\icon[src] beeps, \"[listening ? "Now" : "No longer"] recording input.\"") + T.visible_message("[bicon(src)] beeps, \"[listening ? "Now" : "No longer"] recording input.\"") return 1 diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 8a8a4050624..48855daa8ab 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -162,7 +162,7 @@ corpseradio = /obj/item/device/radio/headset/headset_eng corpseuniform = /obj/item/clothing/under/rank/engineer corpseback = /obj/item/weapon/storage/backpack/industrial - corpseshoes = /obj/item/clothing/shoes/orange + corpseshoes = /obj/item/clothing/shoes/workboots corpsebelt = /obj/item/weapon/storage/belt/utility/full corpsegloves = /obj/item/clothing/gloves/color/yellow corpsehelmet = /obj/item/clothing/head/hardhat diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 39ac1f49676..8da37d2ae3e 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -149,7 +149,7 @@ obj/machinery/gateway/centerstation/process() /obj/machinery/gateway/centerstation/attackby(obj/item/device/W as obj, mob/user as mob, params) if(istype(W,/obj/item/device/multitool)) - to_chat(user, "\black The gate is already calibrated, there is no work for you to do here.") + to_chat(user, "The gate is already calibrated, there is no work for you to do here.") return /////////////////////////////////////Away//////////////////////// diff --git a/code/modules/awaymissions/map_rng.dm b/code/modules/awaymissions/map_rng.dm new file mode 100644 index 00000000000..469dffaca54 --- /dev/null +++ b/code/modules/awaymissions/map_rng.dm @@ -0,0 +1,38 @@ +/obj/effect/landmark/map_loader + name = "map loader" + icon = 'icons/mob/screen_gen.dmi' + icon_state = "x2" + invisibility = 101 + anchored = 1 + density = 0 + opacity = 0 + var/template_name = null + var/datum/map_template/template = null + var/centered = 1 + +/obj/effect/landmark/map_loader/New(loc, tname) + ..() + if(tname) + template_name = tname + if(template_name) + template = map_templates[template_name] + if(template) + load(template) + +/obj/effect/landmark/map_loader/proc/load(datum/map_template/t) + spawn(1) + if(!t) + return + t.load(get_turf(src), centered = centered) + t.loaded++ + qdel(src) + +/obj/effect/landmark/map_loader/random + var/template_list = "" + +/obj/effect/landmark/map_loader/random/New() + ..() + if(template_list) + template_name = safepick(splittext(template_list, ";")) + template = map_templates[template_name] + load(template) \ No newline at end of file diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index 0adf55229e0..682e2137d2a 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -61,10 +61,8 @@ */ //Captain's retro laser - Fires practice laser shots instead. obj/item/weapon/gun/energy/laser/retro/sc_retro - name ="retro laser" - icon_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces." -// projectile_type = "/obj/item/projectile/practice" + ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 //No sense in having a harmless gun blow up in the clowns face //Syndicate sub-machine guns. @@ -196,4 +194,4 @@ var/sc_safecode5 = "[rand(0,9)]" return /obj/singularity/narsie/sc_Narsie/ex_act() - return \ No newline at end of file + return diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index d28d67f1f35..8227671f0ac 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -172,7 +172,7 @@ if(istype(M, /mob/living/carbon/human)) for(var/mob/O in viewers(world.view, src.loc)) - to_chat(O, "[M] triggered the \icon[src] [src]") + to_chat(O, "[M] triggered the [bicon(src)] [src]") triggered = 1 call(src,triggerproc)(M) diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 30e4793c747..c1cbd07daee 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -84,4 +84,8 @@ var/datum/click_intercept/click_intercept = null //datum that controls the displaying and hiding of tooltips - var/datum/tooltip/tooltips \ No newline at end of file + var/datum/tooltip/tooltips + + // Their chat window, sort of important. + // See /goon/code/datums/browserOutput.dm + var/datum/chatOutput/chatOutput \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 768de2a270b..d7b41fe2c59 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -43,6 +43,9 @@ completed_asset_jobs += job return + if(href_list["_src_"] == "chat") + return chatOutput.Topic(href, href_list) + //Reduces spamming of links by dropping calls that happen during the delay period if(next_allowed_topic_time > world.time) return @@ -203,6 +206,11 @@ if("prefs") return prefs.process_link(usr,href_list) if("vars") return view_var_Topic(href,href_list,hsrc) + + switch(href_list["action"]) + if ("openLink") + src << link(href_list["link"]) + ..() //redirect to hsrc.Topic() /client/proc/is_content_unlocked() @@ -245,6 +253,7 @@ //CONNECT// /////////// /client/New(TopicData) + chatOutput = new /datum/chatOutput(src) // Right off the bat. TopicData = null //Prevent calls to client.Topic from connect if(connection != "seeker") //Invalid connection type. @@ -283,6 +292,7 @@ prefs.last_id = computer_id //these are gonna be used for banning . = ..() //calls mob.Login() + chatOutput.start() if(custom_event_msg && custom_event_msg != "") to_chat(src, "

    Custom Event

    ") @@ -316,9 +326,9 @@ send_resources() if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates. -CP - winset(src, "rpane.changelog", "background-color=#f4aa94;font-style=bold") - prefs.SetChangelog(src,changelog_hash) - to_chat(src, "Changelog has changed since your last visit.") + if(establish_db_connection()) + winset(src, "rpane.changelog", "background-color=#f4aa94;font-style=bold") + to_chat(src, "Changelog has changed since your last visit.") if(!void) void = new() diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 6696e6e8ecd..eafc7b59bd6 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -258,8 +258,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "N2 Tank: [speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"]
    " dat += "Secondary Language: [language]
    " dat += "Blood Type: [b_type]
    " - if(species in list("Human", "Drask")) - dat += "Skin Tone: [-s_tone + 35]/220
    " + if(species in list("Human", "Drask", "Vox")) + dat += "Skin Tone: [species == "Vox" ? "[s_tone]" : "[-s_tone + 35]/220"]
    " dat += "Disabilities: \[Set\]
    " dat += "Nanotrasen Relation: [nanotrasen_relation]
    " dat += "Set Flavor Text
    " @@ -410,7 +410,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else dat += "Be [capitalize(i)]: [(i in src.be_special) ? "Yes" : "No"]
    " dat += "
" - + dat += "
" if(!IsGuestKey(user.key)) dat += "Undo - " @@ -984,16 +984,17 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("age") age = rand(AGE_MIN, AGE_MAX) if("hair") - if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Wryn" || species == "Vulpkanin") + if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) r_hair = rand(0,255) g_hair = rand(0,255) b_hair = rand(0,255) if("h_style") h_style = random_hair_style(gender, species) if("facial") - r_facial = rand(0,255) - g_facial = rand(0,255) - b_facial = rand(0,255) + if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Wryn", "Vulpkanin", "Vox")) + r_facial = rand(0,255) + g_facial = rand(0,255) + b_facial = rand(0,255) if("f_style") f_style = random_facial_hair_style(gender, species) if("underwear") @@ -1010,10 +1011,10 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts g_eyes = rand(0,255) b_eyes = rand(0,255) if("s_tone") - if(species in list("Human", "Drask")) - s_tone = random_skin_tone() + if(species in list("Human", "Drask", "Vox")) + s_tone = random_skin_tone(species) if("s_color") - if(species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Wyrn", "Vulpkanin", "Machine")) + if(species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Wryn", "Vulpkanin", "Machine")) r_skin = rand(0,255) g_skin = rand(0,255) b_skin = rand(0,255) @@ -1037,7 +1038,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("age") var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null if(new_age) - age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + age = max(min(round(text2num(new_age)), AGE_MAX),AGE_MIN) if("species") var/list/new_species = list("Human", "Tajaran", "Skrell", "Unathi", "Diona", "Vulpkanin") @@ -1115,6 +1116,11 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts s_tone = 0 + if(!(species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine"))) + r_skin = 0 + g_skin = 0 + b_skin = 0 + ha_style = "None" // No Vulp ears on Unathi m_style = "None" // No Unathi markings on Tajara @@ -1159,7 +1165,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts b_type = new_b_type if("hair") - if(species == "Human" || species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Machine" || species == "Vulpkanin") + if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) var/input = "Choose your character's hair colour:" var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null if(new_hair) @@ -1278,11 +1284,12 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts body_accessory = (new_body_accessory == "None") ? null : new_body_accessory if("facial") - var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null - if(new_facial) - r_facial = hex2num(copytext(new_facial, 2, 4)) - g_facial = hex2num(copytext(new_facial, 4, 6)) - b_facial = hex2num(copytext(new_facial, 6, 8)) + if(species in list("Human", "Unathi", "Tajaran", "Skrell", "Machine", "Vulpkanin", "Vox")) + var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null + if(new_facial) + r_facial = hex2num(copytext(new_facial, 2, 4)) + g_facial = hex2num(copytext(new_facial, 4, 6)) + b_facial = hex2num(copytext(new_facial, 6, 8)) if("f_style") var/list/valid_facialhairstyles = list() @@ -1367,11 +1374,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts b_eyes = hex2num(copytext(new_eyes, 6, 8)) if("s_tone") - if(species != "Human" && species != "Drask") - return - var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null - if(new_s_tone) - s_tone = 35 - max(min( round(new_s_tone), 220),1) + if(species == "Human" || species == "Drask") + var/new_s_tone = input(user, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Character Preference") as num|null + if(new_s_tone) + s_tone = 35 - max(min(round(new_s_tone), 220), 1) + else if(species == "Vox") + var/skin_c = input(user, "Choose your Vox's skin color:\n(1 = Default Green, 2 = Dark Green, 3 = Brown, 4 = Grey, \n5 = Emerald, 6 = Azure)", "Character Preference") as num|null + if(skin_c) + s_tone = max(min(round(skin_c), 6), 1) if("skin") if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user)) @@ -1381,7 +1391,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts g_skin = hex2num(copytext(new_skin, 4, 6)) b_skin = hex2num(copytext(new_skin, 6, 8)) - if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null if(new_ooccolor) diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm index 07db4bf7128..15abdab0360 100644 --- a/code/modules/client/preferences_mysql.dm +++ b/code/modules/client/preferences_mysql.dm @@ -456,10 +456,12 @@ /datum/preferences/proc/SetChangelog(client/C,hash) lastchangelog=hash + winset(C, "rpane.changelog", "background-color=none;font-style=") var/DBQuery/query = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastchangelog='[lastchangelog]' WHERE ckey='[C.ckey]'") if(!query.Execute()) var/err = query.ErrorMsg() log_game("SQL ERROR during lastchangelog updating. Error : \[[err]\]\n") message_admins("SQL ERROR during lastchangelog updating. Error : \[[err]\]\n") + to_chat(C, "Couldn't update your last seen changelog, please try again later.") return return 1 diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 6e4623fa9be..bad4a3dabc5 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -51,8 +51,8 @@ origin_tech = "magnets=2;engineering=2" vision_flags = SEE_TURFS prescription_upgradable = 1 - species_fit = list("Vox") see_darkness = 0 //don't render darkness while wearing mesons + species_fit = list("Vox") sprite_sheets = list( "Vox" = 'icons/mob/species/vox/eyes.dmi', "Drask" = 'icons/mob/species/drask/eyes.dmi' @@ -97,6 +97,10 @@ item_state = "glasses" prescription_upgradable = 0 scan_reagents = 1 //You can see reagents while wearing science goggles + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/science/equipped(mob/user, slot) if(slot == slot_glasses) @@ -120,6 +124,10 @@ desc = "These'll keep the soap out of your eyes." icon_state = "purple" item_state = "glasses" + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/night name = "Night Vision Goggles" @@ -140,6 +148,10 @@ desc = "Yarr." icon_state = "eyepatch" item_state = "eyepatch" + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/monocle name = "monocle" @@ -178,6 +190,10 @@ icon_state = "glasses" item_state = "glasses" prescription = 1 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/regular/hipster name = "prescription glasses" @@ -190,12 +206,20 @@ name = "3D glasses" icon_state = "3d" item_state = "3d" + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/gglasses name = "Green Glasses" desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." icon_state = "gglasses" item_state = "gglasses" + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/sunglasses desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes." @@ -350,10 +374,6 @@ flash_protect = 2 tint = 0 action_button_name = "Flip welding goggles" - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) /obj/item/clothing/glasses/sunglasses/blindfold name = "blindfold" @@ -364,10 +384,6 @@ flash_protect = 2 tint = 3 //to make them blind prescription_upgradable = 0 - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) /obj/item/clothing/glasses/sunglasses/prescription prescription = 1 @@ -376,12 +392,6 @@ desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks many flashes." icon_state = "bigsunglasses" item_state = "bigsunglasses" - flash_protect = 1 - tint = 1 - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) /obj/item/clothing/glasses/thermal name = "Optical Thermal Scanner" @@ -392,6 +402,10 @@ vision_flags = SEE_MOBS invisa_view = 2 flash_protect = -1 + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) emp_act(severity) if(istype(src.loc, /mob/living/carbon/human)) @@ -410,10 +424,6 @@ desc = "Used for seeing walls, floors, and stuff through anything." icon_state = "meson" origin_tech = "magnets=3;syndicate=4" - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) /obj/item/clothing/glasses/thermal/monocle name = "Thermoncle" @@ -432,10 +442,6 @@ desc = "A set of implantable lenses designed to augment your vision" icon_state = "thermalimplants" item_state = "syringe_kit" - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi' - ) /obj/item/clothing/glasses/thermal/cyber name = "Eye Replacement Implant" diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 44138b8e907..8756290ad20 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -28,13 +28,17 @@ desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." icon_state = "healthhud" HUDType = DATA_HUD_MEDICAL_ADVANCED + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' + ) /obj/item/clothing/glasses/hud/health/health_advanced name = "\improper Advanced Health Scanner HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their health status. Includes anti-flash filter." icon_state = "advmedhud" flash_protect = 1 - HUDType = DATA_HUD_MEDICAL_ADVANCED /obj/item/clothing/glasses/hud/health/night name = "\improper Night Vision Health Scanner HUD" @@ -50,6 +54,10 @@ desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." icon_state = "diagnostichud" HUDType = DATA_HUD_DIAGNOSTIC + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi' + ) /obj/item/clothing/glasses/hud/diagnostic/night name = "Night Vision Diagnostic HUD" @@ -67,11 +75,15 @@ var/global/list/jobs[0] flash_protect = 1 HUDType = DATA_HUD_SECURITY_ADVANCED + species_fit = list("Vox") + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/eyes.dmi', + "Drask" = 'icons/mob/species/drask/eyes.dmi' + ) /obj/item/clothing/glasses/hud/security/chameleon name = "Chamleon Security HUD" desc = "A stolen security HUD integrated with Syndicate chameleon technology. Toggle to disguise the HUD. Provides flash protection." - flash_protect = 1 /obj/item/clothing/glasses/hud/security/chameleon/attack_self(mob/user) chameleon(user) @@ -97,15 +109,8 @@ desc = "Sunglasses with a HUD." icon_state = "sunhud" darkness_view = 1 - flash_protect = 1 tint = 1 - HUDType = DATA_HUD_SECURITY_ADVANCED prescription_upgradable = 1 - species_fit = list("Vox") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/eyes.dmi', - "Drask" = 'icons/mob/species/drask/eyes.dmi' - ) /obj/item/clothing/glasses/hud/security/sunglasses/prescription prescription = 1 \ No newline at end of file diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index db163ad3e59..a50e56382a1 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -6,8 +6,32 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 item_color="yellow" - power - var/next_shock = 0 + +/obj/item/clothing/gloves/color/yellow/power + description_antag = "These are a pair of power gloves, and can be used to fire bolts of electricity while standing over powered power cables." + var/old_mclick_override + var/datum/middleClickOverride/power_gloves/mclick_override = new /datum/middleClickOverride/power_gloves + +/obj/item/clothing/gloves/color/yellow/power/equipped(mob/user, slot) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(slot == slot_gloves) + if(H.middleClickOverride) + old_mclick_override = H.middleClickOverride + H.middleClickOverride = mclick_override + to_chat(H, "You feel electricity begin to build up in [src].") + +/obj/item/clothing/gloves/color/yellow/power/dropped(mob/user, slot) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(slot_gloves) == src && H.middleClickOverride == mclick_override) + if(old_mclick_override) + H.middleClickOverride = old_mclick_override + old_mclick_override = null + else + H.middleClickOverride = null /obj/item/clothing/gloves/color/yellow/fake desc = "These gloves will protect the wearer from electric shock. They don't feel like rubber..." @@ -167,4 +191,4 @@ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - strip_delay = 60 \ No newline at end of file + strip_delay = 60 diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index b1b015e6ecb..a9e8bbdb7e2 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -1,10 +1,10 @@ /obj/item/clothing/head/helmet name = "helmet" desc = "Standard Security gear. Protects the head from impacts." - icon_state = "helmet" + icon_state = "helmetmaterials" flags = HEADCOVERSEYES | HEADBANGPROTECT - item_state = "helmet" - armor = list(melee = 50, bullet = 15, laser = 50,energy = 10, bomb = 25, bio = 0, rad = 0) + item_state = "helmetmaterials" + armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) flags_inv = HIDEEARS|HIDEEYES cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT @@ -82,10 +82,19 @@ icon_state = "riot" item_state = "helmet" flags = HEADCOVERSEYES | HEADCOVERSMOUTH | HEADBANGPROTECT - armor = list(melee = 82, bullet = 15, laser = 5,energy = 5, bomb = 5, bio = 2, rad = 0) + armor = list(melee = 80, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) flags_inv = HIDEEARS strip_delay = 80 +/obj/item/clothing/head/helmet/riot/knight + name = "medieval helmet" + desc = "A classic metal helmet." + icon_state = "knight_green" + item_state = "knight_green" + flags = BLOCKHAIR | HEADCOVERSEYES | HEADCOVERSMOUTH + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) + flags_inv = HIDEMASK | HIDEEARS | HIDEEYES | HIDEFACE + /obj/item/clothing/head/helmet/justice name = "helmet of justice" desc = "WEEEEOOO. WEEEEEOOO. WEEEEOOOO." @@ -111,7 +120,7 @@ icon_state = "swat" flags = HEADCOVERSEYES item_state = "swat" - armor = list(melee = 80, bullet = 60, laser = 50,energy = 25, bomb = 50, bio = 10, rad = 0) + armor = list(melee = 80, bullet = 60, laser = 50, energy = 25, bomb = 50, bio = 10, rad = 0) flags_inv = HIDEEARS|HIDEEYES cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT @@ -136,7 +145,7 @@ icon_state = "thunderdome" flags = HEADCOVERSEYES item_state = "thunderdome" - armor = list(melee = 80, bullet = 60, laser = 50,energy = 10, bomb = 25, bio = 10, rad = 0) + armor = list(melee = 80, bullet = 60, laser = 50, energy = 10, bomb = 25, bio = 10, rad = 0) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD @@ -172,7 +181,7 @@ obj/item/clothing/head/helmet/redtaghelm icon_state = "redtaghelm" flags = HEADCOVERSEYES item_state = "redtaghelm" - armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 10, laser = 20, energy = 10, bomb = 20, bio = 0, rad = 0) // Offer about the same protection as a hardhat. flags_inv = HIDEEARS|HIDEEYES @@ -182,7 +191,7 @@ obj/item/clothing/head/helmet/bluetaghelm icon_state = "bluetaghelm" flags = HEADCOVERSEYES item_state = "bluetaghelm" - armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0) + armor = list(melee = 30, bullet = 10, laser = 20, energy = 10, bomb = 20, bio = 0, rad = 0) // Offer about the same protection as a hardhat. flags_inv = HIDEEARS|HIDEEYES @@ -194,16 +203,6 @@ obj/item/clothing/head/blob flags = HEADCOVERSEYES|HEADCOVERSMOUTH flags_inv = HIDEMASK|HIDEEARS|HIDEEYES -/obj/item/clothing/head/helmet/knight - name = "medieval helmet" - desc = "A classic metal helmet." - icon_state = "knight_green" - item_state = "knight_green" - armor = list(melee = 41, bullet = 15, laser = 5,energy = 5, bomb = 5, bio = 2, rad = 0) - flags = BLOCKHAIR|HEADCOVERSEYES|HEADCOVERSMOUTH - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE - strip_delay = 80 - /obj/item/clothing/head/helmet/knight/blue icon_state = "knight_blue" item_state = "knight_blue" @@ -251,4 +250,4 @@ obj/item/clothing/head/blob /obj/item/clothing/head/helmet/ert/janitor name = "emergency response team janitor helmet" desc = "A set of armor worn by janitorial members of the NanoTrasen Emergency Response Team. Has red and white highlights." - icon_state = "erthelmet_jan" \ No newline at end of file + icon_state = "erthelmet_jan" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 30252e49772..9da40760327 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -56,7 +56,7 @@ name = "hat" desc = "Someone who wears this will look very smart." icon_state = "detective" - allowed = list(/obj/item/weapon/reagent_containers/food/snacks/candy_corn, /obj/item/weapon/pen) + allowed = list(/obj/item/weapon/reagent_containers/food/snacks/candy/candy_corn, /obj/item/weapon/pen) armor = list(melee = 50, bullet = 5, laser = 25,energy = 10, bomb = 0, bio = 0, rad = 0) //Mime @@ -85,9 +85,9 @@ armor = list(melee = 60, bullet = 5, laser = 25, energy = 10, bomb = 25, bio = 0, rad = 0) strip_delay = 60 -/obj/item/clothing/head/customs - name = "customs officer's hat" - desc = "A serious looking hat for a serious job." +/obj/item/clothing/head/officer + name = "officer's cap" + desc = "A red cap with an old-fashioned badge on the front for establishing that you are, in fact, the law." icon_state = "customshelm" item_state = "customshelm" armor = list(melee = 30, bullet = 25, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0) diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index 364c4d808ac..1b7ea8fc4c9 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -95,13 +95,12 @@ src.icon_state = "orange" return -/obj/item/clothing/shoes/orange/attackby(H as obj, loc, params) +/obj/item/clothing/shoes/orange/attackby(obj/H, loc, params) ..() - if ((istype(H, /obj/item/weapon/restraints/handcuffs) && !( src.chained ))) - //H = null + if (istype(H, /obj/item/weapon/restraints/handcuffs) && !chained && !(H.flags & NODROP)) if (src.icon_state != "orange") return qdel(H) src.chained = 1 src.slowdown = 15 src.icon_state = "orange1" - return \ No newline at end of file + return diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index babeb811a37..72d00a4abf1 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -99,6 +99,12 @@ item_color = "jacksandal" species_restricted = null +/obj/item/clothing/shoes/workboots + name = "work boots" + desc = "Thick-soled boots for industrial work environments." + can_cut_open = 1 + icon_state = "workboots" + /obj/item/clothing/shoes/cult name = "boots" desc = "A pair of boots worn by the followers of Nar-Sie." diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm index 4015f107e51..91824a9856e 100644 --- a/code/modules/clothing/spacesuits/ert.dm +++ b/code/modules/clothing/spacesuits/ert.dm @@ -34,8 +34,8 @@ armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \ /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \ - /obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \ - /obj/item/weapon/gun/energy/advtaser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun) + /obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse, \ + /obj/item/weapon/gun/energy/gun/advtaser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun) strip_delay = 130 //Commander @@ -121,4 +121,4 @@ /obj/item/clothing/suit/space/rig/ert/paranormal/New() ..() - new /obj/item/weapon/nullrod(src) \ No newline at end of file + new /obj/item/weapon/nullrod(src) diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 2473fd24eb8..16ddf2bdd69 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -119,7 +119,7 @@ gun.attack_self(holder.wearer) return 1 - gun.Fire(target,holder.wearer) + gun.process_fire(target,holder.wearer) return 1 /obj/item/rig_module/mounted/egun @@ -168,7 +168,7 @@ active_power_cost = 10 passive_power_cost = 0 - gun_type = /obj/item/weapon/gun/energy/crossbow/ninja + gun_type = /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja /obj/item/rig_module/mounted/energy_blade/process() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 6e3fcffa7cf..66a0e62a39b 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -82,13 +82,13 @@ var/datum/effect/system/spark_spread/spark_system /obj/item/weapon/rig/examine() - to_chat(usr, "This is \icon[src][src.name].") + to_chat(usr, "This is [bicon(src)][src.name].") to_chat(usr, "[src.desc]") if(wearer) for(var/obj/item/piece in list(helmet,gloves,chest,boots)) if(!piece || piece.loc != wearer) continue - to_chat(usr, "\icon[piece] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed.") + to_chat(usr, "[bicon(piece)] \The [piece] [piece.gender == PLURAL ? "are" : "is"] deployed.") if(src.loc == usr) to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].") diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 7934d49a620..609e24ca6bf 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -36,9 +36,43 @@ /obj/item/clothing/suit/armor/vest/security name = "security armor" - desc = "An armored vest that protects against some damage. This one has Nanotrasen corporate badge." - icon_state = "armorsec" + desc = "An armored vest that protects against some damage. This one has a clip for a holobadge." + icon_state = "armor" item_state = "armor" + var/obj/item/clothing/accessory/holobadge/attached_badge + +/obj/item/clothing/suit/armor/vest/security/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/clothing/accessory/holobadge)) + if(user.unEquip(W)) + add_fingerprint(user) + W.forceMove(src) + attached_badge = W + + action_button_name = "Remove Holobadge" + icon_state = "armorsec" + user.update_inv_wear_suit() + desc = "An armored vest that protects against some damage. This one has [attached_badge] attached to it." + to_chat(user, "You attach [attached_badge] to [src].") + return + ..() + +/obj/item/clothing/suit/armor/vest/security/attack_self(mob/user as mob) + if(attached_badge) + add_fingerprint(user) + user.put_in_hands(attached_badge) + + action_button_name = null + action.Remove(user) + icon_state = "armor" + user.update_inv_wear_suit() + desc = "An armored vest that protects against some damage. This one has a clip for a holobadge." + to_chat(user, "You remove [attached_badge] from [src].") + + attached_badge = null + + return + + ..() /obj/item/clothing/suit/armor/vest/blueshield name = "blueshield security armor" @@ -119,6 +153,32 @@ strip_delay = 80 put_on_delay = 60 +/obj/item/clothing/suit/armor/riot/knight + name = "plate armour" + desc = "A classic suit of plate armour, highly effective at stopping melee attacks." + icon_state = "knight_green" + item_state = "knight_green" + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/suit/armor/riot/knight/yellow + icon_state = "knight_yellow" + item_state = "knight_yellow" + +/obj/item/clothing/suit/armor/riot/knight/blue + icon_state = "knight_blue" + item_state = "knight_blue" + +/obj/item/clothing/suit/armor/riot/knight/red + icon_state = "knight_red" + item_state = "knight_red" + +/obj/item/clothing/suit/armor/riot/knight/templar + name = "crusader armour" + desc = "God wills it!" + icon_state = "knight_templar" + item_state = "knight_templar" + allowed = list(/obj/item/weapon/nullrod/claymore) + /obj/item/clothing/suit/armor/bulletproof name = "Bulletproof Vest" desc = "A bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." @@ -135,13 +195,13 @@ icon_state = "armor_reflec" item_state = "armor_reflec" blood_overlay_type = "armor" - var/hit_reflect_chance = 40 armor = list(melee = 10, bullet = 10, laser = 80, energy = 50, bomb = 0, bio = 0, rad = 0) + var/hit_reflect_chance = 40 /obj/item/clothing/suit/armor/laserproof/IsReflect(var/def_zone) if(!(def_zone in list("chest", "groin"))) //If not shot where ablative is covering you, you don't get the reflection bonus! - hit_reflect_chance = 0 - if (prob(hit_reflect_chance)) + return 0 + if(prob(hit_reflect_chance)) return 1 /obj/item/clothing/suit/armor/vest/det_suit @@ -240,33 +300,6 @@ icon_state = "tdgreen" item_state = "tdgreen" -/obj/item/clothing/suit/armor/riot/knight - name = "plate armour" - desc = "A classic suit of plate armour, highly effective at stopping melee attacks." - icon_state = "knight_green" - item_state = "knight_green" - slowdown = 0 - armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) - -/obj/item/clothing/suit/armor/riot/knight/yellow - icon_state = "knight_yellow" - item_state = "knight_yellow" - -/obj/item/clothing/suit/armor/riot/knight/blue - icon_state = "knight_blue" - item_state = "knight_blue" - -/obj/item/clothing/suit/armor/riot/knight/red - icon_state = "knight_red" - item_state = "knight_red" - -/obj/item/clothing/suit/armor/riot/knight/templar - name = "crusader armour" - desc = "God wills it!" - icon_state = "knight_templar" - item_state = "knight_templar" - allowed = list(/obj/item/weapon/gun/energy,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/gun/projectile,/obj/item/ammo_box,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/restraints/handcuffs,/obj/item/device/flashlight/seclite,/obj/item/weapon/melee/classic_baton/telescopic,/obj/item/weapon/nullrod/claymore) - //Non-hardsuit ERT armor. /obj/item/clothing/suit/armor/vest/ert name = "emergency response team armor" @@ -302,4 +335,4 @@ /obj/item/clothing/suit/armor/vest/ert/janitor name = "emergency response team janitor armor" desc = "A set of armor worn by janitorial members of the Nanotrasen Emergency Response Team. Has red and white highlights." - icon_state = "ertarmor_jan" \ No newline at end of file + icon_state = "ertarmor_jan" diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 8b1d33d6ddb..62981692d01 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -389,7 +389,7 @@ /obj/item/clothing/accessory/petcollar/examine(mob/user) ..() if(access_id) - to_chat(user, "There is \icon[access_id] \a [access_id] clipped onto it.") + to_chat(user, "There is [bicon(access_id)] \a [access_id] clipped onto it.") /obj/item/clothing/accessory/petcollar/equipped(mob/living/simple_animal/user) if(istype(user)) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 0e2392ceff1..9533d7c4aae 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -256,7 +256,7 @@ /obj/item/clothing/under/suit_jacket/charcoal name = "charcoal suit" - desc = "A charcoal suit and red tie. Very professional." + desc = "A charcoal suit and blue tie. Very professional." icon_state = "charcoal_suit" item_state = "charcoal_suit" item_color = "charcoal_suit" diff --git a/code/modules/computer3/NTOS.dm b/code/modules/computer3/NTOS.dm index 5119084f0e6..bc70c49cbac 100644 --- a/code/modules/computer3/NTOS.dm +++ b/code/modules/computer3/NTOS.dm @@ -61,7 +61,7 @@ dat += {" - \icon[C]
+ [bicon(C)]
[C.name]
"} diff --git a/code/modules/computer3/computers/communications.dm b/code/modules/computer3/computers/communications.dm index b738cef704e..23e3bba3e4b 100644 --- a/code/modules/computer3/computers/communications.dm +++ b/code/modules/computer3/computers/communications.dm @@ -60,7 +60,7 @@ if(!interactable() || !computer.radio || ..(href,href_list) ) return if (!(computer.z in config.station_levels)) - to_chat(usr, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") return if("main" in href_list) diff --git a/code/modules/computer3/computers/law.dm b/code/modules/computer3/computers/law.dm index ec278163b2a..71d30df68d6 100644 --- a/code/modules/computer3/computers/law.dm +++ b/code/modules/computer3/computers/law.dm @@ -25,7 +25,7 @@ attackby(obj/item/weapon/aiModule/module as obj, mob/user as mob, params) if (user.z > 6) - to_chat(user, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(user, "Unable to establish a connection: You're too far away from the station!") return if(istype(module, /obj/item/weapon/aiModule)) module.install(src) diff --git a/code/modules/computer3/computers/medical.dm b/code/modules/computer3/computers/medical.dm index aeda16c4414..5d283af5b53 100644 --- a/code/modules/computer3/computers/medical.dm +++ b/code/modules/computer3/computers/medical.dm @@ -50,7 +50,7 @@ if(!interactable()) return if (computer.z > 6) - to_chat(usr, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") return var/dat diff --git a/code/modules/computer3/computers/message.dm b/code/modules/computer3/computers/message.dm index 31aa4f3a501..cb9d27dd0b9 100644 --- a/code/modules/computer3/computers/message.dm +++ b/code/modules/computer3/computers/message.dm @@ -411,10 +411,10 @@ if (!customrecepient.silent) playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, customrecepient.loc)) - O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*")) + O.show_message(text("[bicon(customrecepient)] *[customrecepient.ttone]*")) if( customrecepient.loc && ishuman(customrecepient.loc) ) var/mob/living/carbon/human/H = customrecepient.loc - to_chat(H, "\icon[customrecepient] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)" + to_chat(H, "[bicon(customrecepient)] Message from [customsender] ([customjob]), \"[custommessage]\" (Reply)" log_pda("[usr] (PDA: [customsender]) sent \"[custommessage]\" to [customrecepient.owner]") customrecepient.overlays.Cut() @@ -426,10 +426,10 @@ if (!customrecepient.silent) playsound(customrecepient.loc, 'sound/machines/twobeep.ogg', 50, 1) for (var/mob/O in hearers(3, customrecepient.loc)) - O.show_message(text("\icon[customrecepient] *[customrecepient.ttone]*")) + O.show_message(text("[bicon(customrecepient)] *[customrecepient.ttone]*")) if( customrecepient.loc && ishuman(customrecepient.loc) ) var/mob/living/carbon/human/H = customrecepient.loc - to_chat(H, "\icon[customrecepient] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)" + to_chat(H, "[bicon(customrecepient)] Message from [PDARec.owner] ([customjob]), \"[custommessage]\" (Reply)" log_pda("[usr] (PDA: [PDARec.owner]) sent \"[custommessage]\" to [customrecepient.owner]") customrecepient.overlays.Cut() diff --git a/code/modules/computer3/computers/security.dm b/code/modules/computer3/computers/security.dm index c7eb0a8881b..ebb218b5cee 100644 --- a/code/modules/computer3/computers/security.dm +++ b/code/modules/computer3/computers/security.dm @@ -58,7 +58,7 @@ return if (computer.z > 6) - to_chat(usr, "\red Unable to establish a connection: \black You're too far away from the station!") + to_chat(usr, "Unable to establish a connection: You're too far away from the station!") return var/dat diff --git a/code/modules/computer3/lapvend.dm b/code/modules/computer3/lapvend.dm index 8383981046d..3834efd635a 100644 --- a/code/modules/computer3/lapvend.dm +++ b/code/modules/computer3/lapvend.dm @@ -262,11 +262,11 @@ network = 0 power = 0 else - to_chat(usr, "\icon[src]You don't have that much money!") + to_chat(usr, "[bicon(src)]You don't have that much money!") else - to_chat(usr, "\icon[src]Unable to access account. Check security settings and try again.") + to_chat(usr, "[bicon(src)]Unable to access account. Check security settings and try again.") else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support.") + to_chat(usr, "[bicon(src)]Unable to access vendor account. Please record the machine ID and call CentComm Support.") /obj/machinery/lapvend/proc/total() var/total = 0 @@ -405,6 +405,6 @@ power = 0 else - to_chat(usr, "\icon[src]Unable to access account. Check security settings and try again.") + to_chat(usr, "[bicon(src)]Unable to access account. Check security settings and try again.") else - to_chat(usr, "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support.") + to_chat(usr, "[bicon(src)]Unable to access vendor account. Please record the machine ID and call CentComm Support.") diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index c578c452bbc..d8586b6c0d8 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -44,7 +44,7 @@ /obj/item/robot_parts/r_leg = 1, /obj/item/stack/sheet/metal = 5, /obj/item/stack/cable_coil = 5, - /obj/item/weapon/gun/energy/advtaser = 1, + /obj/item/weapon/gun/energy/gun/advtaser = 1, /obj/item/weapon/stock_parts/cell = 1, /obj/item/device/assembly/prox_sensor = 1, /obj/item/robot_parts/r_arm = 1) @@ -200,4 +200,29 @@ time = 15 reqs = list(/obj/item/stack/sheet/wood = 1, /obj/item/stack/cable_coil = 5) - tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles \ No newline at end of file + tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles + +/datum/table_recipe/makeshift_bolt + name = "Makeshift Bolt" + result = /obj/item/weapon/arrow/rod + time = 15 + reqs = list(/obj/item/stack/rods = 1) + tools = list(/obj/item/weapon/weldingtool) + +/datum/table_recipe/crossbow + name = "Powered Crossbow" + result = /obj/item/weapon/gun/throw/crossbow + time = 300 + reqs = list(/obj/item/stack/rods = 3, + /obj/item/stack/cable_coil = 10, + /obj/item/stack/sheet/mineral/plastic = 3, + /obj/item/stack/sheet/wood = 5) + tools = list(/obj/item/weapon/weldingtool, + /obj/item/weapon/screwdriver) + +/datum/table_recipe/glove_balloon + name = "Latex Glove Balloon" + result = /obj/item/latexballon + time = 15 + reqs = list(/obj/item/clothing/gloves/color/latex = 1, + /obj/item/stack/cable_coil = 5) \ No newline at end of file diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 3cd6566e731..ab8670b3b05 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -67,8 +67,23 @@ target.update_markings() playsound(src.loc, 'sound/items/Welder2.ogg', 20, 1) - icon_state = "tatgun_used" used = 1 + update_icon() + +/obj/item/device/fluff/tattoo_gun/update_icon() + ..() + + overlays.Cut() + + if(!used) + var/image/ink = image(src.icon, src, "ink_overlay") + ink.icon += rgb(tattoo_r, tattoo_g, tattoo_b, 190) + overlays += ink + +/obj/item/device/fluff/tattoo_gun/New() + ..() + update_icon() + /obj/item/weapon/claymore/fluff // MrBarrelrolll: Maximus Greenwood name = "Greenwood's Blade" @@ -293,6 +308,16 @@ src.item_state = "[item_color]" usr.update_inv_w_uniform() +/obj/item/clothing/under/fluff/honourable // MrBarrelrolll: Maximus Greenwood + name = "Viridi Protegat" + desc = "A set of chainmail adorned with a hide mantle. \"Greenwood\" is engraved into the right breast." + icon = 'icons/obj/clothing/uniforms.dmi' + icon_state = "roman" + item_state = "maximus_armor" + item_color = "maximus_armor" + displays_id = 0 + strip_delay = 100 + //////////// Masks //////////// //////////// Shoes //////////// @@ -422,24 +447,34 @@ icon_state = "chaps" item_color = "combat_pants" -/obj/item/clothing/suit/jacket/fluff/windbreaker // DaveTheHeadcrab: Elliot Campbell +/obj/item/clothing/suit/jacket/fluff/elliot_windbreaker // DaveTheHeadcrab: Elliot Campbell name = "nylon windbreaker" desc = "A cheap nylon windbreaker, according to the tag it was manufactured in New Chiba, Earth.
The color reminds you of a television tuned to a dead channel." icon = 'icons/obj/custom_items.dmi' - icon_state = "elliot_windbreaker" - item_state = "elliot_windbreaker" + icon_state = "elliot_windbreaker_open" + item_state = "elliot_windbreaker_open" adjust_flavour = "unzip" + suit_adjusted = 1 -/obj/item/clothing/ears/earring/fluff/industrial_piercing - name = "industrial piercing and stud earring" - desc = "A set of ear piercings containing an industrial rod and a small stud. They appear to be made out of some form of non-magnetic metal." - icon = 'icons/obj/custom_items.dmi' - icon_state = "elliot_earring" - -/obj/item/device/fluff/tattoo_gun/cybernetic_tat - desc = "A cheap plastic tattoo application pen.
This one seems to have light blue ink." +/obj/item/device/fluff/tattoo_gun/elliot_cybernetic_tat + desc = "A cheap plastic tattoo application pen.
This one seems heavily used." tattoo_name = "circuitry tattoo" tattoo_icon = "Elliot Circuit Tattoo" - tattoo_r = 100 - tattoo_g = 150 - tattoo_b = 255 \ No newline at end of file + tattoo_r = 48 + tattoo_g = 138 + tattoo_b = 176 + +/obj/item/device/fluff/tattoo_gun/elliot_cybernetic_tat/attack_self(mob/user as mob) + if(!used) + var/ink_color = input("Please select an ink color.", "Tattoo Ink Color", rgb(tattoo_r, tattoo_g, tattoo_b)) as color|null + if(ink_color && !(user.incapacitated() || used) ) + tattoo_r = hex2num(copytext(ink_color, 2, 4)) + tattoo_g = hex2num(copytext(ink_color, 4, 6)) + tattoo_b = hex2num(copytext(ink_color, 6, 8)) + + to_chat(user, "You change the color setting on the [src].") + + update_icon() + + else + to_chat(user, "The [src] is out of ink!") \ No newline at end of file diff --git a/code/modules/detective_work/scanner.dm b/code/modules/detective_work/scanner.dm index 59466282384..3a5e19169c0 100644 --- a/code/modules/detective_work/scanner.dm +++ b/code/modules/detective_work/scanner.dm @@ -5,7 +5,8 @@ /obj/item/device/detective_scanner name = "forensic scanner" desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings." - icon_state = "forensic1" + icon = 'icons/goonstation/objects/objects.dmi' + icon_state = "detscanner" w_class = 3.0 item_state = "electronic" flags = CONDUCT | NOBLUDGEON @@ -15,9 +16,56 @@ var/list/log = list() /obj/item/device/detective_scanner/attack_self(var/mob/user) + var/search = input(user, "Enter name, fingerprint or blood DNA.", "Find record", "") + + if (!search || user.stat || user.incapacitated()) + return + + search = lowertext(search) + + var/name + var/fingerprint = "FINGERPRINT NOT FOUND" + var/dna = "BLOOD DNA NOT FOUND" + + // I really, really wish I didn't have to split this into two seperate loops. But the datacore is awful. + + for (var/record in data_core.general) + var/datum/data/record/S = record + if(S && (search == lowertext(S.fields["fingerprint"]) || search == lowertext(S.fields["name"]))) + name = S.fields["name"] + fingerprint = S.fields["fingerprint"] + continue + + for (var/record in data_core.medical) + var/datum/data/record/M = record + if (M && ( search == lowertext(M.fields["b_dna"]) || name == M.fields["name"]) ) + dna = M.fields["b_dna"] + + if(fingerprint == "FINGERPRINT NOT FOUND") // We have searched by DNA, and do not have the relevant information from the fingerprint records. + name = M.fields["name"] + for (var/gen_record in data_core.general) + var/datum/data/record/S = gen_record + if(S && (name == S.fields["name"])) + fingerprint = S.fields["fingerprint"] + continue + continue + + if(name) + to_chat(user, "Match found in station records: [name]
\ + Fingerprint: [fingerprint]
\ + Blood DNA: [dna]") + return + + to_chat(user, "No match found in station records.") + + +/obj/item/device/detective_scanner/verb/print_scanner_report() + set name = "Print Scanner Report" + set category = "Object" + if(log.len && !scanning) scanning = 1 - to_chat(user, "Printing report, please wait...") + to_chat(usr, "Printing report, please wait...") playsound(loc, "sound/goonstation/machines/printer_thermal.ogg", 50, 1) spawn(100) @@ -38,7 +86,8 @@ log = list() scanning = 0 else - to_chat(user, "The scanner has no logs or is in use.") + to_chat(usr, "The scanner has no logs or is in use.") + /obj/item/device/detective_scanner/attack(mob/living/M as mob, mob/user as mob) return @@ -171,4 +220,4 @@ CRASH("[src] \ref[src] is adding a log when it was never put in scanning mode!") /proc/get_timestamp() - return time2text(world.time + 432000, ":ss") \ No newline at end of file + return time2text(world.time + 432000, ":ss") diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 7448d3da352..a8134a82f66 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -49,7 +49,7 @@ log transactions if(linked_db && ( (linked_db.stat & NOPOWER) || !linked_db.activated ) ) linked_db = null authenticated_account = null - src.visible_message("\red \icon[src] [src] buzzes rudely, \"Connection to remote database lost.\"") + src.visible_message("\red [bicon(src)] [src] buzzes rudely, \"Connection to remote database lost.\"") updateDialog() if(ticks_left_timeout > 0) @@ -225,7 +225,7 @@ log transactions var/target_account_number = text2num(href_list["target_acc_number"]) var/transfer_purpose = href_list["purpose"] if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount)) - to_chat(usr, "\icon[src]Funds transfer successful.") + to_chat(usr, "[bicon(src)]Funds transfer successful.") authenticated_account.money -= transfer_amount //create an entry in the account transaction log @@ -238,10 +238,10 @@ log transactions T.amount = "([transfer_amount])" authenticated_account.transaction_log.Add(T) else - to_chat(usr, "\icon[src]Funds transfer failed.") + to_chat(usr, "[bicon(src)]Funds transfer failed.") else - to_chat(usr, "\icon[src]You don't have enough funds to do that!") + to_chat(usr, "[bicon(src)]You don't have enough funds to do that!") if("view_screen") view_screen = text2num(href_list["view_screen"]) if("change_security_level") @@ -275,11 +275,11 @@ log transactions T.time = worldtime2text() failed_account.transaction_log.Add(T) else - to_chat(usr, "\red \icon[src] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.") + to_chat(usr, "\red [bicon(src)] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining.") previous_account_number = tried_account_num playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 1) else - to_chat(usr, "\red \icon[src] incorrect pin/account combination entered.") + to_chat(usr, "\red [bicon(src)] incorrect pin/account combination entered.") number_incorrect_tries = 0 else playsound(src, 'sound/machines/twobeep.ogg', 50, 1) @@ -295,7 +295,7 @@ log transactions T.time = worldtime2text() authenticated_account.transaction_log.Add(T) - to_chat(usr, "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'") + to_chat(usr, "\blue [bicon(src)] Access granted. Welcome user '[authenticated_account.owner_name].'") previous_account_number = tried_account_num if("withdrawal") @@ -323,7 +323,7 @@ log transactions T.time = worldtime2text() authenticated_account.transaction_log.Add(T) else - to_chat(usr, "\icon[src]You don't have enough funds to do that!") + to_chat(usr, "[bicon(src)]You don't have enough funds to do that!") if("balance_statement") if(authenticated_account) if(world.timeofday < lastprint + PRINT_DELAY) @@ -391,7 +391,7 @@ log transactions if(I) authenticated_account = attempt_account_access(I.associated_account_number) if(authenticated_account) - to_chat(human_user, "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'") + to_chat(human_user, "\blue [bicon(src)] Access granted. Welcome user '[authenticated_account.owner_name].'") //create a transaction log entry var/datum/transaction/T = new() diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index a9fe34e1e46..fbb7bb4af7a 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -111,9 +111,9 @@ var/obj/item/weapon/card/I = O scan_card(I) else - to_chat(usr, "\icon[src]Unable to connect to linked account.") + to_chat(usr, "[bicon(src)]Unable to connect to linked account.") else - to_chat(usr, "\icon[src]Unable to connect to accounts database.") + to_chat(usr, "[bicon(src)]Unable to connect to accounts database.") else ..() @@ -130,7 +130,7 @@ alert("That is not a valid code!") print_reference() else - to_chat(usr, "\icon[src]Incorrect code entered.") + to_chat(usr, "[bicon(src)]Incorrect code entered.") if("change_id") var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code")) if(attempt_code == access_code) @@ -139,7 +139,7 @@ eftpos_name = name + " EFTPOS scanner" print_reference() else - to_chat(usr, "\icon[src]Incorrect code entered.") + to_chat(usr, "[bicon(src)]Incorrect code entered.") if("link_account") if(!linked_db) reconnect_database() @@ -148,7 +148,7 @@ var/attempt_pin = input("Enter pin code", "Account pin") as num linked_account = attempt_account_access(attempt_account_num, attempt_pin, 1) else - to_chat(usr, "\icon[src]Unable to connect to accounts database.") + to_chat(usr, "[bicon(src)]Unable to connect to accounts database.") if("trans_purpose") var/purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose") as text|null if(purpose) @@ -168,7 +168,7 @@ else if(linked_account) transaction_locked = 1 else - to_chat(usr, "\icon[src] No account connected to send transactions to.") + to_chat(usr, "[bicon(src)] No account connected to send transactions to.") if("scan_card") //attempt to connect to a new db, and if that doesn't work then fail if(!linked_db) @@ -178,7 +178,7 @@ if (istype(I, /obj/item/weapon/card)) scan_card(I) else - to_chat(usr, "\icon[src]Unable to link accounts.") + to_chat(usr, "[bicon(src)]Unable to link accounts.") if("reset") //reset the access code - requires HoP/captain access var/obj/item/I = usr.get_active_hand() @@ -186,10 +186,10 @@ var/obj/item/weapon/card/id/C = I if(access_cent_commander in C.access || access_hop in C.access || access_captain in C.access) access_code = 0 - to_chat(usr, "\icon[src]Access code reset to 0.") + to_chat(usr, "[bicon(src)]Access code reset to 0.") else if (istype(I, /obj/item/weapon/card/emag)) access_code = 0 - to_chat(usr, "\icon[src]Access code reset to 0.") + to_chat(usr, "[bicon(src)]Access code reset to 0.") src.attack_self(usr) @@ -204,7 +204,7 @@ if(D) if(transaction_amount <= D.money) playsound(src, 'sound/machines/chime.ogg', 50, 1) - src.visible_message("\icon[src] The [src] chimes.") + src.visible_message("[bicon(src)] The [src] chimes.") transaction_paid = 1 //transfer the money @@ -233,11 +233,11 @@ T.time = worldtime2text() linked_account.transaction_log.Add(T) else - to_chat(usr, "\icon[src]You don't have that much money!") + to_chat(usr, "[bicon(src)]You don't have that much money!") else - to_chat(usr, "\icon[src]Unable to access account. Check security settings and try again.") + to_chat(usr, "[bicon(src)]Unable to access account. Check security settings and try again.") else - to_chat(usr, "\icon[src]EFTPOS is not connected to an account.") + to_chat(usr, "[bicon(src)]EFTPOS is not connected to an account.") else ..() diff --git a/code/modules/economy/POS.dm b/code/modules/economy/POS.dm index 79e506ddee9..cbdcb0070fb 100644 --- a/code/modules/economy/POS.dm +++ b/code/modules/economy/POS.dm @@ -391,7 +391,7 @@ var/const/POS_HEADER = {" return /obj/machinery/pos/proc/say(var/text) - src.visible_message("\icon[src] [name] states, \"[text]\"") + src.visible_message("[bicon(src)] [name] states, \"[text]\"") /obj/machinery/pos/Topic(var/href, var/list/href_list) if(..(href,href_list)) return diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm new file mode 100644 index 00000000000..1ab10bc8e4f --- /dev/null +++ b/code/modules/error_handler/error_handler.dm @@ -0,0 +1,104 @@ +var/list/error_last_seen = list() +// error_cooldown items will either be positive (cooldown time) or negative (silenced error) +// If negative, starts at -1, and goes down by 1 each time that error gets skipped +var/list/error_cooldown = list() +var/total_runtimes = 0 +var/total_runtimes_skipped = 0 +// The ifdef needs to be down here, since the error viewer references total_runtimes +#ifdef DEBUG +/world/Error(var/exception/e, var/datum/e_src) + if(!istype(e)) // Something threw an unusual exception + log_to_dd("\[[time_stamp()]] Uncaught exception: [e]") + return ..() + if(!error_last_seen) // A runtime is occurring too early in start-up initialization + return ..() + total_runtimes++ + + var/erroruid = "[e.file][e.line]" + var/last_seen = error_last_seen[erroruid] + var/cooldown = error_cooldown[erroruid] || 0 + if(last_seen == null) // A new error! + error_last_seen[erroruid] = world.time + last_seen = world.time + if(cooldown < 0) + error_cooldown[erroruid]-- // Used to keep track of skip count for this error + total_runtimes_skipped++ + return // Error is currently silenced, skip handling it + + // Handle cooldowns and silencing spammy errors + var/silencing = 0 + // Each occurrence of a unique error adds to its "cooldown" time... + cooldown = max(0, cooldown - (world.time - last_seen)) + ERROR_COOLDOWN + // ... which is used to silence an error if it occurs too often, too fast + if(cooldown > ERROR_MAX_COOLDOWN) + cooldown = -1 + silencing = 1 + spawn(0) + usr = null + sleep(ERROR_SILENCE_TIME) + var/skipcount = abs(error_cooldown[erroruid]) - 1 + error_cooldown[erroruid] = 0 + if(skipcount > 0) + log_to_dd("\[[time_stamp()]] Skipped [skipcount] runtimes in [e.file],[e.line].") + error_cache.logError(e, skipCount = skipcount) + error_last_seen[erroruid] = world.time + error_cooldown[erroruid] = cooldown + + // The detailed error info needs some tweaking to make it look nice + var/list/srcinfo = null + var/list/usrinfo = null + var/locinfo + // First, try to make better src/usr info lines + if(istype(e_src)) + srcinfo = list(" src: [datum_info_line(e_src)]") + locinfo = atom_loc_line(e_src) + if(locinfo) + srcinfo += " src.loc: [locinfo]" + if(istype(usr)) + usrinfo = list(" usr: [datum_info_line(usr)]") + locinfo = atom_loc_line(usr) + if(locinfo) + usrinfo += " usr.loc: [locinfo]" + // The proceeding mess will almost definitely break if error messages are ever changed + // I apologize in advance + var/list/splitlines = splittext(e.desc, "\n") + var/list/desclines = list() + if(splitlines.len > 2) // If there aren't at least three lines, there's no info + for(var/line in splitlines) + if(length(line) < 3) + continue // Blank line, skip it + if(findtext(line, "source file:")) + continue // Redundant, skip it + if(findtext(line, "usr.loc:")) + continue // Our usr.loc is better, skip it + if(findtext(line, "usr:")) + if(usrinfo) + desclines.Add(usrinfo) + usrinfo = null + continue // Our usr info is better, replace it + if(srcinfo) + if(findtext(line, "src.loc:")) + continue + if(findtext(line, "src:")) + desclines.Add(srcinfo) + srcinfo = null + continue + if(copytext(line, 1, 3) != " ") + desclines += (" " + line) // Pad any unpadded lines, so they look pretty + else + desclines += line + if(srcinfo) // If these aren't null, they haven't been added yet + desclines.Add(srcinfo) + if(usrinfo) + desclines.Add(usrinfo) + if(silencing) + desclines += " (This error will now be silenced for [ERROR_SILENCE_TIME / 600] minutes)" + + // Now to actually output the error info... + log_to_dd("\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]") + for(var/line in desclines) + log_to_dd(line) + if(error_cache) + error_cache.logError(e, desclines, e_src = e_src) + +#endif diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm new file mode 100644 index 00000000000..1b8bd092ee2 --- /dev/null +++ b/code/modules/error_handler/error_viewer.dm @@ -0,0 +1,197 @@ +// Error viewing datums, responsible for storing error info, notifying admins +// when errors occur, and showing them to admins on demand. + +// There are 3 different types used here: +// +// - ErrorCache keeps track of all error sources, as well as all individually +// logged errors. Only one instance of this datum should ever exist, and it's +// right here: + +#ifdef DEBUG +var/global/datum/ErrorViewer/ErrorCache/error_cache = new() +#else +// If debugging is disabled, there's nothing useful to log, so don't bother. +var/global/datum/ErrorViewer/ErrorCache/error_cache = null +#endif + +// - ErrorSource datums exist for each line (of code) that generates an error, +// and keep track of all errors generated by that line. +// +// - ErrorEntry datums exist for each logged error, and keep track of all +// relevant info about that error. + +// Common vars and procs are kept at the ErrorViewer level +/datum/ErrorViewer/ + var/name = "" + +/datum/ErrorViewer/proc/browseTo(var/user, var/html) + if(user) + var/datum/browser/popup = new(user, "error_viewer", "Runtime Viewer", 700, 500) + popup.add_head_content({""}) + popup.set_content(html) + popup.open(0) + +/datum/ErrorViewer/proc/buildHeader(var/datum/ErrorViewer/back_to, var/linear, var/refreshable) + // Common starter HTML for showTo + var/html = "" + + if(istype(back_to)) + html += "[back_to.makeLink("<<<", null, linear)] " + if(refreshable) + html += "[makeLink("Refresh", null, linear)]" + if(html) + html += "

" + return html + +/datum/ErrorViewer/proc/showTo(var/user, var/datum/ErrorViewer/back_to, var/linear) + // Specific to each child type + return + +/datum/ErrorViewer/proc/makeLink(var/linktext, var/datum/ErrorViewer/back_to, var/linear) + var/back_to_param = "" + if(!linktext) + linktext = name + if(istype(back_to)) + back_to_param = ";viewruntime_backto=\ref[back_to]" + if(linear) + back_to_param += ";viewruntime_linear=1" + return "[html_encode(linktext)]" + +/datum/ErrorViewer/ErrorCache + var/list/errors = list() + var/list/error_sources = list() + var/list/errors_silenced = list() + +/datum/ErrorViewer/ErrorCache/showTo(var/user, var/datum/ErrorViewer/back_to, var/linear) + var/html = buildHeader(null, linear, refreshable=1) + html += "[total_runtimes] runtimes, [total_runtimes_skipped] skipped

" + if(!linear) + html += "organized | [makeLink("linear", null, 1)]
" + var/datum/ErrorViewer/ErrorSource/error_source + for(var/erroruid in error_sources) + error_source = error_sources[erroruid] + html += "

[error_source.makeLink(null, src)]

" + else + html += "[makeLink("organized", null)] | linear
" + for(var/datum/ErrorViewer/ErrorEntry/error_entry in errors) + html += "

[error_entry.makeLink(null, src, 1)]

" + browseTo(user, html) + +/datum/ErrorViewer/ErrorCache/proc/logError(var/exception/e, var/list/desclines, var/skipCount, var/datum/e_src) + if(!istype(e)) + return // Abnormal exception, don't even bother + + var/erroruid = "[e.file][e.line]" + var/datum/ErrorViewer/ErrorSource/error_source = error_sources[erroruid] + if(!error_source) + error_source = new(e) + error_sources[erroruid] = error_source + + var/datum/ErrorViewer/ErrorEntry/error_entry = new(e, desclines, skipCount, e_src) + error_entry.error_source = error_source + errors += error_entry + error_source.errors += error_entry + if(skipCount) + return // Skip notifying admins about skipped errors + + // Show the error to admins with debug messages turned on, but only if one + // from the same source hasn't been shown too recently + if(error_source.next_message_at <= world.time) + var/const/viewtext = "\[view]" // Nesting these in other brackets went poorly + log_debug("Runtime in [e.file],[e.line]: [html_encode(e.name)] [error_entry.makeLink(viewtext)]") + error_source.next_message_at = world.time + ERROR_MSG_DELAY + +/datum/ErrorViewer/ErrorSource + var/list/errors = list() + var/next_message_at = 0 + +/datum/ErrorViewer/ErrorSource/New(var/exception/e) + if(!istype(e)) + name = "\[[time_stamp()]] Uncaught exceptions" + return + name = "\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]" + +/datum/ErrorViewer/ErrorSource/showTo(var/user, var/datum/ErrorViewer/back_to, var/linear) + if(!istype(back_to)) + back_to = error_cache + var/html = buildHeader(back_to, refreshable=1) + for(var/datum/ErrorViewer/ErrorEntry/error_entry in errors) + html += "

[error_entry.makeLink(null, src)]

" + browseTo(user, html) + +/datum/ErrorViewer/ErrorEntry + var/datum/ErrorViewer/ErrorSource/error_source + var/exception/exc + var/desc = "" + var/srcRef + var/srcType + var/turf/srcLoc + var/usrRef + var/turf/usrLoc + var/isSkipCount + +/datum/ErrorViewer/ErrorEntry/New(var/exception/e, var/list/desclines, var/skipCount, var/datum/e_src) + if(!istype(e)) + name = "\[[time_stamp()]] Uncaught exception: [e]" + return + if(skipCount) + name = "\[[time_stamp()]] Skipped [skipCount] runtimes in [e.file],[e.line]." + isSkipCount = TRUE + return + name = "\[[time_stamp()]] Runtime in [e.file],[e.line]: [e]" + exc = e + if(istype(desclines)) + for(var/line in desclines) + // There's probably a better way to do this than non-breaking spaces... + desc += "  " + html_encode(line) + "
" + if(istype(e_src)) + srcRef = "\ref[e_src]" + srcType = e_src.type + srcLoc = get_turf(e_src) + if(usr) + usrRef = "\ref[usr]" + usrLoc = get_turf(usr) + +/datum/ErrorViewer/ErrorEntry/showTo(var/user, var/datum/ErrorViewer/back_to, var/linear) + if(!istype(back_to)) + back_to = error_source + var/html = buildHeader(back_to, linear) + html += "
[html_encode(name)]
[desc]
" + if(srcRef) + html += "
src: VV" + if(ispath(srcType, /mob)) + html += " PP" + html += " Follow" + if(istype(srcLoc)) + html += "
src.loc: VV" + html += " JMP" + if(usrRef) + html += "
usr: VV" + html += " PP" + html += " Follow" + if(istype(usrLoc)) + html += "
usr.loc: VV" + html += " JMP" + browseTo(user, html) + +/datum/ErrorViewer/ErrorEntry/makeLink(var/linktext, var/datum/ErrorViewer/back_to, var/linear) + if(isSkipCount) + return html_encode(name) + else + return ..() diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 304abd3cd13..5955d60cbec 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -184,6 +184,7 @@ var/list/event_last_fired = list() new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1), new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1), ) diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index 2d7316cc0ef..7837bd61d7c 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -25,11 +25,11 @@ /datum/event/rogue_drone/announce() var/msg if(prob(33)) - msg = "A combat drone wing operating out of the NMV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution." + msg = "A combat drone wing operating out of the NSV Icarus has failed to return from a sweep of this sector, if any are sighted approach with caution." else if(prob(50)) - msg = "Contact has been lost with a combat drone wing operating out of the NMV Icarus. If any are sighted in the area, approach with caution." + msg = "Contact has been lost with a combat drone wing operating out of the NSV Icarus. If any are sighted in the area, approach with caution." else - msg = "Unidentified hackers have targetted a combat drone wing deployed from the NMV Icarus. If any are sighted in the area, approach with caution." + msg = "Unidentified hackers have targetted a combat drone wing deployed from the NSV Icarus. If any are sighted in the area, approach with caution." command_announcement.Announce(msg, "Rogue drone alert") /datum/event/rogue_drone/tick() diff --git a/code/modules/events/traders.dm b/code/modules/events/traders.dm new file mode 100644 index 00000000000..e4c7d95fb89 --- /dev/null +++ b/code/modules/events/traders.dm @@ -0,0 +1,87 @@ +var/global/list/unused_trade_stations = list("sol") + +// Traders event. +// Heavily copy-pasted from "heist" gamemode. + +/datum/event/traders + var/success_spawn = 0 + var/station = null + var/spawn_count = 3 + var/list/trader_objectives = list() + +/datum/event/traders/setup() + if(unused_trade_stations.len) + station = pick_n_take(unused_trade_stations) + +/datum/event/traders/start() + if(!station) // If there are no unused stations, just no. + return + var/list/spawnlocs = list() + for(var/obj/effect/landmark/landmark in landmarks_list) + if(landmark.name == "traderstart_[station]") + spawnlocs += get_turf(landmark) + if(!spawnlocs.len) + return + + trader_objectives = forge_trader_objectives() + + spawn() + var/list/candidates = pollCandidates("Do you want to play as a trader?", ROLE_TRADER, 1) + var/index = 1 + while(spawn_count > 0 && candidates.len > 0) + if(index > spawnlocs.len) + index = 1 + + var/turf/picked_loc = spawnlocs[index] + index++ + var/mob/C = pick_n_take(candidates) + if(C) + respawnable_list -= C.client + var/mob/living/carbon/human/M = create_trader(picked_loc) + M.ckey = C.ckey + M.mind.objectives += trader_objectives + greet_trader(M) + success_spawn = 1 + if(!success_spawn) + unused_trade_stations += station // Return the station to the list of usable stations. + +/datum/event/traders/proc/create_trader(var/turf/picked_loc) + var/mob/living/carbon/human/M + switch(station) + if("sol") + M = new /mob/living/carbon/human(picked_loc) + M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) + M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/cargotech(M), slot_w_uniform) + M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes) + M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(M), slot_back) + var/obj/item/weapon/card/id/supply/W = new(M) + W.name = "[M.real_name]'s ID Card (Sol Trader)" + W.assignment = "Sol Trader" + W.registered_name = M.real_name + W.access = list(access_trade_sol, access_maint_tunnels, access_external_airlocks) + M.equip_to_slot_or_del(W, slot_wear_id) + return M + +/datum/event/traders/proc/greet_trader(var/mob/living/carbon/human/M) + to_chat(M, "You are a trader!") + to_chat(M, "You are currently docked at [get_area(M)].") + to_chat(M, "You are about to trade with NSS Cyberiad.") + to_chat(M, "Negotiate an agreement, and request docking.") + spawn(25) + show_objectives(M.mind) + +/datum/event/traders/proc/forge_trader_objectives() + var/i = 1 + var/max_objectives = pick(2, 2, 2, 2, 3, 3, 3, 4) + var/list/objs = list() + var/list/goals = list("stockparts") + while(i<= max_objectives) + var/goal = pick(goals) + var/datum/objective/trade/O + if(goal == "stockparts") + O = new /datum/objective/trade/stock(station) + O.choose_target() + objs += O + + i++ + return objs diff --git a/code/modules/examine/descriptions/weapons.dm b/code/modules/examine/descriptions/weapons.dm index 90929d31e08..264e0e99dfe 100644 --- a/code/modules/examine/descriptions/weapons.dm +++ b/code/modules/examine/descriptions/weapons.dm @@ -26,7 +26,7 @@ then click where you want to fire. Most energy weapons can fire through windows harmlessly. To switch between stun and lethal, click the weapon \ in your hand. To recharge this weapon, use a weapon recharger." -/obj/item/weapon/gun/energy/advtaser +/obj/item/weapon/gun/energy/gun/advtaser description_info = "This is an energy weapon. To fire the weapon, have your gun mode set to 'fire', \ then click where you want to fire. To recharge this weapon, use a weapon recharger. \ To switch between insta-stun and disabler beams, click the weapon in your hand. This weapon can only fire through glass if it is set to disabler beams." @@ -55,11 +55,6 @@ then click where you want to fire. After firing, you will need to pump the gun, by clicking on the gun in your hand. To reload, load more shotgun \ shells into the gun." -/obj/item/weapon/gun/projectile/heavysniper - description_info = "This is a ballistic weapon. To fire the weapon, have your gun mode set to 'fire', \ - then click where you want to fire. The gun's chamber can be opened or closed by using it in your hand. To reload, open the chamber, add a new bullet \ - then close it. To use the scope, use the appropriate verb in the object tab." - //******* //*Melee* //******* diff --git a/code/modules/examine/examine.dm b/code/modules/examine/examine.dm index c4d54a44ab6..0956877d202 100644 --- a/code/modules/examine/examine.dm +++ b/code/modules/examine/examine.dm @@ -46,7 +46,7 @@ description_holders["antag"] = (update_antag_info)? A.get_description_antag() : "" description_holders["name"] = "[A.name]" - description_holders["icon"] = "\icon[A]" + description_holders["icon"] = "[bicon(A)]" description_holders["desc"] = A.desc /client/Stat() diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index c4088d9a53f..6229105a8b3 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -693,9 +693,10 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite if(slots_free.len) halitem.screen_loc = pick(slots_free) halitem.layer = 50 + halitem.plane = HUD_PLANE switch(rand(1,6)) if(1) //revolver - halitem.icon = 'icons/obj/gun.dmi' + halitem.icon = 'icons/obj/guns/projectile.dmi' halitem.icon_state = "revolver" halitem.name = "Revolver" if(2) //c4 @@ -780,4 +781,4 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite if(client) client.images += halbody spawn(rand(50,80)) //Only seen for a brief moment. if(client) client.images -= halbody - halbody = null \ No newline at end of file + halbody = null diff --git a/code/modules/food/recipes_candy.dm b/code/modules/food/recipes_candy.dm index 8067820786f..2ab54fc0e27 100644 --- a/code/modules/food/recipes_candy.dm +++ b/code/modules/food/recipes_candy.dm @@ -69,7 +69,7 @@ result = /obj/item/weapon/reagent_containers/food/snacks/candy/toffee /datum/recipe/candy/taffy - reagents = list("sugar" = 5, "water" = 5, "sodiumchloride" = 5) + reagents = list("salglu_solution" = 15) items = list() result = /obj/item/weapon/reagent_containers/food/snacks/candy/taffy @@ -532,4 +532,4 @@ /obj/item/weapon/reagent_containers/food/snacks/candy/caramel, /obj/item/weapon/reagent_containers/food/snacks/candy/nougat, ) - result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel_nougat \ No newline at end of file + result = /obj/item/weapon/reagent_containers/food/snacks/candy/candybar/caramel_nougat diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index fd9405cc6bf..40ecc2938e9 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -80,7 +80,7 @@ /obj/item/weapon/grown/nettle/death name = "deathnettle" - desc = "The glowing \black nettle incites rage\black in you just from looking at it!" + desc = "The glowing nettle incites rage in you just from looking at it!" icon_state = "deathnettle" force = 30 throwforce = 15 diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 6e94201c75c..b820a7ad35f 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -68,15 +68,15 @@ active = 0 if(failed_task) failed_task = 0 - visible_message("\icon[src] [src] pings unhappily, flashing a red warning light.") + visible_message("[bicon(src)] [src] pings unhappily, flashing a red warning light.") else - visible_message("\icon[src] [src] pings happily.") + visible_message("[bicon(src)] [src] pings happily.") if(eject_disk) eject_disk = 0 if(loaded_disk) loaded_disk.loc = get_turf(src) - visible_message("\icon[src] [src] beeps and spits out [loaded_disk].") + visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null /obj/machinery/botany/attackby(obj/item/weapon/W as obj, mob/user as mob) @@ -212,14 +212,14 @@ plant_controller.seeds[seed.seed.name] = seed.seed seed.update_seed() - visible_message("\icon[src] [src] beeps and spits out [seed].") + visible_message("[bicon(src)] [src] beeps and spits out [seed].") seed = null if(href_list["eject_disk"]) if(!loaded_disk) return loaded_disk.loc = get_turf(src) - visible_message("\icon[src] [src] beeps and spits out [loaded_disk].") + visible_message("[bicon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null usr.set_machine(src) diff --git a/code/modules/media/jukebox.dm b/code/modules/media/jukebox.dm index 9cea989fde7..623241ca491 100644 --- a/code/modules/media/jukebox.dm +++ b/code/modules/media/jukebox.dm @@ -218,7 +218,7 @@ var/global/loopModeNames=list( if(response) var/json = file2text(response["CONTENT"]) if("/>" in json) - visible_message("\icon[src] \The [src] buzzes, unable to update its playlist.","You hear a buzz.") + visible_message("[bicon(src)] \The [src] buzzes, unable to update its playlist.","You hear a buzz.") stat &= BROKEN update_icon() return @@ -226,11 +226,11 @@ var/global/loopModeNames=list( for(var/list/record in songdata) playlist += new /datum/song_info(record) if(playlist.len==0) - visible_message("\icon[src] \The [src] buzzes, unable to update its playlist.","You hear a buzz.") + visible_message("[bicon(src)] \The [src] buzzes, unable to update its playlist.","You hear a buzz.") stat &= BROKEN update_icon() return - visible_message("\icon[src] \The [src] beeps, and the menu on its front fills with [playlist.len] items.","You hear a beep.") + visible_message("[bicon(src)] \The [src] beeps, and the menu on its front fills with [playlist.len] items.","You hear a beep.") if(autoplay) playing=1 autoplay=0 @@ -261,8 +261,8 @@ var/global/loopModeNames=list( var/datum/song_info/song = playlist[current_song] media_url = song.url media_start_time = world.time - visible_message("\icon[src] \The [src] begins to play [song.display()].","You hear music.") - //visible_message("\icon[src] \The [src] warbles: [song.length/10]s @ [song.url]") + visible_message("[bicon(src)] \The [src] begins to play [song.display()].","You hear music.") + //visible_message("[bicon(src)] \The [src] warbles: [song.length/10]s @ [song.url]") else media_url="" media_start_time = 0 diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index ee84c1a5864..148ea595f04 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -292,6 +292,7 @@ s.use(s.max_amount) s.forceMove(loc) s.layer = initial(s.layer) + s.plane = initial(s.plane) /obj/machinery/mineral/ore_redemption/power_change() ..() @@ -730,13 +731,13 @@ if(istype(I, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/W = I if(W.welding && !stat) - if(AIStatus == AI_ON) + if(FindTarget())//if the bot has anything to shoot at, to prevent combat repair cheesing to_chat(user, "[src] is moving around too much to repair!") return if(maxHealth == health) to_chat(user, "[src] is at full integrity.") else - health += 10 + adjustHealth(-10)//actually repairs the bot, not damages it to_chat(user, "You repair some of the armor on [src].") return if(istype(I, /obj/item/device/mining_scanner) || istype(I, /obj/item/device/t_scanner/adv_mining_scanner)) diff --git a/code/modules/mining/security_recipes.dm b/code/modules/mining/security_recipes.dm index f08addbf4a0..9cbdeadc154 100644 --- a/code/modules/mining/security_recipes.dm +++ b/code/modules/mining/security_recipes.dm @@ -99,7 +99,7 @@ /datum/manufacture/taser name = "Advanced Taser" - item = /obj/item/weapon/gun/energy/advtaser + item = /obj/item/weapon/gun/energy/gun/advtaser cost1 = /obj/item/weapon/ore/iron cname1 = "Iron" amount1 = 15 diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index 7f63a8f1261..a6269b96d36 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -14,52 +14,8 @@ if (src.client.handle_spam_prevention(message,MUTE_DEADCHAT)) return + if(copytext(message,1,2) == "*") + return emote(copytext(message,2)) + . = src.say_dead(message) - -/mob/dead/observer/emote(var/act, var/type, var/message) - message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN)) - - if(!message) - return - - if(act != "me") - return - - log_emote("Ghost/[src.key] : [message]") - - if(src.client) - if(src.client.prefs.muted & MUTE_DEADCHAT) - to_chat(src, "\red You cannot emote in deadchat (muted).") - return - - if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT)) - return - - . = src.emote_dead(message) - -/* - for (var/mob/M in hearers(null, null)) - if (!M.stat) - if(M.job == "Chaplain") - if (prob (49)) - M.show_message("You hear muffled speech... but nothing is there...", 2) - if(prob(20)) - playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1) - else - M.show_message("You hear muffled speech... you can almost make out some words...", 2) -// M.show_message("[stutter(message)]", 2) - if(prob(30)) - playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1) - else - if (prob(50)) - return - else if (prob (95)) - M.show_message("You hear muffled speech... but nothing is there...", 2) - if(prob(20)) - playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1) - else - M.show_message("You hear muffled speech... you can almost make out some words...", 2) -// M.show_message("[stutter(message)]", 2) - playsound(src.loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1) -*/ diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 2bfe10a1f35..11e51987285 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -76,6 +76,10 @@ /mob/proc/death(gibbed) + //Makes it so gib/dust/melt all unbuckle their victims from anything they may be buckled to to avoid breaking beds/chairs/etc + if(gibbed && buckled) + buckled.unbuckle_mob() + //Quick fix for corpses kept propped up in chairs. ~Z drop_r_hand() drop_l_hand() diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm deleted file mode 100644 index 8d03cdd969a..00000000000 --- a/code/modules/mob/emote.dm +++ /dev/null @@ -1,124 +0,0 @@ -#define EMOTE_COOLDOWN 20 //Time in deciseconds that the cooldown lasts - -//Emote Cooldown System (it's so simple!) -/mob/proc/handle_emote_CD(cooldown = EMOTE_COOLDOWN) - if(emote_cd == 2) return 1 // Cooldown emotes were disabled by an admin, prevent use - if(src.emote_cd == 1) return 1 // Already on CD, prevent use - - src.emote_cd = 1 // Starting cooldown - spawn(cooldown) - if(emote_cd == 2) return 1 // Don't reset if cooldown emotes were disabled by an admin during the cooldown - src.emote_cd = 0 // Cooldown complete, ready for more! - - return 0 // Proceed with emote -//--FalseIncarnate - -// All mobs should have custom emote, really.. -/mob/proc/custom_emote(var/m_type=1,var/message = null) - - if(stat || !use_me && usr == src) - to_chat(usr, "You are unable to emote.") - return - - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) - if(m_type == 2 && muzzled) return - - var/input - if(!message) - input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN)) - else - input = message - if(input) - message = "[src] [input]" - else - return - - - if (message) - log_emote("[name]/[key] : [message]") - - //Hearing gasp and such every five seconds is not good emotes were not global for a reason. - // Maybe some people are okay with that. - - for(var/mob/M in player_list) - if (!M.client) - continue //skip monkeys and leavers - if (istype(M, /mob/new_player)) - continue - if(findtext(message," snores.")) //Because we have so many sleeping people. - break - if(M.stat == 2 && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) - M.show_message(message) - - - // Type 1 (Visual) emotes are sent to anyone in view of the item - if (m_type & 1) - var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around. - can_see |= viewers(src,null) - for (var/mob/O in can_see) - - if(O.status_flags & PASSEMOTES) - - for(var/obj/item/weapon/holder/H in O.contents) - H.show_message(message, m_type) - - for(var/mob/living/M in O.contents) - M.show_message(message, m_type) - - O.show_message(message, m_type) - - // Type 2 (Audible) emotes are sent to anyone in hear range - // of the *LOCATION* -- this is important for pAIs to be heard - else if (m_type & 2) - for (var/mob/O in get_mobs_in_view(7,src)) - - if(O.status_flags & PASSEMOTES) - - for(var/obj/item/weapon/holder/H in O.contents) - H.show_message(message, m_type) - - for(var/mob/living/M in O.contents) - M.show_message(message, m_type) - - O.show_message(message, m_type) - -/mob/proc/emote_dead(var/message) - - if(client.prefs.muted & MUTE_DEADCHAT) - to_chat(src, "\red You cannot send deadchat emotes (muted).") - return - - if(!(client.prefs.toggles & CHAT_DEAD)) - to_chat(src, "\red You have deadchat muted.") - return - - if(!src.client.holder) - if(!config.dsay_allowed) - to_chat(src, "\red Deadchat is globally muted") - return - - - var/input - if(!message) - input = sanitize(copytext(input(src, "Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN)) - else - input = message - - if(input) - message = "DEAD: [src] [message]" - else - return - - - if(message) - log_emote("Ghost/[src.key] : [message]") - - for(var/mob/M in player_list) - if(istype(M, /mob/new_player)) - continue - - if(check_rights(R_ADMIN|R_MOD, 0, M) && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to admins/mods - to_chat(M, message) - - else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on - M.show_message(message, 2) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 8d68373e3f4..bbc313e0421 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -28,6 +28,7 @@ W.forceMove(src) //TODO: move to equipped? l_hand = W W.layer = 20 //TODO: move to equipped? + W.plane = HUD_PLANE //TODO: move to equipped? W.equipped(src,slot_l_hand) if(pulling == W) stop_pulling() @@ -43,6 +44,7 @@ W.forceMove(src) r_hand = W W.layer = 20 + W.plane = HUD_PLANE W.equipped(src,slot_r_hand) if(pulling == W) stop_pulling() @@ -72,6 +74,7 @@ /mob/proc/put_in_hands(obj/item/W) W.forceMove(get_turf(src)) W.layer = initial(W.layer) + W.plane = initial(W.plane) W.dropped() /mob/proc/drop_item_v() //this is dumb. @@ -124,6 +127,7 @@ I.dropped(src) if(I) I.layer = initial(I.layer) + I.plane = initial(I.plane) return 1 diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index c88684c77c0..6abd4acd6fc 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -213,7 +213,7 @@ colour = "vox" key = "v" flags = RESTRICTED | WHITELISTED - syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ + syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya", "yi", "chi","cha","kah", \ "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") /datum/language/vox/get_random_name() @@ -278,7 +278,7 @@ /datum/language/drask name = "Orluum" - desc = "The droning, vibrous language of the Drask. It sounds somewhat like whalesong" + desc = "The droning, vibrous language of the Drask. It sounds somewhat like whalesong." speech_verb = "drones" ask_verb = "hums" exclaim_verb = "rumbles" diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index afae056b99f..9311ab0592f 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -123,8 +123,8 @@ Doesn't work on other aliens/AI.*/ A.firer = src A.yo = U.y - T.y A.xo = U.x - T.x - spawn(1) - A.process() + A.fire() + A.newtonian_move(get_dir(U, T)) return /mob/living/carbon/alien/humanoid/proc/resin() // -- TLE @@ -185,4 +185,4 @@ Doesn't work on other aliens/AI.*/ adjustPlasma(-amount) return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/emote.dm b/code/modules/mob/living/carbon/alien/humanoid/emote.dm deleted file mode 100644 index c20cc155f37..00000000000 --- a/code/modules/mob/living/carbon/alien/humanoid/emote.dm +++ /dev/null @@ -1,115 +0,0 @@ -/mob/living/carbon/alien/humanoid/emote(var/act,var/m_type=1,var/message = null) - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - -// if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' -// act = copytext(act,1,length(act)) //seriously who the fuck wrote this - var/muzzled = is_muzzled() - act = lowertext(act) - switch(act) - if("sign") - if(!restrained()) - var/num = null - if(text2num(param)) - num = "the number [text2num(param)]" - if(num) - message = "\The [src] signs [num]." - m_type = 1 - if ("burp") - if (!muzzled) - message = "\The [src] burps." - m_type = 2 - if ("deathgasp") - message = "\The [src] lets out a waning guttural screech, green blood bubbling from its maw..." - m_type = 2 - if("scratch") - if (!src.restrained()) - message = "\The [src] scratches." - m_type = 1 - if("whimper") - if (!muzzled) - message = "\The [src] whimpers." - m_type = 2 - if("roar") - if (!muzzled) - message = "\The [src] roars." - m_type = 2 - if("hiss") - if(!muzzled) - message = "\The [src] hisses." - m_type = 2 - if("tail") - message = "\The [src] waves its tail." - m_type = 1 - if("gasp") - message = "\The [src] gasps." - m_type = 2 - if("shiver") - message = "\The [src] shivers." - m_type = 2 - if("drool") - message = "\The [src] drools." - m_type = 1 - if("scretch") - if (!muzzled) - message = "\The [src] scretches." - m_type = 2 - if("choke") - message = "\The [src] chokes." - m_type = 2 - if("moan") - message = "\The [src] moans!" - m_type = 2 - if("nod") - message = "\The [src] nods its head." - m_type = 1 - if("sit") - message = "\The [src] sits down." - m_type = 1 - if("sway") - message = "\The [src] sways around dizzily." - m_type = 1 - if("sulk") - message = "\The [src] sulks down sadly." - m_type = 1 - if("twitch") - message = "\The [src] twitches violently." - m_type = 1 - if("dance") - if (!src.restrained()) - message = "\The [src] dances around happily." - m_type = 1 - if("roll") - if (!src.restrained()) - message = "\The [src] rolls." - m_type = 1 - if("shake") - message = "\The [src] shakes its head." - m_type = 1 - if("gnarl") - if (!muzzled) - message = "\The [src] gnarls and shows its teeth.." - m_type = 2 - if("jump") - message = "\The [src] jumps!" - m_type = 1 - if("collapse") - Paralyse(2) - message = "\The [src] collapses!" - m_type = 2 - if ("flip") - m_type = 1 - message = "\The [src] does a flip!" - src.SpinAnimation(5,1) - if("help") - to_chat(src, "burp, flip, deathgasp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper") - - if(!stat) - if (act == "roar") - playsound(src.loc, 'sound/voice/hiss5.ogg', 40, 1, 1) - if (act == "deathgasp") - playsound(src.loc, 'sound/voice/hiss6.ogg', 80, 1, 1) - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/larva/emote.dm b/code/modules/mob/living/carbon/alien/larva/emote.dm deleted file mode 100644 index dc7a66f7018..00000000000 --- a/code/modules/mob/living/carbon/alien/larva/emote.dm +++ /dev/null @@ -1,126 +0,0 @@ -/mob/living/carbon/alien/larva/emote(var/act,var/m_type=1,var/message = null) - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - var/muzzled = is_muzzled() - act = lowertext(act) - switch(act) - if ("me") - if(silent) - return - if (src.client) - if (client.prefs.muted & MUTE_IC) - to_chat(src, "\red You cannot send IC messages (muted).") - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - if (stat) - return - if(!(message)) - return - return custom_emote(m_type, message) - - if ("custom") - return custom_emote(m_type, message) - if("sign") - if (!src.restrained()) - message = text("The alien signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null)) - m_type = 1 - if ("burp") - if (!muzzled) - message = "[src] burps." - m_type = 2 - if("scratch") - if (!src.restrained()) - message = "The [src.name] scratches." - m_type = 1 - if("whimper") - if (!muzzled) - message = "The [src.name] whimpers." - m_type = 2 -// if("roar") -// if (!muzzled) -// message = "The [src.name] roars." Commenting out since larva shouldn't roar /N -// m_type = 2 - if("tail") - message = "The [src.name] waves its tail." - m_type = 1 - if("gasp") - message = "The [src.name] gasps." - m_type = 2 - if("shiver") - message = "The [src.name] shivers." - m_type = 2 - if("drool") - message = "The [src.name] drools." - m_type = 1 - if("scretch") - if (!muzzled) - message = "The [src.name] scretches." - m_type = 2 - if("choke") - message = "The [src.name] chokes." - m_type = 2 - if("moan") - message = "The [src.name] moans!" - m_type = 2 - if("nod") - message = "The [src.name] nods its head." - m_type = 1 -// if("sit") -// message = "The [src.name] sits down." //Larvan can't sit down, /N -// m_type = 1 - if("sway") - message = "The [src.name] sways around dizzily." - m_type = 1 - if("sulk") - message = "The [src.name] sulks down sadly." - m_type = 1 - if("twitch") - message = "The [src.name] twitches violently." - m_type = 1 - if("dance") - if (!src.restrained()) - message = "The [src.name] dances around happily." - m_type = 1 - if("roll") - if (!src.restrained()) - message = "The [src.name] rolls." - m_type = 1 - if("shake") - message = "The [src.name] shakes its head." - m_type = 1 - if("gnarl") - if (!muzzled) - message = "The [src.name] gnarls and shows its teeth.." - m_type = 2 - if("jump") - message = "The [src.name] jumps!" - m_type = 1 - if("hiss_") - message = "The [src.name] hisses softly." - m_type = 1 - if("collapse") - Paralyse(2) - message = text("[] collapses!", src) - m_type = 2 - if("help") - to_chat(src, "burp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper") - else - to_chat(src, text("Invalid Emote: []", act)) - if ((message && src.stat == 0)) - log_emote("[name]/[key] : [message]") - if (m_type & 1) - for(var/mob/O in viewers(src, null)) - O.show_message(message, m_type) - //Foreach goto(703) - else - for(var/mob/O in hearers(src, null)) - O.show_message(message, m_type) - //Foreach goto(746) - return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/emote.dm b/code/modules/mob/living/carbon/brain/emote.dm deleted file mode 100644 index 16cf01e4266..00000000000 --- a/code/modules/mob/living/carbon/brain/emote.dm +++ /dev/null @@ -1,51 +0,0 @@ -/mob/living/carbon/brain/emote(var/act,var/m_type=1,var/message = null) - if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes - return - - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - if(src.stat == DEAD) - return - act = lowertext(act) - switch(act) - - if ("alarm") - to_chat(src, "You sound an alarm.") - message = "\The [src] sounds an alarm." - m_type = 2 - if ("alert") - to_chat(src, "You let out a distressed noise.") - message = "\The [src] lets out a distressed noise." - m_type = 2 - if ("notice") - to_chat(src, "You play a loud tone.") - message = "\The [src] plays a loud tone." - m_type = 2 - if ("flash") - message = "The lights on \the [src] flash quickly." - m_type = 1 - if ("blink") - message = "\The [src] blinks." - m_type = 1 - if ("whistle") - to_chat(src, "You whistle.") - message = "\The [src] whistles." - m_type = 2 - if ("beep") - to_chat(src, "You beep.") - message = "\The [src] beeps." - m_type = 2 - if ("boop") - to_chat(src, "You boop.") - message = "\The [src] boops." - m_type = 2 - if ("help") - to_chat(src, "alarm, alert, notice, flash,blink, whistle, beep, boop") - - if(message && !stat) - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index f6cdb0362e3..f37faf32750 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -147,7 +147,7 @@ if(!..(user)) return - var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n" + var/msg = "*---------*\nThis is [bicon(src)] \a [src]!\n[desc]\n" msg += "" if(src.brainmob && src.brainmob.key) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 5a641a81689..f9afba579fb 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -455,6 +455,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, for(var/obj/machinery/atmospherics/A in totalMembers) if(!A.pipe_image) A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir) //the 20 puts it above Byond's darkness (not its opacity view) + A.pipe_image.plane = HUD_PLANE pipes_shown += A.pipe_image client.images += A.pipe_image @@ -517,57 +518,39 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/throw_item(atom/target) throw_mode_off() - if(stat || !target) + if(!target || !isturf(loc)) return - if(target.type == /obj/screen) + if(istype(target, /obj/screen)) return - var/atom/movable/item = get_active_hand() + var/atom/movable/thrown_thing + var/obj/item/I = src.get_active_hand() - if(!item || (item.flags & NODROP)) + if(!I || (I.flags & NODROP)) return - if (istype(item, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = item - item = G.get_mob_if_throwable() //throw the person instead of the grab - if(ismob(item)) + if(istype(I, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = I + var/mob/throwable_mob = G.get_mob_if_throwable() //throw the person instead of the grab + qdel(G) //We delete the grab. + if(throwable_mob) + thrown_thing = throwable_mob var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) if(start_T && end_T) - var/mob/M = item var/start_T_descriptor = "tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]" var/end_T_descriptor = "tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]" - M.attack_log += text("\[[time_stamp()]\] Has been thrown by [key_name(src)] from [start_T_descriptor] with the target [end_T_descriptor]") - attack_log += text("\[[time_stamp()]\] Has thrown [key_name(M)] from [start_T_descriptor] with the target [end_T_descriptor]") - msg_admin_attack("[key_name_admin(src)] has thrown [key_name_admin(M)] from [start_T_descriptor] with the target [end_T_descriptor]") + add_logs(throwable_mob, src, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]") - if(!iscarbon(src)) - M.LAssailant = null - else - M.LAssailant = src - - if(!item) - return //Grab processing has a chance of returning null - if(!ismob(item)) //Honk mobs don't have a dropped() proc honk - unEquip(item) - update_icons() - - if (istype(src, /mob/living/carbon)) //Check if a carbon mob is throwing. Modify/remove this line as required. - item.loc = loc - if(client) - client.screen -= item - if(istype(item, /obj/item)) - item:dropped(src) // let it know it's been dropped - - //actually throw it! - if (item) - item.layer = initial(item.layer) - visible_message("\red [src] has thrown [item].") + else if(!(I.flags & ABSTRACT)) //can't throw abstract items + thrown_thing = I + unEquip(I) + if(thrown_thing) + visible_message("[src] has thrown [thrown_thing].") newtonian_move(get_dir(target, src)) - - item.throw_at(target, item.throw_range, item.throw_speed, src) + thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src) /* /mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() @@ -863,6 +846,12 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, //called when we get cuffed/uncuffed /mob/living/carbon/proc/update_handcuffed() if(handcuffed) + //we don't want problems with nodrop shit if there ever is more than one nodrop twohanded + var/obj/item/I = get_active_hand() + if(istype(I, /obj/item/weapon/twohanded)) + var/obj/item/weapon/twohanded/TH = I //FML + if(TH.wielded) + TH.unwield() drop_r_hand() drop_l_hand() stop_pulling() @@ -914,6 +903,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, W.dropped(src) if (W) W.layer = initial(W.layer) + W.plane = initial(W.plane) if (legcuffed) var/obj/item/weapon/W = legcuffed legcuffed = null @@ -925,6 +915,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, W.dropped(src) if (W) W.layer = initial(W.layer) + W.plane = initial(W.plane) /mob/living/carbon/proc/slip(var/description, var/stun, var/weaken, var/tilesSlipped, var/walkSafely, var/slipAny) @@ -992,13 +983,15 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return 1 /mob/living/carbon/proc/forceFed(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, fullness) - if (fullness <= (550 * (1 + overeatduration / 1000))) - visible_message("[user] attempts to force [src] to [toEat.apply_method] [toEat].") + if(fullness <= (550 * (1 + overeatduration / 1000))) + if(!toEat.instant_application) + visible_message("[user] attempts to force [src] to [toEat.apply_method] [toEat].") else visible_message("[user] cannot force anymore of [toEat] down [src]'s throat.") return 0 - if(!do_mob(user, src)) - return 0 + if(!toEat.instant_application) + if(!do_mob(user, src)) + return 0 forceFedAttackLog(toEat, user) visible_message("[user] forces [src] to [toEat.apply_method] [toEat].") return 1 diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 13e8fe153ea..9dfa6efac89 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -49,6 +49,7 @@ target.l_hand = I I.loc = target I.layer = 20 + I.plane = HUD_PLANE I.add_fingerprint(target) src.update_inv_l_hand() src.update_inv_r_hand() diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 52488051f50..f3cd00463e2 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -243,7 +243,7 @@ return 1 /mob/living/carbon/human/proc/change_skin_tone(var/tone) - if(s_tone == tone || !(species.bodyflags & HAS_SKIN_TONE)) + if(s_tone == tone || !((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) return s_tone = tone diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index fce12362d73..5ac5d796897 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -118,10 +118,6 @@ callHook("death", list(src, gibbed)) - if(ticker && ticker.mode) - if(istype(ticker.mode,/datum/game_mode/heist)) - vox_kills++ //Bad vox. Shouldn't be killing humans. - if(ishuman(LAssailant)) var/mob/living/carbon/human/H=LAssailant if(H.mind) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm deleted file mode 100644 index b1d7e356b39..00000000000 --- a/code/modules/mob/living/carbon/human/emote.dm +++ /dev/null @@ -1,884 +0,0 @@ -/mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null,var/force) - - if (stat == DEAD) - return // No screaming bodies - - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - var/muzzled = is_muzzled() - if(sdisabilities & MUTE || silent) - muzzled = 1 - //var/m_type = 1 - - for (var/obj/item/weapon/implant/I in src) - if (I.implanted) - I.trigger(act, src) - - var/miming = 0 - if(mind) - miming = mind.miming - - //Emote Cooldown System (it's so simple!) - // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] - var/on_CD = 0 - act = lowertext(act) - switch(act) - //Cooldown-inducing emotes - if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no") - if (species.name == "Machine") //Only Machines can beep, ping, and buzz - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - else //Everyone else fails, skip the emote attempt - return - if("drone","drones","hum","hums","rumble","rumbles") - if (species.name == "Drask") //Only Drask can make whale noises - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - else - return - if("squish", "squishes") - var/found_slime_bodypart = 0 - - if(species.name == "Slime People") //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 organs) // if your limbs are squishy you can squish too! - if(L.dna.species in list("Slime People")) - on_CD = handle_emote_CD() - found_slime_bodypart = 1 - break - - if(!found_slime_bodypart) //Everyone else fails, skip the emote attempt - return - if("scream", "screams") - on_CD = handle_emote_CD(50) //longer cooldown - if("fart", "farts", "flip", "flips", "snap", "snaps") - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - //Everything else, including typos of the above emotes - else - on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown - - if(on_CD == 1) // Check if we need to suppress the emote attempt. - return // Suppress emote, you're still cooling off. - - switch(act) - if("me") //OKAY SO RANT TIME, THIS FUCKING HAS TO BE HERE OR A SHITLOAD OF THINGS BREAK - return custom_emote(m_type, message) //DO YOU KNOW WHY SHIT BREAKS? BECAUSE SO MUCH OLDCODE CALLS mob.emote("me",1,"whatever_the_fuck_it_wants_to_emote") - //WHO THE FUCK THOUGHT THAT WAS A GOOD FUCKING IDEA!?!? - - if("ping", "pings") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] pings at [param]." - else - message = "[src] pings." - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - m_type = 2 - - if("buzz", "buzzes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] buzzes at [param]." - else - message = "[src] buzzes." - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - m_type = 2 - - if("beep", "beeps") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] beeps at [param]." - else - message = "[src] beeps." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - m_type = 2 - - if("drone", "drones", "hum", "hums", "rumble", "rumbles") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] drones at [param]." - else - message = "[src] rumbles." - playsound(src.loc, 'sound/voice/DraskTalk.ogg', 50, 0) - m_type = 2 - - if("squish", "squishes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] squishes at [param]." - else - message = "[src] squishes." - playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound. - m_type = 2 - - if("yes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits an affirmative blip at [param]." - else - message = "[src] emits an affirmative blip." - playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) - m_type = 2 - - if("no") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits a negative blip at [param]." - else - message = "[src] emits a negative blip." - playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) - m_type = 2 - - if("wag", "wags") - if(body_accessory) - if(body_accessory.try_restrictions(src)) - message = "[src] starts wagging \his tail." - start_tail_wagging(1) - - else if(species.bodyflags & TAIL_WAGGING) - if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) - message = "[src] starts wagging \his tail." - src.start_tail_wagging(1) - else - return - else - return - m_type = 1 - - if("swag", "swags") - if(species.bodyflags & TAIL_WAGGING || body_accessory) - message = "[src] stops wagging \his tail." - src.stop_tail_wagging(1) - else - return - m_type = 1 - - if ("airguitar") - if (!src.restrained()) - message = "[src] is strumming the air and headbanging like a safari chimp." - m_type = 1 - - if ("blink", "blinks") - message = "[src] blinks." - m_type = 1 - - if ("blink_r", "blinks_r") - message = "[src] blinks rapidly." - m_type = 1 - - if ("bow", "bows") - if (!src.buckled) - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] bows to [param]." - else - message = "[src] bows." - m_type = 1 - - if ("salute", "salutes") - if (!src.buckled) - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] salutes to [param]." - else - message = "[src] salutes." - m_type = 1 - - if ("choke", "chokes") - if(miming) - message = "[src] clutches \his throat desperately!" - m_type = 1 - else - if (!muzzled) - message = "[src] chokes!" - m_type = 2 - else - message = "[src] makes a strong noise." - m_type = 2 - - if ("burp", "burps") - if(miming) - message = "[src] opens their mouth rather obnoxiously." - m_type = 1 - else - if (!muzzled) - message = "[src] burps." - m_type = 2 - else - message = "[src] makes a peculiar noise." - m_type = 2 - if ("clap", "claps") - if (!src.restrained()) - message = "[src] claps." - m_type = 2 - if(miming) - m_type = 1 - if ("flap", "flaps") - if (!src.restrained()) - message = "[src] flaps \his wings." - m_type = 2 - if(miming) - m_type = 1 - - if ("flip", "flips") - m_type = 1 - if (!src.restrained()) - var/M = null - if (param) - for (var/mob/A in view(1, null)) - if (param == A.name) - M = A - break - if (M == src) - M = null - - if(M) - if(lying || weakened) - message = "[src] flops and flails around on the floor." - else - message = "[src] flips in [M]'s general direction." - SpinAnimation(5,1) - else - if(lying || weakened) - message = "[src] flops and flails around on the floor." - else - var/obj/item/weapon/grab/G - if(istype(get_active_hand(), /obj/item/weapon/grab)) - G = get_active_hand() - if(G && G.affecting) - if(buckled || G.affecting.buckled) - return - var/turf/oldloc = loc - var/turf/newloc = G.affecting.loc - if(isturf(oldloc) && isturf(newloc)) - SpinAnimation(5,1) - forceMove(newloc) - G.affecting.forceMove(oldloc) - message = "[src] flips over [G.affecting]!" - else - message = "[src] does a flip!" - SpinAnimation(5,1) - - if ("aflap", "aflaps") - if (!src.restrained()) - message = "[src] flaps \his wings ANGRILY!" - m_type = 2 - if(miming) - m_type = 1 - - if ("drool", "drools") - message = "[src] drools." - m_type = 1 - - if ("eyebrow") - message = "[src] raises an eyebrow." - m_type = 1 - - if ("chuckle", "chuckles") - if(miming) - message = "[src] appears to chuckle." - m_type = 1 - else - if (!muzzled) - message = "[src] chuckles." - m_type = 2 - else - message = "[src] makes a noise." - m_type = 2 - - if ("twitch", "twitches") - message = "[src] twitches violently." - m_type = 1 - - if ("twitch_s", "twitches_s") - message = "[src] twitches." - m_type = 1 - - if ("faint", "faints") - message = "[src] faints." - if(src.sleeping) - return //Can't faint while asleep - src.sleeping += 1 - m_type = 1 - - if ("cough", "coughs") - if(miming) - message = "[src] appears to cough!" - m_type = 1 - else - if (!muzzled) - message = "[src] coughs!" - m_type = 2 - else - message = "[src] makes a strong noise." - m_type = 2 - - if ("frown", "frowns") - message = "[src] frowns." - m_type = 1 - - if ("nod", "nods") - message = "[src] nods." - m_type = 1 - - if ("blush", "blushes") - message = "[src] blushes." - m_type = 1 - - if ("wave", "waves") - message = "[src] waves." - m_type = 1 - - if ("quiver", "quivers") - message = "[src] quivers." - m_type = 1 - - if ("gasp", "gasps") - if(miming) - message = "[src] appears to be gasping!" - m_type = 1 - else - if (!muzzled) - message = "[src] gasps!" - m_type = 2 - else - message = "[src] makes a weak noise." - m_type = 2 - - if ("deathgasp", "deathgasps") - message = "[src] [species.death_message]" - m_type = 1 - - if ("giggle", "giggles") - if(miming) - message = "[src] giggles silently!" - m_type = 1 - else - if (!muzzled) - message = "[src] giggles." - m_type = 2 - else - message = "[src] makes a noise." - m_type = 2 - - if ("glare", "glares") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] glares at [param]." - else - message = "[src] glares." - m_type = 1 - - if ("stare", "stares") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] stares at [param]." - else - message = "[src] stares." - m_type = 1 - - if ("look", "looks") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - - if (!M) - param = null - - if (param) - message = "[src] looks at [param]." - else - message = "[src] looks." - m_type = 1 - - if ("grin", "grins") - message = "[src] grins." - m_type = 1 - - if ("cry", "cries") - if(miming) - message = "[src] cries." - m_type = 1 - else - if (!muzzled) - message = "[src] cries." - m_type = 2 - else - message = "[src] makes a weak noise. \He frowns." - m_type = 2 - - if ("sigh", "sighs") - if(miming) - message = "[src] sighs." - m_type = 1 - else - if (!muzzled) - message = "[src] sighs." - m_type = 2 - else - message = "[src] makes a weak noise." - m_type = 2 - - if ("laugh", "laughs") - if(miming) - message = "[src] acts out a laugh." - m_type = 1 - else - if (!muzzled) - message = "[src] laughs." - m_type = 2 - else - message = "[src] makes a noise." - m_type = 2 - - if ("mumble", "mumbles") - message = "[src] mumbles!" - m_type = 2 - if(miming) - m_type = 1 - - if ("grumble", "grumbles") - if(miming) - message = "[src] grumbles!" - m_type = 1 - if (!muzzled) - message = "[src] grumbles!" - m_type = 2 - else - message = "[src] makes a noise." - m_type = 2 - - if ("groan", "groans") - if(miming) - message = "[src] appears to groan!" - m_type = 1 - else - if (!muzzled) - message = "[src] groans!" - m_type = 2 - else - message = "[src] makes a loud noise." - m_type = 2 - - if ("moan", "moans") - if(miming) - message = "[src] appears to moan!" - m_type = 1 - else - message = "[src] moans!" - m_type = 2 - - if ("johnny") - var/M - if (param) - M = param - if (!M) - param = null - else - if(miming) - message = "[src] takes a drag from a cigarette and blows \"[M]\" out in smoke." - m_type = 1 - else - message = "[src] says, \"[M], please. They had a family.\" [src.name] takes a drag from a cigarette and blows their name out in smoke." - m_type = 2 - - if ("point", "points") - if (!src.restrained()) - var/atom/M = null - if (param) - for (var/atom/A as mob|obj|turf in view()) - if (param == A.name) - M = A - break - - if (!M) - message = "[src] points." - else - pointed(M) - m_type = 1 - - if ("raise", "raises") - if (!src.restrained()) - message = "[src] raises a hand." - m_type = 1 - - if("shake", "shakes") - message = "[src] shakes \his head." - m_type = 1 - - if ("shrug", "shrugs") - message = "[src] shrugs." - m_type = 1 - - if ("signal", "signals") - if (!src.restrained()) - var/t1 = round(text2num(param)) - if (isnum(t1)) - if (t1 <= 5 && (!src.r_hand || !src.l_hand)) - message = "[src] raises [t1] finger\s." - else if (t1 <= 10 && (!src.r_hand && !src.l_hand)) - message = "[src] raises [t1] finger\s." - m_type = 1 - - if ("smile", "smiles") - message = "[src] smiles." - m_type = 1 - - if ("shiver", "shivers") - message = "[src] shivers." - m_type = 2 - if(miming) - m_type = 1 - - if ("pale", "pales") - message = "[src] goes pale for a second." - m_type = 1 - - if ("tremble", "trembles") - message = "[src] trembles." - m_type = 1 - - if ("sneeze", "sneezes") - if (miming) - message = "[src] sneezes." - m_type = 1 - else - if (!muzzled) - message = "[src] sneezes." - m_type = 2 - else - message = "[src] makes a strange noise." - m_type = 2 - - if ("sniff", "sniffs") - message = "[src] sniffs." - m_type = 2 - if(miming) - m_type = 1 - - if ("snore", "snores") - if (miming) - message = "[src] sleeps soundly." - m_type = 1 - else - if (!muzzled) - message = "[src] snores." - m_type = 2 - else - message = "[src] makes a noise." - m_type = 2 - - if ("whimper", "whimpers") - if (miming) - message = "[src] appears hurt." - m_type = 1 - else - if (!muzzled) - message = "[src] whimpers." - m_type = 2 - else - message = "[src] makes a weak noise." - m_type = 2 - - if ("wink", "winks") - message = "[src] winks." - m_type = 1 - - if ("yawn", "yawns") - if (!muzzled) - message = "[src] yawns." - m_type = 2 - if(miming) - m_type = 1 - - if ("collapse", "collapses") - Paralyse(2) - message = "[src] collapses!" - m_type = 2 - if(miming) - m_type = 1 - - if("hug", "hugs") - m_type = 1 - if (!src.restrained()) - var/M = null - if (param) - for (var/mob/A in view(1, null)) - if (param == A.name) - M = A - break - if (M == src) - M = null - - if (M) - message = "[src] hugs [M]." - else - message = "[src] hugs \himself." - - if ("handshake") - m_type = 1 - if (!src.restrained() && !src.r_hand) - var/mob/M = null - if (param) - for (var/mob/A in view(1, null)) - if (param == A.name) - M = A - break - if (M == src) - M = null - - if (M) - if (M.canmove && !M.r_hand && !M.restrained()) - message = "[src] shakes hands with [M]." - else - message = "[src] holds out \his hand to [M]." - - if("dap", "daps") - m_type = 1 - if (!src.restrained()) - var/M = null - if (param) - for (var/mob/A in view(1, null)) - if (param == A.name) - M = A - break - if (M) - message = "[src] gives daps to [M]." - else - message = "[src] sadly can't find anybody to give daps to, and daps \himself. Shameful." - - if("slap", "slaps") - m_type = 1 - if (!src.restrained()) - var/M = null - if (param) - for (var/mob/A in view(1, null)) - if (param == A.name) - M = A - break - if (M) - message = "\red [src] slaps [M] across the face. Ouch!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - else - message = "\red [src] slaps \himself!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - src.adjustFireLoss(4) - - if ("scream", "screams") - if (miming) - message = "[src] acts out a scream!" - m_type = 1 - else - if (!muzzled) - message = "[src] [species.scream_verb]!" - m_type = 2 - if(gender == FEMALE) - playsound(src.loc, "[species.female_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) - else - playsound(src.loc, "[species.male_scream_sound]", 80, 1, 0, pitch = get_age_pitch()) //default to male screams if no gender is present. - - else - message = "[src] makes a very loud noise." - m_type = 2 - - - if ("snap", "snaps") - if(prob(95)) - m_type = 2 - var/mob/living/carbon/human/H = src - var/obj/item/organ/external/L = H.get_organ("l_hand") - var/obj/item/organ/external/R = H.get_organ("r_hand") - var/left_hand_good = 0 - var/right_hand_good = 0 - if(L && (!(L.status & ORGAN_DESTROYED)) && (!(L.status & ORGAN_SPLINTED)) && (!(L.status & ORGAN_BROKEN))) - left_hand_good = 1 - if(R && (!(R.status & ORGAN_DESTROYED)) && (!(R.status & ORGAN_SPLINTED)) && (!(R.status & ORGAN_BROKEN))) - right_hand_good = 1 - - if (!left_hand_good && !right_hand_good) - to_chat(usr, "You need at least one hand in good working order to snap your fingers.") - return - - message = "[src] snaps \his fingers." - playsound(src.loc, 'sound/effects/fingersnap.ogg', 50, 1, -3) - else - message = "[src] snaps \his fingers right off!" - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - - - // Needed for M_TOXIC_FART - if("fart", "farts") - if(reagents.has_reagent("simethicone")) - return -// playsound(src.loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun - if(locate(/obj/item/weapon/storage/bible) in get_turf(src)) - to_chat(viewers(src), "[src] farts on the Bible!") - to_chat(viewers(src), "A mysterious force smites [src]!") - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, src) - s.start() - src.gib() - else if(TOXIC_FARTS in mutations) - message = "[src] unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart." - else - message = "[src] [pick("passes wind","farts")]." - m_type = 2 - - var/turf/location = get_turf(src) - var/aoe_range=2 // Default - - // Process toxic farts first. - if(TOXIC_FARTS in mutations) - for(var/mob/M in range(location,aoe_range)) - if (M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT)) - continue - // Now, we don't have this: - //new /obj/effects/fart_cloud(T,L) - if (M == src) - continue - M.reagents.add_reagent("jenkem", 1) - - if ("help") - var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-(none)/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s),cry, cries, custom, dap(s)(none)/mob," \ - + " deathgasp(s), drool(s), eyebrow,fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-(none)/mob, grin(s), groan(s), grumble(s), handshake-mob, hug(s)-(none)/mob," \ - + " glare(s)-(none)/mob, grin(s), johnny, laugh(s), look(s)-(none)/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-(none)/mob, scream(s), shake(s)," \ - + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \ - + " wag(s), wave(s), whimper(s), wink(s), yawn(s)" - if(species.name == "Machine") - emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob" - else if(species.name == "Slime People") - emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob" - to_chat(src, emotelist) - - else - to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.") - - - - - - if(message) //Humans are special fucking snowflakes and have 735 lines of emotes, they get to handle their own emotes, not call the parent - log_emote("[name]/[key] : [message]") - - //Hearing gasp and such every five seconds is not good emotes were not global for a reason. - // Maybe some people are okay with that. - - for(var/mob/M in dead_mob_list) - if(!M.client || istype(M, /mob/new_player)) - continue //skip monkeys, leavers and new players - if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) - M.show_message(message) - - switch(m_type) - if(1) - visible_message(message) - if(2) - audible_message(message) - -/mob/living/carbon/human/verb/pose() - set name = "Set Pose" - set desc = "Sets a description which will be shown when someone examines you." - set category = "IC" - - pose = sanitize(copytext(input(usr, "This is [src]. \He is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN)) - -/mob/living/carbon/human/verb/set_flavor() - set name = "Set Flavour Text" - set desc = "Sets an extended description of your character's features." - set category = "IC" - - update_flavor_text() diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 539d88f11cb..d8307e5056c 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -41,7 +41,7 @@ t_is = "are" else if(icon) - msg += "\icon[icon] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated + msg += "[bicon(icon(icon, dir=SOUTH))] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated switch(gender) if(MALE) t_He = "He" @@ -80,83 +80,83 @@ tie_msg += " with [english_accessory_list(U)]" if(w_uniform.blood_DNA) - msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [w_uniform.blood_color != "#030303" ? "blood-stained":"oil-stained"] [w_uniform.name][tie_msg]!\n" + msg += "[t_He] [t_is] wearing [bicon(w_uniform)] [w_uniform.gender==PLURAL?"some":"a"] [w_uniform.blood_color != "#030303" ? "blood-stained":"oil-stained"] [w_uniform.name][tie_msg]!\n" else - msg += "[t_He] [t_is] wearing \icon[w_uniform] \a [w_uniform][tie_msg].\n" + msg += "[t_He] [t_is] wearing [bicon(w_uniform)] \a [w_uniform][tie_msg].\n" //head if(head && !(head.flags & ABSTRACT)) if(head.blood_DNA) - msg += "[t_He] [t_is] wearing \icon[head] [head.gender==PLURAL?"some":"a"] [head.blood_color != "#030303" ? "blood-stained":"oil-stained"] [head.name] on [t_his] head!\n" + msg += "[t_He] [t_is] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] [head.blood_color != "#030303" ? "blood-stained":"oil-stained"] [head.name] on [t_his] head!\n" else - msg += "[t_He] [t_is] wearing \icon[head] \a [head] on [t_his] head.\n" + msg += "[t_He] [t_is] wearing [bicon(head)] \a [head] on [t_his] head.\n" //suit/armour if(wear_suit && !(wear_suit.flags & ABSTRACT)) if(wear_suit.blood_DNA) - msg += "[t_He] [t_is] wearing \icon[wear_suit] [wear_suit.gender==PLURAL?"some":"a"] [wear_suit.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_suit.name]!\n" + msg += "[t_He] [t_is] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] [wear_suit.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_suit.name]!\n" else - msg += "[t_He] [t_is] wearing \icon[wear_suit] \a [wear_suit].\n" + msg += "[t_He] [t_is] wearing [bicon(wear_suit)] \a [wear_suit].\n" //suit/armour storage if(s_store && !skipsuitstorage) if(s_store.blood_DNA) - msg += "[t_He] [t_is] carrying \icon[s_store] [s_store.gender==PLURAL?"some":"a"] [s_store.blood_color != "#030303" ? "blood-stained":"oil-stained"] [s_store.name] on [t_his] [wear_suit.name]!\n" + msg += "[t_He] [t_is] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] [s_store.blood_color != "#030303" ? "blood-stained":"oil-stained"] [s_store.name] on [t_his] [wear_suit.name]!\n" else - msg += "[t_He] [t_is] carrying \icon[s_store] \a [s_store] on [t_his] [wear_suit.name].\n" + msg += "[t_He] [t_is] carrying [bicon(s_store)] \a [s_store] on [t_his] [wear_suit.name].\n" //back if(back && !(back.flags & ABSTRACT)) if(back.blood_DNA) - msg += "[t_He] [t_has] \icon[back] [back.gender==PLURAL?"some":"a"] [back.blood_color != "#030303" ? "blood-stained":"oil-stained"] [back] on [t_his] back.\n" + msg += "[t_He] [t_has] [bicon(back)] [back.gender==PLURAL?"some":"a"] [back.blood_color != "#030303" ? "blood-stained":"oil-stained"] [back] on [t_his] back.\n" else - msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n" + msg += "[t_He] [t_has] [bicon(back)] \a [back] on [t_his] back.\n" //left hand if(l_hand && !(l_hand.flags & ABSTRACT)) if(l_hand.blood_DNA) - msg += "[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] [l_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [l_hand.name] in [t_his] left hand!\n" + msg += "[t_He] [t_is] holding [bicon(l_hand)] [l_hand.gender==PLURAL?"some":"a"] [l_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [l_hand.name] in [t_his] left hand!\n" else - msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n" + msg += "[t_He] [t_is] holding [bicon(l_hand)] \a [l_hand] in [t_his] left hand.\n" //right hand if(r_hand && !(r_hand.flags & ABSTRACT)) if(r_hand.blood_DNA) - msg += "[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] [r_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [r_hand.name] in [t_his] right hand!\n" + msg += "[t_He] [t_is] holding [bicon(r_hand)] [r_hand.gender==PLURAL?"some":"a"] [r_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [r_hand.name] in [t_his] right hand!\n" else - msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n" + msg += "[t_He] [t_is] holding [bicon(r_hand)] \a [r_hand] in [t_his] right hand.\n" //gloves if(gloves && !skipgloves && !(gloves.flags & ABSTRACT)) if(gloves.blood_DNA) - msg += "[t_He] [t_has] \icon[gloves] [gloves.gender==PLURAL?"some":"a"] [gloves.blood_color != "#030303" ? "blood-stained":"oil-stained"] [gloves.name] on [t_his] hands!\n" + msg += "[t_He] [t_has] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] [gloves.blood_color != "#030303" ? "blood-stained":"oil-stained"] [gloves.name] on [t_his] hands!\n" else - msg += "[t_He] [t_has] \icon[gloves] \a [gloves] on [t_his] hands.\n" + msg += "[t_He] [t_has] [bicon(gloves)] \a [gloves] on [t_his] hands.\n" else if(blood_DNA) msg += "[t_He] [t_has] [hand_blood_color != "#030303" ? "blood-stained":"oil-stained"] hands!\n" //handcuffed? if(handcuffed) if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable/zipties)) - msg += "[t_He] [t_is] \icon[handcuffed] restrained with zipties!\n" + msg += "[t_He] [t_is] [bicon(handcuffed)] restrained with zipties!\n" else if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable)) - msg += "[t_He] [t_is] \icon[handcuffed] restrained with cable!\n" + msg += "[t_He] [t_is] [bicon(handcuffed)] restrained with cable!\n" else - msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n" + msg += "[t_He] [t_is] [bicon(handcuffed)] handcuffed!\n" //belt if(belt) if(belt.blood_DNA) - msg += "[t_He] [t_has] \icon[belt] [belt.gender==PLURAL?"some":"a"] [belt.blood_color != "#030303" ? "blood-stained":"oil-stained"] [belt.name] about [t_his] waist!\n" + msg += "[t_He] [t_has] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] [belt.blood_color != "#030303" ? "blood-stained":"oil-stained"] [belt.name] about [t_his] waist!\n" else - msg += "[t_He] [t_has] \icon[belt] \a [belt] about [t_his] waist.\n" + msg += "[t_He] [t_has] [bicon(belt)] \a [belt] about [t_his] waist.\n" //shoes if(shoes && !skipshoes && !(shoes.flags & ABSTRACT)) if(shoes.blood_DNA) - msg += "[t_He] [t_is] wearing \icon[shoes] [shoes.gender==PLURAL?"some":"a"] [shoes.blood_color != "#030303" ? "blood-stained":"oil-stained"] [shoes.name] on [t_his] feet!\n" + msg += "[t_He] [t_is] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] [shoes.blood_color != "#030303" ? "blood-stained":"oil-stained"] [shoes.name] on [t_his] feet!\n" else - msg += "[t_He] [t_is] wearing \icon[shoes] \a [shoes] on [t_his] feet.\n" + msg += "[t_He] [t_is] wearing [bicon(shoes)] \a [shoes] on [t_his] feet.\n" else if (blood_DNA) msg += "[t_He] [t_has] [feet_blood_color != "#030303" ? "blood-stained":"oil-stained"] feet!\n" @@ -164,24 +164,24 @@ //mask if(wear_mask && !skipmask && !(wear_mask.flags & ABSTRACT)) if(wear_mask.blood_DNA) - msg += "[t_He] [t_has] \icon[wear_mask] [wear_mask.gender==PLURAL?"some":"a"] [wear_mask.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_mask.name] on [t_his] face!\n" + msg += "[t_He] [t_has] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] [wear_mask.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_mask.name] on [t_his] face!\n" else - msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n" + msg += "[t_He] [t_has] [bicon(wear_mask)] \a [wear_mask] on [t_his] face.\n" //eyes if(glasses && !skipeyes && !(glasses.flags & ABSTRACT)) if(glasses.blood_DNA) - msg += "[t_He] [t_has] \icon[glasses] [glasses.gender==PLURAL?"some":"a"] [glasses.blood_color != "#030303" ? "blood-stained":"oil-stained"] [glasses] covering [t_his] eyes!\n" + msg += "[t_He] [t_has] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] [glasses.blood_color != "#030303" ? "blood-stained":"oil-stained"] [glasses] covering [t_his] eyes!\n" else - msg += "[t_He] [t_has] \icon[glasses] \a [glasses] covering [t_his] eyes.\n" + msg += "[t_He] [t_has] [bicon(glasses)] \a [glasses] covering [t_his] eyes.\n" //left ear if(l_ear && !skipears) - msg += "[t_He] [t_has] \icon[l_ear] \a [l_ear] on [t_his] left ear.\n" + msg += "[t_He] [t_has] [bicon(l_ear)] \a [l_ear] on [t_his] left ear.\n" //right ear if(r_ear && !skipears) - msg += "[t_He] [t_has] \icon[r_ear] \a [r_ear] on [t_his] right ear.\n" + msg += "[t_He] [t_has] [bicon(r_ear)] \a [r_ear] on [t_his] right ear.\n" //ID if(wear_id) @@ -193,9 +193,9 @@ var/obj/item/weapon/card/id/idcard = wear_id id = idcard.registered_name if(id && (id != real_name) && (get_dist(src, user) <= 1) && prob(10)) - msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...\n" + msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id] yet something doesn't seem right...\n" else*/ - msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n" + msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id].\n" //Jitters switch(jitteriness) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 7775830b4a0..ed02823215f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1537,14 +1537,17 @@ if(species.base_color && default_colour) //Apply colour. - r_skin = hex2num(copytext(species.base_color,2,4)) - g_skin = hex2num(copytext(species.base_color,4,6)) - b_skin = hex2num(copytext(species.base_color,6,8)) + r_skin = hex2num(copytext(species.base_color, 2, 4)) + g_skin = hex2num(copytext(species.base_color, 4, 6)) + b_skin = hex2num(copytext(species.base_color, 6, 8)) else r_skin = 0 g_skin = 0 b_skin = 0 + if(!(species.bodyflags & HAS_SKIN_TONE)) + s_tone = 0 + species.create_organs(src) //Handle default hair/head accessories for created mobs. @@ -1556,6 +1559,32 @@ if(species.default_headacc) H.ha_style = species.default_headacc + if(species.default_hair_colour) + //Apply colour. + H.r_hair = hex2num(copytext(species.default_hair_colour, 2, 4)) + H.g_hair = hex2num(copytext(species.default_hair_colour, 4, 6)) + H.b_hair = hex2num(copytext(species.default_hair_colour, 6, 8)) + else + H.r_hair = 0 + H.g_hair = 0 + H.b_hair = 0 + if(species.default_fhair_colour) + H.r_facial = hex2num(copytext(species.default_fhair_colour, 2, 4)) + H.g_facial = hex2num(copytext(species.default_fhair_colour, 4, 6)) + H.b_facial = hex2num(copytext(species.default_fhair_colour, 6, 8)) + else + H.r_facial = 0 + H.g_facial = 0 + H.b_facial = 0 + if(species.default_headacc_colour) + H.r_headacc = hex2num(copytext(species.default_headacc_colour, 2, 4)) + H.g_headacc = hex2num(copytext(species.default_headacc_colour, 4, 6)) + H.b_headacc = hex2num(copytext(species.default_headacc_colour, 6, 8)) + else + H.r_headacc = 0 + H.g_headacc = 0 + H.b_headacc = 0 + if(!dna) dna = new /datum/dna(null) dna.species = species.name @@ -1982,4 +2011,21 @@ . |= A.GetAccess() /mob/living/carbon/human/is_mechanical() - return ..() || (species.flags & ALL_RPARTS) != 0 \ No newline at end of file + return ..() || (species.flags & ALL_RPARTS) != 0 + +/mob/living/carbon/human/can_use_guns(var/obj/item/weapon/gun/G) + . = ..() + + if(G.trigger_guard == TRIGGER_GUARD_NORMAL) + if(HULK in mutations) + to_chat(src, "Your meaty finger is much too large for the trigger guard!") + return 0 + if(species.flags & NOGUNS) + to_chat(src, "Your fingers don't fit in the trigger guard!") + return 0 + + if(martial_art && martial_art.name == "The Sleeping Carp") //great dishonor to famiry + to_chat(src, "Use of ranged weaponry would bring dishonor to the clan.") + return 0 + + return . diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 835f741be3d..3a935e5e449 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -27,7 +27,7 @@ emp_act P.current = curloc P.yo = new_y - curloc.y P.xo = new_x - curloc.x - P.Angle = ""//round(Get_Angle(P,P.original)) + P.Angle = null return -1 // complete projectile permutation @@ -46,7 +46,10 @@ emp_act if((P.embed && prob(20 + max(P.damage - armor, -10)))) var/obj/item/weapon/shard/shrapnel/SP = new() (SP.name) = "[P.name] shrapnel" - (SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]." + if(P.ammo_casing && P.ammo_casing.caliber) + (SP.desc) = "[SP.desc] It looks like it is a [P.ammo_casing.caliber] caliber round." + else + (SP.desc) = "[SP.desc] The round's caliber is unidentifiable." (SP.loc) = organ organ.embed(SP) diff --git a/code/modules/mob/living/carbon/human/interactive/functions.dm b/code/modules/mob/living/carbon/human/interactive/functions.dm index 0a220accc98..c1b22e721f2 100644 --- a/code/modules/mob/living/carbon/human/interactive/functions.dm +++ b/code/modules/mob/living/carbon/human/interactive/functions.dm @@ -433,7 +433,7 @@ return 1 /mob/living/carbon/human/interactive/proc/souschef(obj) - if(shouldModulePass() || enforceHome() || prob(SNPC_FUZZY_CHANCE_LOW)) + if(shouldModulePass() || enforceHome() || prob(SNPC_FUZZY_CHANCE_HIGH) || prob(SNPC_FUZZY_CHANCE_HIGH)) return if(doing & SNPC_SPECIAL) @@ -693,7 +693,7 @@ best = R if(istype(R, /obj/item/weapon/gun)) var/obj/item/weapon/gun/G = R - if(G.can_fire()) + if(G.can_shoot()) best = R break // gun with ammo? screw the rest if(best && best != main_hand) @@ -727,22 +727,23 @@ if(main_hand.force != 0) if(istype(main_hand,/obj/item/weapon/gun)) var/obj/item/weapon/gun/G = main_hand - if(G.special_check(src)) + if(G.can_trigger_gun(src)) var/shouldFire = 1 if(istype(main_hand, /obj/item/weapon/gun/energy)) var/obj/item/weapon/gun/energy/P = main_hand var/stunning = 0 - if(ispath(text2path(P.projectile_type), /obj/item/projectile/energy/electrode)) - stunning = 1 + for(var/A in P.ammo_type) + if(ispath(A,/obj/item/ammo_casing/energy/electrode)) + stunning = 1 var/mob/stunCheck = TARGET if(stunning && stunCheck.stunned) shouldFire = 0 if(shouldFire) - if(!G.process_chambered()) - G.click_empty(src) + if(!G.can_shoot()) + G.shoot_with_empty_chamber(src) npcDrop(G, 1) else - G.Fire(TARGET, src) + G.process_fire(TARGET, src) else if(get_dist(src,TARGET) > 6) if(!walk2derpless(TARGET)) @@ -775,6 +776,12 @@ else return "[word]ed" +/mob/living/carbon/human/interactive/proc/ing_verb(word) + if(copytext(word, length(word)) == "e") + return "[copytext(word, 1, length(word))]ing" + else + return "[word]ing" + /mob/living/carbon/human/interactive/proc/paperwork_sentence() var/verbs_use = pick_list(speak_file, "verbs_use") var/verbs_touch = pick_list(speak_file, "verbs_touch") @@ -871,4 +878,4 @@ else A.stamp(S) custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as they stamp \the [A] with \a [S]!") - return \ No newline at end of file + return diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm index 14402788451..9e4b77f055f 100644 --- a/code/modules/mob/living/carbon/human/interactive/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm @@ -258,12 +258,15 @@ RPID.access = myjob.get_access() equip_to_slot_or_del(MYID, slot_wear_id) - MYPDA = new(src) + if(wear_pda) + MYPDA = wear_pda + else + MYPDA = new(src) + equip_to_slot_or_del(MYPDA, slot_wear_pda) MYPDA.owner = real_name MYPDA.ownjob = alt_title MYPDA.ownrank = job MYPDA.name = "PDA-[real_name] ([alt_title])" - equip_to_slot_or_del(MYPDA, slot_belt) zone_sel.selecting = "chest" //arms if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4)) @@ -836,7 +839,7 @@ return 0 if(myPath.len <= 0) - myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, SNPC_MAX_RANGE_FIND + 1, 250,1, id=Path_ID) + myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, SNPC_MAX_RANGE_FIND + 1, 250,1, id=Path_ID, simulated_only = 0) if(myPath) if(myPath.len > 0) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index f9d9ae27442..bde2c900636 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -218,6 +218,7 @@ W.loc = src W.equipped(src, slot) W.layer = 20 + W.plane = HUD_PLANE switch(slot) if(slot_back) @@ -260,6 +261,7 @@ O.loc = src r_ear = O O.layer = 20 + O.plane = HUD_PLANE update_inv_ears(redraw_mob) if(slot_r_ear) r_ear = W @@ -268,6 +270,7 @@ O.loc = src l_ear = O O.layer = 20 + O.plane = HUD_PLANE update_inv_ears(redraw_mob) if(slot_glasses) glasses = W diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 14585c8d972..c7c20904da4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -39,6 +39,7 @@ handle_pain() handle_heartbeat() handle_heartattack() + handle_drunk() species.handle_life(src) if(!client) @@ -730,6 +731,80 @@ return //TODO: DEFERRED +/mob/living/carbon/human/handle_drunk() + var/slur_start = 30 //12u ethanol, 30u whiskey FOR HUMANS + var/confused_start = 40 + var/brawl_start = 30 + var/blur_start = 75 + var/vomit_start = 60 + var/pass_out = 90 + var/spark_start = 50 //40u synthanol + var/collapse_start = 75 + var/braindamage_start = 120 + var/alcohol_strength = drunk + var/sober_str=!(SOBER in mutations)?1:2 + + if(drunk) + alcohol_strength/=sober_str + + var/obj/item/organ/internal/liver/L + if(!isSynthetic()) + L = get_int_organ(/obj/item/organ/internal/liver) + if(L) + alcohol_strength *= L.alcohol_intensity + else + alcohol_strength *= 5 + + if(alcohol_strength >= slur_start) //slurring + if (!slurring) slurring = 1 + slurring = drunk + if(alcohol_strength >= brawl_start) //the drunken martial art + if(!istype(martial_art, /datum/martial_art/drunk_brawling)) + var/datum/martial_art/drunk_brawling/F = new + F.teach(src,1) + if(alcohol_strength < brawl_start) //removing the art + if(istype(martial_art, /datum/martial_art/drunk_brawling)) + martial_art.remove(src) + if(alcohol_strength >= confused_start && prob(33)) //confused walking + if (!confused) confused = 1 + confused = max(confused+(3/sober_str),0) + if(alcohol_strength >= blur_start) //blurry eyes + eye_blurry = max(eye_blurry, 10/sober_str) + drowsyness = max(drowsyness, 0) + if(!isSynthetic()) //stuff only for non-synthetics + if(alcohol_strength >= vomit_start) //vomiting + if(prob(8)) + fakevomit() + if(alcohol_strength >= pass_out) + Paralyse(5 / sober_str) + drowsyness = max(drowsyness, 30/sober_str) + if (L) + L.take_damage(0.1, 1) + adjustToxLoss(0.1) + else //stuff only for synthetics + if(alcohol_strength >= spark_start && prob(25)) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + if(alcohol_strength >= collapse_start && prob(10)) + emote("collapse") + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + if(alcohol_strength >= braindamage_start && prob(10)) + adjustBrainLoss(1) + + if(!has_booze()) + AdjustDrunk(-0.5) + return + +/mob/living/carbon/human/proc/has_booze() //checks if the human has ethanol or its subtypes inside + for(var/A in reagents.reagent_list) + var/datum/reagent/R = A + if(istype(R, /datum/reagent/ethanol)) + return 1 + return 0 + /mob/living/carbon/human/handle_regular_status_updates() if(status_flags & GODMODE) return 0 @@ -825,13 +900,9 @@ else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs ear_damage = max(ear_damage - 0.05, 0) - if(flying) - spawn() - animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING) - spawn(10) - if(flying) - animate(src, pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING) + animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING) + animate(pixel_y = pixel_y - 5, time = 10, loop = 1, easing = SINE_EASING) // If you're dirty, your gloves will become dirty, too. if(gloves && germ_level > gloves.germ_level && prob(10)) diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 7162933349d..840b500de01 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -148,6 +148,9 @@ if(prob(braindam)) message = uppertext(message) verb = "yells loudly" + + if(locate(/obj/item/organ/internal/cyberimp/brain/clown_voice) in internal_organs) + message = "[message]" returns[1] = message returns[2] = verb diff --git a/code/modules/mob/living/carbon/human/species/plasmaman.dm b/code/modules/mob/living/carbon/human/species/plasmaman.dm index 26ee19b0788..003e1969d33 100644 --- a/code/modules/mob/living/carbon/human/species/plasmaman.dm +++ b/code/modules/mob/living/carbon/human/species/plasmaman.dm @@ -66,7 +66,7 @@ if("Warden","Security Officer","Security Pod Pilot") suit=/obj/item/clothing/suit/space/eva/plasmaman/security/ helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/ - H.equip_or_collect(new /obj/item/weapon/gun/energy/advtaser(H), slot_in_backpack) + H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_in_backpack) if("Magistrate") suit=/obj/item/clothing/suit/space/eva/plasmaman/magistrate helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/magistrate diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index f6a1e5e2088..ad0d5b18c61 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -121,8 +121,14 @@ //Default hair/headacc style vars. var/default_hair = "Bald" //Default hair style for newly created humans unless otherwise set. + var/default_hair_colour var/default_fhair = "Shaved" //Default facial hair style for newly created humans unless otherwise set. + var/default_fhair_colour var/default_headacc = "None" //Default head accessory style for newly created humans unless otherwise set. + var/default_headacc_colour + + //Defining lists of icon skin tones for species that have them. + var/list/icon_skin_tones = list() // Determines the organs that the species spawns with and var/list/has_organ = list( // which required-organ checks are conducted. @@ -372,6 +378,9 @@ grant_abilities(C) 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 diff --git a/code/modules/mob/living/carbon/human/species/station.dm b/code/modules/mob/living/carbon/human/species/station.dm index 65d100dc420..7f5daa824d5 100644 --- a/code/modules/mob/living/carbon/human/species/station.dm +++ b/code/modules/mob/living/carbon/human/species/station.dm @@ -59,6 +59,16 @@ default_hair = "Unathi Horns" butt_sprite = "unathi" + 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, + ) + 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) @@ -116,6 +126,16 @@ default_headacc = "Tajaran Ears" 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, + ) + 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) @@ -161,6 +181,16 @@ base_color = "#B43214" butt_sprite = "vulp" + 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, + ) + 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) @@ -221,8 +251,8 @@ /datum/species/vox name = "Vox" name_plural = "Vox" - icobase = 'icons/mob/human_races/r_vox.dmi' - deform = 'icons/mob/human_races/r_def_vox.dmi' + 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" @@ -267,12 +297,13 @@ flags = NO_SCAN | IS_WHITELISTED clothing_flags = HAS_SOCKS dietflags = DIET_OMNI - bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED + bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED 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 @@ -280,10 +311,19 @@ male_scream_sound = 'sound/voice/shriek1.ogg' female_scream_sound = 'sound/voice/shriek1.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, - "liver" = /obj/item/organ/internal/liver, + "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, @@ -327,12 +367,44 @@ if (H.internals) H.internals.icon_state = "internal1" -/* /datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H) - H.verbs += /mob/living/carbon/human/proc/leap - ..() */ + updatespeciescolor(H) + H.update_icons() + //H.verbs += /mob/living/carbon/human/proc/leap + ..() + +/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H) //Handling species-specific skin-tones for the Vox race. + if(H.species.name == "Vox") //Making sure we don't break Armalis. + switch(H.s_tone) + if(6) //Azure Vox. + icobase = 'icons/mob/human_races/vox/r_voxazu.dmi' + deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi' + tail = "voxtail_azu" + if(5) //Emerald Vox. + icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi' + deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi' + tail = "voxtail_emrl" + if(4) //Grey Vox. + icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi' + tail = "voxtail_gry" + if(3) //Brown Vox. + icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi' + deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi' + tail = "voxtail_brn" + if(2) //Dark Green Vox. + icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi' + deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi' + tail = "voxtail_dgrn" + else //Default Green Vox. + icobase = 'icons/mob/human_races/vox/r_vox.dmi' + deform = 'icons/mob/human_races/vox/r_def_vox.dmi' + tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone. + + H.update_dna() /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 ..() @@ -412,6 +484,16 @@ reagent_tag = PROCESS_ORG 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, + ) + allowed_consumed_mobs = list(/mob/living/simple_animal/diona) suicide_messages = list( @@ -616,6 +698,16 @@ 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, + "appendix" = /obj/item/organ/internal/appendix, + "eyes" = /obj/item/organ/internal/eyes, + ) + brute_mod = 1.25 //greys are fragile default_genes = list(REMOTE_TALK) @@ -838,4 +930,4 @@ spawn(100) if(H) H.update_hair() - H.update_fhair() \ No newline at end of file + H.update_fhair() diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 45bc15b1d51..628ea630555 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -212,6 +212,9 @@ var/global/list/damage_icon_parts = list() var/hulk = (HULK in src.mutations) var/skeleton = (SKELETON in src.mutations) + if(species && species.bodyflags & HAS_ICON_SKIN_TONE) + 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. @@ -636,6 +639,7 @@ var/global/list/damage_icon_parts = list() thing.loc = loc // thing.dropped(src) // thing.layer = initial(thing.layer) + thing.plane = initial(thing.plane) if(update_icons) update_icons() /mob/living/carbon/human/update_inv_wear_id(var/update_icons=1) @@ -1108,12 +1112,13 @@ 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) - accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) + if(species.bodyflags & HAS_SKIN_COLOR) + accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/temp1 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(src.species.name in body_accessory.allowed_species) + if(species.name in body_accessory.allowed_species) var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") temp1 = temp else @@ -1129,7 +1134,7 @@ 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/temp2 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(src.species.name in body_accessory.allowed_species) + if(species.name in body_accessory.allowed_species) var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") temp2 = temp else @@ -1145,9 +1150,10 @@ var/global/list/damage_icon_parts = list() else if(species.tail && species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") - tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + if(species.bodyflags & HAS_SKIN_COLOR) + tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/temp1 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") temp1.Insert(new/icon(tail_s,dir=SOUTH),dir=SOUTH) @@ -1177,13 +1183,14 @@ 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()) - accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) + if(species.bodyflags & HAS_SKIN_COLOR) + accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/temp1 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") if(body_accessory.allowed_species) - if(src.species.name in body_accessory.allowed_species) + if(species.name in body_accessory.allowed_species) var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") temp1 = temp else @@ -1199,7 +1206,7 @@ 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/temp2 = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s") - if(src.species.name in body_accessory.allowed_species) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank + if(species.name in body_accessory.allowed_species) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank var/icon/temp = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "[species.tail]_delay") temp2 = temp else // Else if the user's species is not in the list of allowed species for the currently selected body accessory, this point must have been reached by admin-override. Use vulpkanin timings as default. @@ -1214,9 +1221,10 @@ var/global/list/damage_icon_parts = list() else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") - tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + if(species.bodyflags & HAS_SKIN_COLOR) + tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - if(src.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... + if(species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/temp1 = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_delay") temp1.Insert(tailw_s,dir=SOUTH) diff --git a/code/modules/mob/living/carbon/slime/emote.dm b/code/modules/mob/living/carbon/slime/emote.dm deleted file mode 100644 index 8c290dc6094..00000000000 --- a/code/modules/mob/living/carbon/slime/emote.dm +++ /dev/null @@ -1,75 +0,0 @@ -/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null) - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - //param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - act = lowertext(act) - switch(act) //Alphabetical please - if ("me") - if(silent) - return - if (src.client) - if (client.prefs.muted & MUTE_IC) - to_chat(src, "\red You cannot send IC messages (muted).") - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - if (stat) - return - if(!(message)) - return - return custom_emote(m_type, message) - if("bounce") - message = "The [src.name] bounces in place." - m_type = 1 - - if ("custom") - return custom_emote(m_type, message) - - if("jiggle") - message = "The [src.name] jiggles!" - m_type = 1 - - if("light") - message = "The [src.name] lights up for a bit, then stops." - m_type = 1 - - if("moan") - message = "The [src.name] moans." - m_type = 2 - - if("shiver") - message = "The [src.name] shivers." - m_type = 2 - - if("sway") - message = "The [src.name] sways around dizzily." - m_type = 1 - - if("twitch") - message = "The [src.name] twitches." - m_type = 1 - - if("vibrate") - message = "The [src.name] vibrates!" - m_type = 1 - - if ("help") //This is an exception - to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate") - - else - to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.") - if ((message && src.stat == 0)) - if (m_type & 1) - for(var/mob/O in viewers(src, null)) - O.show_message(message, m_type) - //Foreach goto(703) - else - for(var/mob/O in hearers(src, null)) - O.show_message(message, m_type) - //Foreach goto(746) - return \ No newline at end of file diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index e647dfcd442..82f865621da 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -59,6 +59,8 @@ if(get_nations_mode()) process_nations() + ..() + /mob/living/proc/handle_breathing() return @@ -112,6 +114,7 @@ handle_paralysed() handle_sleeping() handle_slowed() + handle_drunk() /mob/living/proc/handle_stunned() @@ -166,6 +169,11 @@ slowed = max(slowed-1, 0) return slowed +/mob/living/proc/handle_drunk() + if(drunk) + AdjustDrunk(-1) + return drunk + /mob/living/proc/handle_disabilities() //Eyes if(sdisabilities & BLIND || stat) //blindness from disability or unconsciousness doesn't get better on its own @@ -321,4 +329,4 @@ if(client) var/client/C = client for(var/mob/living/carbon/human/H in view(src, world.view)) - C.images += H.hud_list[NATIONS_HUD] \ No newline at end of file + C.images += H.hud_list[NATIONS_HUD] diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f28e884f92f..bd360456009 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -588,9 +588,6 @@ visible_message("[src] resists!") return 1 -/mob/living/proc/resist_borer() - return - /mob/living/proc/resist_buckle() spawn(0) resist_muzzle() @@ -855,3 +852,9 @@ tally += 10 return tally + +/mob/living/proc/can_use_guns(var/obj/item/weapon/gun/G) + if (G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser()) + to_chat(src, "You don't have the dexterity to do this!") + return 0 + return 1 diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 4d994436489..cc50408148e 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -47,10 +47,6 @@ proj_sharp = 0 proj_edge = 0 - if(istype(P, /obj/item/projectile/beam/lightning)) //Stupid snowflake lightning gun. - if(P.damage >= 200) - src.dust() - if(!P.nodamage) apply_damage(P.damage, P.damage_type, def_zone, armor) return P.on_hit(src, armor, def_zone) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index c6d0d8e3ee0..85eea65bbab 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -296,34 +296,6 @@ proc/get_radio_key_from_channel(var/channel) /mob/living/proc/GetVoice() return name -/mob/living/emote(var/act, var/type, var/message) //emote code is terrible, this is so that anything that isn't - if(stat) return 0 //already snowflaked to shit can call the parent and handle emoting sanely - - if(..(act, type, message)) - return 1 - - if(act && type && message) //parent call - log_emote("[name]/[key] : [message]") - - for(var/mob/M in dead_mob_list) - if(!M.client || istype(M, /mob/new_player)) - continue //skip monkeys, leavers and new players //who the hell knows why new players are in the dead mob list - - if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null))) - M.show_message(message) - - switch(type) - if(1) //Visible - visible_message(message) - return 1 - if(2) //Audible - audible_message(message) - return 1 - - else //everything else failed, emote is probably invalid - if(act == "help") return //except help, because help is handled individually - to_chat(src, "\blue Unusable emote '[act]'. Say *help for a list.") - /mob/living/whisper(message as text) message = trim_strip_html_properly(message) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3346882a488..812d2e8df58 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -814,7 +814,8 @@ var/list/ai_verbs_default = list( var/icon_list[] = list( "default", "floating face", - "xeno queen" + "xeno queen", + "eldritch" ) input = input("Please select a hologram:") as null|anything in icon_list if(input) @@ -826,6 +827,8 @@ var/list/ai_verbs_default = list( holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo2")) if("xeno queen") holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo3")) + if("eldritch") + holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4")) return /mob/living/silicon/ai/proc/corereturn() diff --git a/code/modules/mob/living/silicon/emote.dm b/code/modules/mob/living/silicon/emote.dm deleted file mode 100644 index c70979c5947..00000000000 --- a/code/modules/mob/living/silicon/emote.dm +++ /dev/null @@ -1,121 +0,0 @@ -/mob/living/silicon/emote(var/act, var/m_type=1, var/message = null) - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - //Emote Cooldown System (it's so simple!) - // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] - var/on_CD = 0 - act = lowertext(act) - switch(act) - //Cooldown-inducing emotes - if("scream", "screams") - on_CD = handle_emote_CD(50) //longer cooldown - if("ping","pings","buzz","buzzs","buzzes","beep","beeps","yes","no") - //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - //Everything else, including typos of the above emotes - else - on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown - - if(on_CD == 1) // Check if we need to suppress the emote attempt. - return // Suppress emote, you're still cooling off. - //--FalseIncarnate - - switch(act) - if("ping","pings") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] pings at [param]." - else - message = "[src] pings." - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - m_type = 2 - - if("buzz","buzzs","buzzes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] buzzes at [param]." - else - message = "[src] buzzes." - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - m_type = 2 - - if("beep","beeps") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] beeps at [param]." - else - message = "[src] beeps." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - m_type = 2 - - if("yes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits an affirmative blip at [param]." - else - message = "[src] emits an affirmative blip." - playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) - m_type = 2 - - if("no") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits a negative blip at [param]." - else - message = "[src] emits a negative blip." - playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) - m_type = 2 - - if("scream", "screams") - message = "[src] screams!" - playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0) - m_type = 2 - - if("help") - to_chat(src, "yes, no, beep, ping, buzz") - - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/emote.dm b/code/modules/mob/living/silicon/pai/emote.dm deleted file mode 100644 index a418c0972d5..00000000000 --- a/code/modules/mob/living/silicon/pai/emote.dm +++ /dev/null @@ -1,2 +0,0 @@ -/mob/living/silicon/pai/emote(var/act, var/m_type=1, var/message = null) - ..(act, m_type, message) diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index b4fd1ff3fa7..dbed9015220 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -670,7 +670,7 @@ if(href_list["send"]) P.sradio.send_signal("ACTIVATE") for(var/mob/O in hearers(1, P.loc)) - O.show_message(text("\icon[] *beep* *beep*", P), 3, "*beep* *beep*", 2) + O.show_message("[bicon(P)] *beep* *beep*", 3, "*beep* *beep*", 2) return 1 else if(href_list["freq"]) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm deleted file mode 100644 index 36c61910e6d..00000000000 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ /dev/null @@ -1,163 +0,0 @@ -/mob/living/silicon/robot/emote(var/act, var/m_type=1, var/message = null) - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - //Emote Cooldown System (it's so simple!) - // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] - var/on_CD = 0 - act = lowertext(act) - switch(act) - //Cooldown-inducing emotes - if("law","flip","flips","halt") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - //Everything else, including typos of the above emotes - else - on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown - - if(on_CD == 1) // Check if we need to suppress the emote attempt. - return // Suppress emote, you're still cooling off. - //--FalseIncarnate - - switch(act) - - if ("salute","salutes") - if (!src.buckled) - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] salutes to [param]." - else - message = "[src] salutes." - m_type = 1 - if ("bow","bows") - if (!src.buckled) - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] bows to [param]." - else - message = "[src] bows." - m_type = 1 - - if ("clap","claps") - if (!src.restrained()) - message = "[src] claps." - m_type = 2 - if ("flap","flaps") - if (!src.restrained()) - message = "[src] flaps its wings." - m_type = 2 - - if ("aflap","aflaps") - if (!src.restrained()) - message = "[src] flaps its wings ANGRILY!" - m_type = 2 - - if ("twitch") - message = "[src] twitches violently." - m_type = 1 - - if ("twitch_s","twitches") - message = "[src] twitches." - m_type = 1 - - if ("nod","nods") - message = "[src] nods." - m_type = 1 - - if ("deathgasp") - message = "[src] shudders violently for a moment, then becomes motionless, its eyes slowly darkening." - m_type = 1 - - if ("glare","glares") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] glares at [param]." - else - message = "[src] glares." - - if ("stare","stares") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if (!M) - param = null - - if (param) - message = "[src] stares at [param]." - else - message = "[src] stares." - - if ("look","looks") - var/M = null - if (param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - - if (!M) - param = null - - if (param) - message = "[src] looks at [param]." - else - message = "[src] looks." - m_type = 1 - - - if("law") - if (istype(module,/obj/item/weapon/robot_module/security)) - message = "[src] shows its legal authorization barcode." - - playsound(src.loc, 'sound/voice/biamthelaw.ogg', 50, 0) - m_type = 2 - else - to_chat(src, "You are not THE LAW, pal.") - - if("halt") - if (istype(module,/obj/item/weapon/robot_module/security)) - message = "[src]'s speakers skreech, \"Halt! Security!\"." - - playsound(src.loc, 'sound/voice/halt.ogg', 50, 0) - m_type = 2 - else - to_chat(src, "You are not security.") - - if ("flip","flips") - m_type = 1 - message = "[src] does a flip!" - src.SpinAnimation(5,1) - - if ("help") - to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt") - - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 8d2af648463..546bdd2eb6c 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -4,7 +4,7 @@ var/msg = "" var/obj/act_module = get_active_hand() if(act_module) - msg += "It is holding \icon[act_module] \a [act_module].\n" + msg += "It is holding [bicon(act_module)] \a [act_module].\n" msg += "" if (src.getBruteLoss()) if (src.getBruteLoss() < 75) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 97b15ecda1a..7e824eeb279 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -56,6 +56,7 @@ O.mouse_opacity = initial(O.mouse_opacity) module_state_1 = O O.layer = 20 + O.plane = HUD_PLANE O.screen_loc = inv1.screen_loc contents += O if(istype(module_state_1,/obj/item/borg/sight)) @@ -64,6 +65,7 @@ O.mouse_opacity = initial(O.mouse_opacity) module_state_2 = O O.layer = 20 + O.plane = HUD_PLANE O.screen_loc = inv2.screen_loc contents += O if(istype(module_state_2,/obj/item/borg/sight)) @@ -72,6 +74,7 @@ O.mouse_opacity = initial(O.mouse_opacity) module_state_3 = O O.layer = 20 + O.plane = HUD_PLANE O.screen_loc = inv3.screen_loc contents += O if(istype(module_state_3,/obj/item/borg/sight)) @@ -246,4 +249,4 @@ if(!module) hands.icon_state = "nomod" else - hands.icon_state = lowertext(module.module_type) \ No newline at end of file + hands.icon_state = lowertext(module.module_type) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 12030e52773..7fb1ba0a8aa 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -337,7 +337,7 @@ src.modules += new /obj/item/device/flash/cyborg(src) src.modules += new /obj/item/borg/sight/thermal(src) src.modules += new /obj/item/weapon/melee/energy/sword/cyborg(src) - src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/pulse/cyborg(src) src.modules += new /obj/item/weapon/tank/jetpack/carbondioxide(src) src.modules += new /obj/item/weapon/crowbar(src) src.emag = null diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index a546e164901..94ae02a56ce 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -128,13 +128,6 @@ return return 1 -/mob/living/silicon/ai/emote(var/act, var/type, var/message) - var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src) //Is the AI using a holopad? - src.holopad_emote(message) - else //Emote normally, then. - ..() - #undef IS_AI #undef IS_ROBOT #undef IS_PAI diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 700b47da3f3..ca5ca8fa33f 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -507,7 +507,7 @@ Pass a positive integer as an argument to override a bot's default speed. turn_on() //Saves the AI the hassle of having to activate a bot manually. access_card = all_access //Give the bot all-access while under the AI's command. if(message) - to_chat(calling_ai, "\icon[src] [name] called to [end_area.name]. [path.len-1] meters to destination.") + to_chat(calling_ai, "[bicon(src)] [name] called to [end_area.name]. [path.len-1] meters to destination.") pathset = 1 mode = BOT_RESPONDING tries = 0 @@ -522,7 +522,7 @@ Pass a positive integer as an argument to override a bot's default speed. var/success = bot_move(ai_waypoint, 3) if(!success) if(calling_ai) - to_chat(calling_ai, "\icon[src] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]") + to_chat(calling_ai, "[bicon(src)] [get_turf(src) == ai_waypoint ? "[src] successfully arrived to waypoint." : "[src] failed to reach waypoint."]") calling_ai = null bot_reset() diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 2c2ca652d10..27bfe821502 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -158,7 +158,7 @@ return newname = "redtag ED-209 assembly" if("") - if(!istype(W, /obj/item/weapon/gun/energy/advtaser)) + if(!istype(W, /obj/item/weapon/gun/energy/gun/advtaser)) return newname = "taser ED-209 assembly" else diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 12dd032ba49..34888dd3488 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -365,7 +365,7 @@ Auto Patrol[]"}, new /obj/item/device/assembly/prox_sensor(Tsec) if(!lasercolor) - var/obj/item/weapon/gun/energy/advtaser/G = new /obj/item/weapon/gun/energy/advtaser(Tsec) + var/obj/item/weapon/gun/energy/gun/advtaser/G = new /obj/item/weapon/gun/energy/gun/advtaser(Tsec) G.power_supply.charge = 0 G.update_icon() else if(lasercolor == "b") @@ -403,7 +403,7 @@ Auto Patrol[]"}, shoot_sound = 'sound/weapons/laser.ogg' if(emagged == 2) if(lasercolor) - projectile = /obj/item/projectile/lasertag + projectile = /obj/item/projectile/beam/lasertag else projectile = /obj/item/projectile/beam else @@ -411,9 +411,9 @@ Auto Patrol[]"}, shoot_sound = 'sound/weapons/Taser.ogg' projectile = /obj/item/projectile/energy/electrode else if(lasercolor == "b") - projectile = /obj/item/projectile/lasertag/blue + projectile = /obj/item/projectile/beam/lasertag/bluetag else if(lasercolor == "r") - projectile = /obj/item/projectile/lasertag/red + projectile = /obj/item/projectile/beam/lasertag/redtag /mob/living/simple_animal/bot/ed209/proc/shootAt(mob/target) if(lastfired && world.time - lastfired < shot_delay) @@ -438,8 +438,7 @@ Auto Patrol[]"}, A.current = U A.yo = U.y - T.y A.xo = U.x - T.x - spawn(0) - A.process() + A.fire() /mob/living/simple_animal/bot/ed209/attack_alien(mob/living/carbon/alien/user) ..() @@ -491,10 +490,10 @@ Auto Patrol[]"}, if(!disabled) var/lasertag_check = 0 if((lasercolor == "b")) - if(istype(Proj, /obj/item/projectile/lasertag/red)) + if(istype(Proj, /obj/item/projectile/beam/lasertag/redtag)) lasertag_check++ else if((lasercolor == "r")) - if(istype(Proj, /obj/item/projectile/lasertag/blue)) + if(istype(Proj, /obj/item/projectile/beam/lasertag/bluetag)) lasertag_check++ if(lasertag_check) icon_state = "[lasercolor]ed2090" diff --git a/code/modules/mob/living/simple_animal/bot/emote.dm b/code/modules/mob/living/simple_animal/bot/emote.dm deleted file mode 100644 index 0c8b591f069..00000000000 --- a/code/modules/mob/living/simple_animal/bot/emote.dm +++ /dev/null @@ -1,120 +0,0 @@ -/mob/living/simple_animal/bot/emote(var/act, var/m_type=1, var/message = null) - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - //Emote Cooldown System (it's so simple!) - // proc/handle_emote_CD() located in [code\modules\mob\emote.dm] - var/on_CD = 0 - act = lowertext(act) - switch(act) - //Cooldown-inducing emotes - if("scream", "screams") - on_CD = handle_emote_CD(50) //longer cooldown - if("ping","buzz","beep","yes","no") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. - on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - //Everything else, including typos of the above emotes - else - on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown - - if(on_CD == 1) // Check if we need to suppress the emote attempt. - return // Suppress emote, you're still cooling off. - //--FalseIncarnate - - switch(act) - if("ping") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] pings at [param]." - else - message = "[src] pings." - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - m_type = 2 - - if("buzz") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] buzzes at [param]." - else - message = "[src] buzzes." - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - m_type = 2 - - if("beep") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] beeps at [param]." - else - message = "[src] beeps." - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - m_type = 2 - - if("yes") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits an affirmative blip at [param]." - else - message = "[src] emits an affirmative blip." - playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) - m_type = 2 - - if("no") - var/M = null - if(param) - for (var/mob/A in view(null, null)) - if (param == A.name) - M = A - break - if(!M) - param = null - - if (param) - message = "[src] emits a negative blip at [param]." - else - message = "[src] emits a negative blip." - playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0) - m_type = 2 - - if("scream", "screams") - message = "[src] screams!" - playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0) - m_type = 2 - - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index e2bad0bcd3b..45af81affb5 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -639,7 +639,7 @@ if(pathset) //The AI called us here, so notify it of our arrival. loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing". if(calling_ai) - to_chat(calling_ai, "\icon[src] [src] wirelessly plays a chiming sound!") + to_chat(calling_ai, "[bicon(src)] [src] wirelessly plays a chiming sound!") playsound(calling_ai, 'sound/machines/chime.ogg',40, 0) calling_ai = null radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us. diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 4f8b7753caf..e8ba27fa07d 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -632,8 +632,7 @@ A.current = T A.yo = U.y - T.y A.xo = U.x - T.x - spawn( 0 ) - A.process() + A.fire() return /mob/living/simple_animal/pet/corgi/Ian/borgi/Life() @@ -657,4 +656,4 @@ s.start() respawnable_list += src qdel(src) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/simple_animal/friendly/diona.dm b/code/modules/mob/living/simple_animal/friendly/diona.dm index f62176ee926..125061f9275 100644 --- a/code/modules/mob/living/simple_animal/friendly/diona.dm +++ b/code/modules/mob/living/simple_animal/friendly/diona.dm @@ -243,31 +243,9 @@ /mob/living/simple_animal/diona/put_in_hands(obj/item/W) W.loc = get_turf(src) W.layer = initial(W.layer) + W.plane = initial(W.plane) W.dropped() /mob/living/simple_animal/diona/put_in_active_hand(obj/item/W) to_chat(src, "You don't have any hands!") return - -/mob/living/simple_animal/diona/emote(var/act, var/m_type=1, var/message = null) - if(stat) - return - - var/on_CD = 0 - act = lowertext(act) - switch(act) - if("chirp") - on_CD = handle_emote_CD() - else - on_CD = 0 - - if(on_CD == 1) - return - - switch(act) //IMPORTANT: Emotes MUST NOT CONFLICT anywhere along the chain. - if("chirp") - message = "\The [src] chirps!" - m_type = 2 //audible - playsound(src, 'sound/misc/nymphchirp.ogg', 40, 1, 1) - - ..(act, m_type, message) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index b269256f7a0..dee6489b9cb 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -112,7 +112,7 @@ if( ishuman(AM) ) if(!stat) var/mob/M = AM - to_chat(M, "\blue \icon[src] Squeek!") + to_chat(M, "\blue [bicon(src)] Squeek!") M << 'sound/effects/mousesqueek.ogg' ..() diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index 590dfa47b5e..9e2e33d7c4e 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -285,4 +285,4 @@ /mob/living/simple_animal/spiderbot/examine(mob/user) ..(user) if(src.held_item) - to_chat(user, "It is carrying \a [src.held_item] \icon[src.held_item].") + to_chat(user, "It is carrying \a [src.held_item] [bicon(src.held_item)].") diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 418c30199d0..faf0cc0f9a3 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -260,20 +260,23 @@ if(target == start) return - var/obj/item/projectile/A = new projectiletype(src.loc) - playsound(user, projectilesound, 100, 1) - if(!A) return - - A.current = target - A.firer = src - A.yo = target:y - start:y - A.xo = target:x - start:x - if(AIStatus == AI_OFF)//Don't want mindless mobs to have their movement screwed up firing in space - newtonian_move(get_dir(target, user)) - A.original = target - spawn( 0 ) - A.process() - return + if(casingtype) + var/obj/item/ammo_casing/casing = new casingtype + playsound(src, projectilesound, 100, 1) + casing.fire(target, src, zone_override = ran_zone()) + casing.loc = loc + else + var/obj/item/projectile/A = new projectiletype(loc) + playsound(user, projectilesound, 100, 1) + A.current = target + A.firer = src + A.yo = target:y - start:y + A.xo = target:x - start:x + if(AIStatus == AI_OFF)//Don't want mindless mobs to have their movement screwed up firing in space + newtonian_move(get_dir(target, user)) + A.original = target + A.fire() + return A /mob/living/simple_animal/hostile/proc/DestroySurroundings() if(environment_smash) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index e5ee97a70ef..f14d1bf649a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -1,7 +1,3 @@ -// -// Abstract Class -// - /mob/living/simple_animal/hostile/mimic name = "crate" desc = "A rectangular steel crate." @@ -39,7 +35,7 @@ /mob/living/simple_animal/hostile/mimic/death() ..() - visible_message("\red [src] stops moving!") + visible_message("[src]
stops moving!") ghostize() qdel(src) @@ -52,16 +48,9 @@ adjustBruteLoss(50) ..(severity) -// -// Crate Mimic -// - - // Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. /mob/living/simple_animal/hostile/mimic/crate - attacktext = "bites" - stop_automated_movement = 1 wander = 0 var/attempt_open = 0 @@ -112,7 +101,6 @@ icon_state = initial(icon_state) /mob/living/simple_animal/hostile/mimic/crate/death() - var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) @@ -127,22 +115,18 @@ L.Weaken(2) L.visible_message("\the [src] knocks down \the [L]!") -// -// Copy Mimic -// - -var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window, /obj/item/projectile/magic/animate) +var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window) /mob/living/simple_animal/hostile/mimic/copy - health = 100 maxHealth = 100 var/mob/living/creator = null // the creator var/destroy_objects = 0 var/knockdown_people = 0 + var/image/googly_eyes = null gold_core_spawnable = CHEM_MOB_SPAWN_INVALID -/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator, var/destroy_original = 0) +/mob/living/simple_animal/hostile/mimic/copy/New(loc, obj/copy, mob/living/creator, destroy_original = 0) ..(loc) CopyObject(copy, creator, destroy_original) @@ -158,7 +142,6 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca ..() /mob/living/simple_animal/hostile/mimic/copy/ListTargets() - // Return a list of targets that isn't the creator . = ..() return . - creator @@ -173,10 +156,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca return 1 return 0 -/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/creator, var/destroy_original = 0) - +/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/mob/living/user, var/destroy_original = 0) if(destroy_original || CheckObject(O)) - O.loc = src name = O.name desc = O.desc @@ -184,7 +165,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca icon_state = O.icon_state icon_living = icon_state overlays = O.overlays - + googly_eyes = image('icons/mob/mob.dmi',"googly_eyes") + overlays += googly_eyes if(istype(O, /obj/structure) || istype(O, /obj/machinery)) health = (anchored * 50) + 50 destroy_objects = 1 @@ -202,10 +184,9 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca move_to_delay = 2 * I.w_class + 1 if(istype(O, /obj/item/device)) is_electronic = 1 - maxHealth = health - if(creator) - src.creator = creator + if(user) + creator = user faction += "\ref[creator]" // very unique if(destroy_original) qdel(O) @@ -226,9 +207,9 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca C.visible_message("\The [src] knocks down \the [C]!", \ "\The [src] knocks you down!") -// -// Machine Mimics (Made by Malf AI) -// +/mob/living/simple_animal/hostile/mimic/copy/Aggro() + ..() + googly_eyes.dir = get_dir(src,target) /mob/living/simple_animal/hostile/mimic/copy/machine speak = list("HUMANS ARE IMPERFECT!", "YOU SHALL BE ASSIMILATED!", "YOU ARE HARMING YOURSELF", "You have been deemed hazardous. Will you comply?", \ @@ -242,4 +223,77 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca var/mob/living/silicon/robot/R = the_target if(R.connected_ai == creator) // Only attack robots that aren't synced to our creator AI. return 0 - return ..() \ No newline at end of file + return ..() + +/mob/living/simple_animal/hostile/mimic/copy/ranged + var/obj/item/weapon/gun/TrueGun = null + var/obj/item/weapon/gun/magic/Zapstick + var/obj/item/weapon/gun/projectile/Pewgun + var/obj/item/weapon/gun/energy/Zapgun + +/mob/living/simple_animal/hostile/mimic/copy/ranged/CopyObject(obj/O, mob/living/creator, destroy_original = 0) + if(..()) + emote_see = list("aims menacingly") + environment_smash = 0 //needed? seems weird for them to do so + ranged = 1 + retreat_distance = 1 //just enough to shoot + minimum_distance = 6 + var/obj/item/weapon/gun/G = O + melee_damage_upper = G.force + melee_damage_lower = G.force - max(0, (G.force / 2)) + move_to_delay = 2 * G.w_class + 1 + projectilesound = G.fire_sound + TrueGun = G + if(istype(G, /obj/item/weapon/gun/magic)) + Zapstick = G + var/obj/item/ammo_casing/magic/M = Zapstick.ammo_type + projectiletype = initial(M.projectile_type) + if(istype(G, /obj/item/weapon/gun/projectile)) + Pewgun = G + var/obj/item/ammo_box/magazine/M = Pewgun.mag_type + casingtype = initial(M.ammo_type) + if(istype(G, /obj/item/weapon/gun/energy)) + Zapgun = G + var/selectfiresetting = Zapgun.select + var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting] + projectiletype = initial(E.projectile_type) + +/mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target) + if(Zapgun) + if(Zapgun.power_supply) + var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select] + if(Zapgun.power_supply.charge >= shot.e_cost) + Zapgun.power_supply.use(shot.e_cost) + Zapgun.update_icon() + ..() + else if(Zapstick) + if(Zapstick.charges) + Zapstick.charges-- + Zapstick.update_icon() + ..() + else if(Pewgun) + if(Pewgun.chambered) + if(Pewgun.chambered.BB) + qdel(Pewgun.chambered.BB) + Pewgun.chambered.BB = null //because qdel takes too long, ensures icon update + Pewgun.chambered.update_icon() + ..() + else + visible_message("The [src] clears a jam!") + Pewgun.chambered.loc = loc //rip revolver immersions, blame shotgun snowflake procs + Pewgun.chambered = null + if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) + Pewgun.chambered = Pewgun.magazine.get_round(0) + Pewgun.chambered.loc = Pewgun + Pewgun.update_icon() + else if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) //only true for pumpguns i think + Pewgun.chambered = Pewgun.magazine.get_round(0) + Pewgun.chambered.loc = Pewgun + visible_message("The [src] cocks itself!") + else + ranged = 0 //BANZAIIII + retreat_distance = 0 + minimum_distance = 1 + return + icon_state = TrueGun.icon_state + icon_living = TrueGun.icon_state diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index 71d088a425c..9a64b5c4d3e 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -77,7 +77,7 @@ //repair a bit of damage if(prob(1)) - src.visible_message("\red \icon[src] [src] shudders and shakes as some of it's damaged systems come back online.") + src.visible_message("\red [bicon(src)] [src] shudders and shakes as some of it's damaged systems come back online.") var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() @@ -92,10 +92,10 @@ //sometimes our targetting sensors malfunction, and we attack anyone nearby if(prob(disabled ? 0 : 1)) if(hostile_drone) - src.visible_message("\blue \icon[src] [src] retracts several targetting vanes, and dulls it's running lights.") + src.visible_message("\blue [bicon(src)] [src] retracts several targetting vanes, and dulls it's running lights.") hostile_drone = 0 else - src.visible_message("\red \icon[src] [src] suddenly lights up, and additional targetting vanes slide into place.") + src.visible_message("\red [bicon(src)] [src] suddenly lights up, and additional targetting vanes slide into place.") hostile_drone = 1 if(health / maxHealth > 0.9) @@ -116,17 +116,17 @@ exploding = 0 if(!disabled) if(prob(50)) - src.visible_message("\blue \icon[src] [src] suddenly shuts down!") + src.visible_message("\blue [bicon(src)] [src] suddenly shuts down!") else - src.visible_message("\blue \icon[src] [src] suddenly lies still and quiet.") + src.visible_message("\blue [bicon(src)] [src] suddenly lies still and quiet.") disabled = rand(150, 600) walk(src,0) if(exploding && prob(20)) if(prob(50)) - src.visible_message("\red \icon[src] [src] begins to spark and shake violenty!") + src.visible_message("\red [bicon(src)] [src] begins to spark and shake violenty!") else - src.visible_message("\red \icon[src] [src] sparks and shakes like it's about to explode!") + src.visible_message("\red [bicon(src)] [src] sparks and shakes like it's about to explode!") var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread s.set_up(3, 1, src) s.start() @@ -151,7 +151,7 @@ /mob/living/simple_animal/hostile/retaliate/malf_drone/death() ..() - visible_message("\blue \icon[src] [src] suddenly breaks apart.") + visible_message("\blue [bicon(src)] [src] suddenly breaks apart.") qdel(src) /mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy() //Seriously, what the actual hell. diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index 148eeeef9a7..0126dd5c704 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -32,8 +32,6 @@ ranged = 1 retreat_distance = 5 minimum_distance = 5 - projectiletype = /obj/item/projectile/bullet - projectilesound = 'sound/weapons/Gunshot.ogg' casingtype = /obj/item/ammo_casing/a357 loot = list(/obj/effect/landmark/mobcorpse/russian/ranged, /obj/item/weapon/gun/projectile/revolver/mateba) @@ -45,4 +43,4 @@ /mob/living/simple_animal/hostile/russian/death() ..() qdel(src) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 5546547046d..32bdf5fc772 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -88,8 +88,6 @@ icon_state = "syndicateranged" icon_living = "syndicateranged" casingtype = /obj/item/ammo_casing/c45 - projectilesound = 'sound/weapons/Gunshot_smg.ogg' - projectiletype = /obj/item/projectile/bullet/midbullet2 loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier, /obj/item/weapon/gun/projectile/automatic/c20r) /mob/living/simple_animal/hostile/syndicate/ranged/space @@ -130,4 +128,4 @@ ..() visible_message("\red [src] is smashed into pieces!") qdel(src) - return \ No newline at end of file + return diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm index 3b34ddaf143..1a46e46e4e4 100644 --- a/code/modules/mob/living/simple_animal/vox.dm +++ b/code/modules/mob/living/simple_animal/vox.dm @@ -65,15 +65,26 @@ if ((O.client && !( O.blinded ))) to_chat(O, "\red [src] launches a razor-sharp quill at [target]!") - var/obj/item/weapon/arrow/quill/Q = new(loc) + var/obj/item/weapon/quill/Q = new(loc) Q.fingerprintslast = src.ckey Q.throw_at(target,10,30) + quills-- spawn(100) to_chat(src, "\red You feel a fresh quill slide into place.") quills++ +/obj/item/weapon/quill + name = "vox quill" + desc = "A wickedly barbed quill from some bizarre animal." + icon_state = "quill" + item_state = "quill" + throwforce = 5 + w_class = 3.0 + sharp = 1 + edge = 0 + /mob/living/simple_animal/vox/armalis/verb/message_mob() set category = "Alien" set name = "Commune with creature" @@ -155,4 +166,4 @@ desc = "A series of metallic lenses and chains." icon = 'icons/obj/clothing/hats.dmi' icon_state = "amp" - item_state = "amp" \ No newline at end of file + item_state = "amp" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 872350d6d9e..f41cef386aa 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -12,6 +12,8 @@ for(var/mob/dead/observer/M in following_mobs) M.following = null following_mobs = null + if(buckled) + buckled.unbuckle_mob() return ..() /mob/New() @@ -21,6 +23,7 @@ else living_mob_list += src prepare_huds() + emoteHandler = new /datum/emoteHandler(src) ..() /atom/proc/prepare_huds() @@ -1094,6 +1097,9 @@ var/list/slot_equipment_priority = list( \ /mob/proc/Dizzy(amount) dizziness = max(dizziness, amount, 0) +/mob/proc/AdjustDrunk(amount) + drunk = max(drunk + amount, 0) + /mob/proc/Stun(amount) SetStunned(max(stunned, amount)) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index bc09aa11a1b..13d5d7c976e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -63,6 +63,7 @@ var/ajourn = 0 var/druggy = 0 //Carbon var/confused = 0 //Carbon + var/drunk = 0 var/antitoxs = null var/plasma = null var/sleeping = 0 //Carbon @@ -233,3 +234,5 @@ var/datum/vision_override/vision_type = null //Vision override datum. var/list/permanent_huds = list() + + var/datum/emoteHandler/emoteHandler \ No newline at end of file diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 98437a53ffd..e9ee311db76 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -23,6 +23,7 @@ var/dancing //determines if assailant and affecting keep looking at each other. Basically a wrestling position layer = 21 + plane = HUD_PLANE item_state = "nothing" icon = 'icons/mob/screen_gen.dmi' w_class = 5.0 @@ -93,13 +94,15 @@ hud.screen_loc = ui_rhand else hud.screen_loc = ui_lhand - + assailant.client.screen += hud /obj/item/weapon/grab/process() - if(!confirm()) return //If the confirm fails, the grab is about to be deleted. That means it shouldn't continue processing. + if(!confirm()) + return //If the confirm fails, the grab is about to be deleted. That means it shouldn't continue processing. if(assailant.client) - if(!hud) return //this somehow can runtime under the right circumstances + if(!hud) + return //this somehow can runtime under the right circumstances assailant.client.screen -= hud assailant.client.screen += hud @@ -136,12 +139,8 @@ hud.icon_state = "!reinforce" if(state >= GRAB_AGGRESSIVE) - var/h = affecting.hand - affecting.hand = 0 - affecting.drop_item() - affecting.hand = 1 - affecting.drop_item() - affecting.hand = h + affecting.drop_r_hand() + affecting.drop_l_hand() //var/announce = 0 @@ -440,7 +439,13 @@ affecting.pixel_y = 0 //used to be an animate, not quick enough for del'ing affecting.layer = initial(affecting.layer) affecting.grabbed_by -= src + affecting = null + if(assailant) + if(assailant.client) + assailant.client.screen -= hud + assailant = null qdel(hud) + hud = null return ..() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index f9023a97dd3..8d57d115ebe 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -304,26 +304,38 @@ ///Called by client/Move() ///Checks to see if you are being grabbed and if so attemps to break it /client/proc/Process_Grab() - if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len))) + if(mob.grabbed_by.len) var/list/grabbing = list() + if(istype(mob.l_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = mob.l_hand grabbing += G.affecting + if(istype(mob.r_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = mob.r_hand grabbing += G.affecting - for(var/obj/item/weapon/grab/G in mob.grabbed_by) - if((G.state == 1)&&(!grabbing.Find(G.assailant))) qdel(G) - if(G.state == 2) - move_delay = world.time + 10 - if(!prob(25)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s grip!") - qdel(G) - if(G.state == 3) - move_delay = world.time + 10 - if(!prob(5)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s headlock!") - qdel(G) + + for(var/X in mob.grabbed_by) + var/obj/item/weapon/grab/G = X + switch(G.state) + + if(GRAB_PASSIVE) + if(!grabbing.Find(G.assailant)) //moving always breaks a passive grab unless we are also grabbing our grabber. + qdel(G) + + if(GRAB_AGGRESSIVE) + move_delay = world.time + 10 + if(!prob(25)) + return 1 + mob.visible_message("[mob] has broken free of [G.assailant]'s grip!") + qdel(G) + + if(GRAB_NECK) + move_delay = world.time + 10 + if(!prob(5)) + return 1 + mob.visible_message("[mob] has broken free of [G.assailant]'s headlock!") + qdel(G) return 0 diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index bbb0211ce67..f7cff248519 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -34,10 +34,6 @@ verbs += /client/proc/readmin spawn(40) if(client) - if(client.prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates. -CP - winset(client, "rpane.changelog", "background-color=#f4aa94;font-style=bold") - client.prefs.SetChangelog(client,changelog_hash) - to_chat(src, "Changelog has changed since your last visit.") client.playtitlemusic() if(config.player_overflow_cap && config.overflow_server_url) //Overflow rerouting, if set, forces players to be moved to a different server once a player cap is reached. Less rough than a pure kick. diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 60285b092fc..f752b1f4409 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -24,7 +24,8 @@ /mob/new_player/proc/new_player_panel_proc() - var/output = "

Setup Character

" + var/real_name = client.prefs.real_name + var/output = "

Setup Character
[real_name]

" if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) if(!ready) output += "

Declare Ready

" @@ -452,7 +453,7 @@ var/datum/language/chosen_language if(client.prefs.language) chosen_language = all_languages[client.prefs.language] - if((chosen_language == null && chosen_language != "None") || (chosen_language && chosen_language.flags & RESTRICTED)) + if((chosen_language == null && client.prefs.language != "None") || (chosen_language && chosen_language.flags & RESTRICTED)) log_debug("[src] had language [client.prefs.language], though they weren't supposed to. Setting to None.") client.prefs.language = "None" diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 63567b0399c..0632e0af5e8 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -199,13 +199,25 @@ var/icon/icobase var/datum/species/current_species = all_species[species] + //Icon-based species colour. + var/coloured_tail if(current_species) - icobase = current_species.icobase + 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.s_tone = s_tone + H.species.updatespeciescolor(H) + + icobase = H.species.icobase + if(H.species.bodyflags & HAS_TAIL) + coloured_tail = H.species.tail + else + icobase = current_species.icobase else icobase = 'icons/mob/human_races/r_human.dmi' var/fat="" - if(disabilities&DISABILITY_FLAG_FAT && current_species.flags & CAN_BE_FAT) + if(disabilities & DISABILITY_FLAG_FAT && current_species.flags & CAN_BE_FAT) fat="_fat" preview_icon = new /icon(icobase, "torso_[g][fat]") preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY) @@ -222,7 +234,10 @@ tail_icon_state = accessory.icon_state else tail_icon = "icons/effects/species.dmi" - tail_icon_state = "[current_species.tail]_s" + if(coloured_tail) + tail_icon_state = "[coloured_tail]_s" + else + tail_icon_state = "[current_species.tail]_s" var/icon/temp = new /icon("icon" = tail_icon, "icon_state" = tail_icon_state) preview_icon.Blend(temp, ICON_OVERLAY) diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 93797b5bb17..3ade5970d03 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -1017,7 +1017,6 @@ icon_state = "vox_beard" species_allowed = list("Vox") - //Vulpkanin vulp_blaze diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index e3e8d4620be..493fade2ea1 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -27,17 +27,23 @@ set_typing_indicator(0) usr.say(message) + /mob/verb/me_verb(message as text) set name = "Me" - set category = "IC" + set category = "Emotes" + set desc = "(action) Enter a custom emote." - message = strip_html_properly(message) + if(!message) + return + + message = trim_strip_html_properly(message) + + if(message == "") + return + + if(emoteHandler) + return emoteHandler.runEmote("me", message) - set_typing_indicator(0) - if(use_me) - custom_emote(usr.emote_type, message) - else - usr.emote(message) /mob/proc/say_dead(var/message) if(!(client && client.holder)) @@ -98,8 +104,11 @@ /mob/proc/emote(var/act, var/type, var/message) - if(act == "me") - return custom_emote(type, message) + + act = lowertext(act) + return emoteHandler.runEmote(act, message, type) + + /mob/proc/get_ear() // returns an atom representing a location on the map from which this @@ -144,3 +153,6 @@ return L return null + +/mob/proc/custom_emote(var/m_type=0, var/message = null) + return emoteHandler.runEmote("me", message, m_type) \ No newline at end of file diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 583b68b3dc6..55027a90852 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -38,9 +38,27 @@ return 1 if(href_list["skin_tone"]) if(can_change_skin_tone()) - var/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) + var/new_s_tone = null + if(owner.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) + 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; i <= owner.species.icon_skin_tones.len; i++) + 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 += ", " + 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) + + if(new_s_tone) return owner.change_skin_tone(new_s_tone) if(href_list["skin_color"]) if(can_change_skin_color()) @@ -209,7 +227,7 @@ 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) + return owner && (flags & APPEARANCE_SKIN) && ((owner.species.bodyflags & HAS_SKIN_TONE) || (owner.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) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 23a0f3eec7e..c0e7a2bc468 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -260,9 +260,10 @@ var/list/alldepartments = list() visible_message("[src] beeps, \"Message transmitted successfully.\"") -/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#006100") - var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (SM) ([admin_jump_link(sender, "holder")]) (CA) (BSA) (REPLY): Receiving '[sent.name]' via secure connection... view message" - +/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#9A04D1") + var/msg = "\blue [faxname]: [key_name(sender, 1)] (PP) (VV) (CA) ([admin_jump_link(sender, "holder")]) | REPLY: (RADIO) (FAX) (SM) | REJECT: (TEMPLATE) (BSA) (EVILFAX) : Receiving '[sent.name]' via secure connection... view message" for(var/client/C in admins) if(R_EVENT & C.holder.rights) to_chat(C, msg) + if(C.prefs.sound & SOUND_ADMINHELP) + C << 'sound/effects/adminhelp.ogg' diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index bf847a06c0a..11f864451b7 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -398,12 +398,14 @@ h_user.unEquip(src) B.loc = h_user B.layer = 20 + B.plane = HUD_PLANE h_user.l_store = B h_user.update_inv_pockets() else if (h_user.r_store == src) h_user.unEquip(src) B.loc = h_user B.layer = 20 + B.plane = HUD_PLANE h_user.r_store = B h_user.update_inv_pockets() else if (h_user.head == src) @@ -618,3 +620,85 @@ /obj/item/weapon/paper/crumpled/bloody icon_state = "scrap_bloodied" + +/obj/item/weapon/paper/evilfax + name = "Centcomm Reply" + info = "" + var/mytarget = null + var/myeffect = null + var/used = 0 + var/countdown = 60 + var/activate_on_timeout = 0 + +/obj/item/weapon/paper/evilfax/show_content(var/mob/user, var/forceshow = 0, var/forcestars = 0, var/infolinks = 0, var/view = 1) + if(user == mytarget) + if(istype(user, /mob/living/carbon)) + var/mob/living/carbon/C = user + evilpaper_specialaction(C) + ..() + else + // This should never happen, but just in case someone is adminbussing + evilpaper_selfdestruct() + else + if(mytarget) + to_chat(user,"This page appears to be covered in some sort of bizzare code. The only bit you recognize is the name of [mytarget]. Perhaps [mytarget] can make sense of it?") + else + evilpaper_selfdestruct() + + +/obj/item/weapon/paper/evilfax/New() + ..() + processing_objects.Add(src) + + +/obj/item/weapon/paper/evilfax/Destroy() + processing_objects.Remove(src) + if(mytarget && !used) + var/mob/living/carbon/target = mytarget + target.ForceContractDisease(new /datum/disease/transformation/corgi(0)) + return ..() + + +/obj/item/weapon/paper/evilfax/process() + if(!countdown) + if(mytarget) + if(activate_on_timeout) + evilpaper_specialaction(mytarget) + else + message_admins("[mytarget] ignored an evil fax until it timed out.") + else + message_admins("Evil paper '[src]' timed out, after not being assigned a target.") + used = 1 + evilpaper_selfdestruct() + else + countdown-- + +/obj/item/weapon/paper/evilfax/proc/evilpaper_specialaction(var/mob/living/carbon/target) + spawn(30) + if(istype(target,/mob/living/carbon)) + if(myeffect == "borging") + target.ForceContractDisease(new /datum/disease/transformation/robot(0)) + else if(myeffect == "corgifying") + target.ForceContractDisease(new /datum/disease/transformation/corgi(0)) + else if(myeffect == "firedeath") + var/turf/simulated/T = get_turf(target) + new /obj/effect/hotspot(T) + target.adjustFireLoss(150) // hard crit, the burning takes care of the rest. + else if(myeffect == "braindeath") + to_chat(target,"A series of bright lights flash across your vision: COGNITOHAZARD YHWH-3 ACTIVATED") + target.mutations.Add(NOCLONE) + target.adjustBrainLoss(125) + else if(myeffect == "honktumor") + if(!target.get_int_organ(/obj/item/organ/internal/honktumor)) + var/obj/item/organ/internal/organ = new /obj/item/organ/internal/honktumor + organ.insert(target) + else if(myeffect == "demotion") + command_announcement.Announce("[mytarget] is hereby demoted to the rank of Civilian. Process this demotion immediately. Failure to comply with these orders is grounds for termination.","CC Demotion Order") + else + message_admins("Evil paper [src] was activated without a proper effect set! This is a bug.") + used = 1 + evilpaper_selfdestruct() + +/obj/item/weapon/paper/evilfax/proc/evilpaper_selfdestruct() + visible_message("[src] spontaneously catches fire, and burns up!") + qdel(src) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index a99efb09294..0cd00015af4 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -204,6 +204,7 @@ for(var/obj/O in src) O.loc = usr.loc O.layer = initial(O.layer) + O.plane = initial(O.plane) O.add_fingerprint(usr) usr.unEquip(src) qdel(src) diff --git a/code/modules/pda/PDA.dm b/code/modules/pda/PDA.dm index 96c5eedff2d..6ade2b7c76a 100755 --- a/code/modules/pda/PDA.dm +++ b/code/modules/pda/PDA.dm @@ -468,7 +468,7 @@ var/global/list/obj/item/device/pda/PDAs = list() S = 'sound/machines/twobeep.ogg' playsound(loc, S, 50, 1) for(var/mob/O in hearers(3, loc)) - O.show_message(text("\icon[src] *[ttone]*")) + O.show_message(text("[bicon(src)] *[ttone]*")) /obj/item/device/pda/proc/set_ringtone() var/t = input("Please enter new ringtone", name, ttone) as text diff --git a/code/modules/pda/app.dm b/code/modules/pda/app.dm index 45b2e79aec3..86c7f85aec0 100644 --- a/code/modules/pda/app.dm +++ b/code/modules/pda/app.dm @@ -24,7 +24,7 @@ L = get(pda, /mob/living/silicon) if(L) - to_chat(L, "\icon[pda] [message]") + to_chat(L, "[bicon(pda)] [message]") nanomanager.update_user_uis(L, pda) // Update the receiving user's PDA UI so that they can see the new message if(!notify_silent) diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 5dd8f2e36ea..dd15f904614 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -113,6 +113,7 @@ var/global/list/rad_collectors = list() return Z.loc = get_turf(src) Z.layer = initial(Z.layer) + Z.plane = initial(Z.plane) src.P = null if(active) toggle_power() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 4f0d72e1511..06ba1a093f8 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -213,7 +213,7 @@ else // Any other A.yo = -20 A.xo = 0 - A.process() //TODO: Carn: check this out + A.fire() //TODO: Carn: check this out /obj/machinery/power/emitter/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 45670ec70b0..26dce25ead2 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -6,14 +6,16 @@ flags = CONDUCT slot_flags = SLOT_BELT throwforce = 1 - w_class = 1.0 - var/caliber = "" //Which kind of guns it can be loaded into - var/projectile_type = ""//The bullet type to create when New() is called + w_class = 1 + var/fire_sound = null //What sound should play when this ammo is fired + var/caliber = null //Which kind of guns it can be loaded into + var/projectile_type = null //The bullet type to create when New() is called var/obj/item/projectile/BB = null //The loaded bullet - var/pellets = 1 - var/deviation = 0 - var/spread = 0 - + var/pellets = 1 //Pellets for spreadshot + var/variance = 0 //Variance for inaccuracy fundamental to the casing + var/delay = 0 //Delay for energy weapons + var/randomspread = 0 //Randomspread for automatics + var/click_cooldown_override = 0 //Override this to make your gun have a faster fire rate, in tenths of a second. 4 is the default gun cooldown. /obj/item/ammo_casing/New() ..() @@ -29,54 +31,50 @@ icon_state = "[initial(icon_state)][BB ? "-live" : ""]" desc = "[initial(desc)][BB ? "" : " This one is spent"]" - - -/obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/weapon/screwdriver)) - if(BB) - if(initial(BB.name) == "bullet") - var/tmp_label = "" - var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label)) - if(length(label_text) > 20) - to_chat(user, "The inscription can be at most 20 characters long.") - else - if(label_text == "") - to_chat(user, "You scratch the inscription off of [initial(BB)].") - BB.name = initial(BB.name) - else - to_chat(user, "You inscribe \"[label_text]\" into \the [initial(BB.name)].") - BB.name = "[initial(BB.name)] \"[label_text]\"" - else - to_chat(user, "You can only inscribe a metal bullet.")//because inscribing beanbags is silly - - else - to_chat(user, "There is no bullet in the casing to inscribe anything into.") - -/obj/item/ammo_casing/attackby(obj/item/ammo_box/box as obj, mob/user as mob, params) - if(!istype(box, /obj/item/ammo_box)) - return - if(isturf(loc)) - var/boolets = 0 - for(var/obj/item/ammo_casing/pew in loc) - if(box.stored_ammo.len >= box.max_ammo) - break - if(pew.BB) - if(box.give_round(pew)) - boolets++ - else - continue - if(boolets > 0) - box.update_icon() - to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.") - else - to_chat(user, "You fail to collect anything.") - -/obj/item/ammo_casing/proc/newshot() //For energy weapons, shotgun shells and wands (!). - if(!BB) - BB = new projectile_type(src) +/obj/item/ammo_casing/proc/newshot(params) //For energy weapons, shotgun shells and wands (!). + if (!BB) + BB = new projectile_type(src, params) return +/obj/item/ammo_casing/attackby(obj/item/I as obj, mob/user as mob, params) + if(istype(I, /obj/item/ammo_box)) + var/obj/item/ammo_box/box = I + if(isturf(loc)) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in loc) + if (box.stored_ammo.len >= box.max_ammo) + break + if (bullet.BB) + if (box.give_round(bullet, 0)) + boolets++ + else + continue + if (boolets > 0) + box.update_icon() + to_chat(user, "You collect [boolets] shell\s. [box] now contains [box.stored_ammo.len] shell\s.") + else + to_chat(user, "You fail to collect anything!") + else + if(istype(I, /obj/item/weapon/screwdriver)) + if(BB) + if(initial(BB.name) == "bullet") + var/tmp_label = "" + var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label)) + if(length(label_text) > 20) + to_chat(user, "The inscription can be at most 20 characters long.") + else + if(label_text == "") + to_chat(user, "You scratch the inscription off of [initial(BB)].") + BB.name = initial(BB.name) + else + to_chat(user, "You inscribe \"[label_text]\" into \the [initial(BB.name)].") + BB.name = "[initial(BB.name)] \"[label_text]\"" + else + to_chat(user, "You can only inscribe a metal bullet.")//because inscribing beanbags is silly + else + to_chat(user, "There is no bullet in the casing to inscribe anything into.") + ..() //Boxes of ammo /obj/item/ammo_box @@ -89,53 +87,78 @@ item_state = "syringe_kit" materials = list(MAT_METAL=30000) throwforce = 2 - w_class = 1.0 + w_class = 1 throw_speed = 4 throw_range = 10 var/list/stored_ammo = list() - var/obj/item/ammo_casing/ammo_type + var/ammo_type = /obj/item/ammo_casing var/max_ammo = 7 var/multiple_sprites = 0 - var/caliber = "" + var/caliber var/multiload = 1 + /obj/item/ammo_box/New() - for(var/i = 1, i <= max_ammo, i++) + for(var/i in 1 to max_ammo) stored_ammo += new ammo_type(src) update_icon() -/obj/item/ammo_box/proc/get_round(var/keep = 0) - if(!stored_ammo.len) +/obj/item/ammo_box/Destroy() + for(var/atom/A in stored_ammo) + qdel(A) + stored_ammo = null + return ..() + +/obj/item/ammo_box/proc/get_round(keep = 0) + if (!stored_ammo.len) return null else var/b = stored_ammo[stored_ammo.len] stored_ammo -= b - if(keep) + if (keep) stored_ammo.Insert(1,b) return b -/obj/item/ammo_box/proc/give_round(var/obj/item/ammo_casing/r) - var/obj/item/ammo_casing/rb = r - if(rb) - if(stored_ammo.len < max_ammo && rb.caliber == caliber) - stored_ammo += rb - rb.loc = src - return 1 +/obj/item/ammo_box/proc/give_round(obj/item/ammo_casing/R, replace_spent = 0) + // Boxes don't have a caliber type, magazines do. Not sure if it's intended or not, but if we fail to find a caliber, then we fall back to ammo_type. + if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + return 0 + + if (stored_ammo.len < max_ammo) + stored_ammo += R + R.loc = src + return 1 + //for accessibles magazines (e.g internal ones) when full, start replacing spent ammo + else if(replace_spent) + for(var/obj/item/ammo_casing/AC in stored_ammo) + if(!AC.BB)//found a spent ammo + stored_ammo -= AC + AC.loc = get_turf(loc) + + stored_ammo += R + R.loc = src + return 1 + return 0 -/obj/item/ammo_box/attackby(var/obj/item/A as obj, mob/user as mob, var/silent = 0, params) +/obj/item/ammo_box/proc/can_load(mob/user) + return 1 + +/obj/item/ammo_box/attackby(obj/item/A, mob/user, params, silent = 0, replace_spent = 0) var/num_loaded = 0 + if(!can_load(user)) + return if(istype(A, /obj/item/ammo_box)) var/obj/item/ammo_box/AM = A for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - var/didload = give_round(AC) - if(didload) + var/did_load = give_round(AC, replace_spent) + if(did_load) AM.stored_ammo -= AC num_loaded++ - if(!multiload || !didload) + if(!multiload || !did_load) break if(istype(A, /obj/item/ammo_casing)) var/obj/item/ammo_casing/AC = A - if(give_round(AC)) + if(give_round(AC, replace_spent)) user.drop_item() AC.loc = src num_loaded++ @@ -145,6 +168,8 @@ A.update_icon() update_icon() + return num_loaded + /obj/item/ammo_box/attack_self(mob/user as mob) var/obj/item/ammo_casing/A = get_round() if(A) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index 44189411515..a5af74e4d6c 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -1,128 +1,146 @@ /obj/item/ammo_casing/a357 desc = "A .357 bullet casing." caliber = "357" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet + +/obj/item/ammo_casing/a762 + desc = "A 7.62mm bullet casing." + icon_state = "762-casing" + caliber = "a762" + projectile_type = /obj/item/projectile/bullet + +/obj/item/ammo_casing/a762/enchanted + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/a50 desc = "A .50AE bullet casing." caliber = ".50" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet /obj/item/ammo_casing/c38 desc = "A .38 bullet casing." caliber = "38" - projectile_type = "/obj/item/projectile/bullet/weakbullet2/rubber" - -/obj/item/ammo_casing/cap - desc = "A cap for children toys." - caliber = "caps" - projectile_type = "/obj/item/projectile/bullet/cap" - + projectile_type = /obj/item/projectile/bullet/weakbullet2/rubber /obj/item/ammo_casing/c10mm desc = "A 10mm bullet casing." caliber = "10mm" - projectile_type = "/obj/item/projectile/bullet/midbullet3" - + projectile_type = /obj/item/projectile/bullet/midbullet3 /obj/item/ammo_casing/c9mm desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/weakbullet3" + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/c9mmap desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/armourpiercing" + projectile_type = /obj/item/projectile/bullet/armourpiercing /obj/item/ammo_casing/c9mmtox desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/toxinbullet" + projectile_type = /obj/item/projectile/bullet/toxinbullet /obj/item/ammo_casing/c9mminc desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" + projectile_type = /obj/item/projectile/bullet/incendiary/firebullet /obj/item/ammo_casing/c46x30mm desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/weakbullet3" + projectile_type = /obj/item/projectile/bullet/weakbullet3 /obj/item/ammo_casing/c46x30mmap desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/armourpiercing" + projectile_type = /obj/item/projectile/bullet/armourpiercing /obj/item/ammo_casing/c46x30mmtox desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/toxinbullet" + projectile_type = /obj/item/projectile/bullet/toxinbullet /obj/item/ammo_casing/c46x30mminc desc = "A 4.6x30mm bullet casing." caliber = "4.6x30mm" - projectile_type = "/obj/item/projectile/bullet/incendiary/firebullet" + projectile_type = /obj/item/projectile/bullet/incendiary/firebullet /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." caliber = ".45" - projectile_type = "/obj/item/projectile/bullet/midbullet" + projectile_type = /obj/item/projectile/bullet/midbullet +/obj/item/ammo_casing/c45nostamina + desc = "A .45 bullet casing." + caliber = ".45" + projectile_type = /obj/item/projectile/bullet/midbullet3 + +/obj/item/ammo_casing/n762 + desc = "A 7.62x38mmR bullet casing." + caliber = "n762" + projectile_type = /obj/item/projectile/bullet + +/obj/item/ammo_casing/caseless/magspear + name = "magnetic spear" + desc = "A reusable spear that is typically loaded into kinetic spearguns." + projectile_type = /obj/item/projectile/bullet/reusable/magspear + caliber = "speargun" + icon_state = "magspear" + throwforce = 15 //still deadly when thrown + throw_speed = 3 /obj/item/ammo_casing/shotgun name = "shotgun slug" desc = "A 12 gauge lead slug." icon_state = "blshell" caliber = "shotgun" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet materials = list(MAT_METAL=4000) - /obj/item/ammo_casing/shotgun/buckshot name = "buckshot shell" desc = "A 12 gauge buckshot shell." icon_state = "gshell" - projectile_type = "/obj/item/projectile/bullet/pellet" + projectile_type = /obj/item/projectile/bullet/pellet pellets = 6 - deviation = 30 + variance = 25 /obj/item/ammo_casing/shotgun/rubbershot name = "rubber shot" desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance." icon_state = "bshell" - projectile_type = "/obj/item/projectile/bullet/rpellet" + projectile_type = /obj/item/projectile/bullet/rpellet pellets = 6 - deviation = 30 + variance = 25 materials = list(MAT_METAL=4000) /obj/item/ammo_casing/shotgun/beanbag name = "beanbag slug" desc = "A weak beanbag slug for riot control." icon_state = "bshell" - projectile_type = "/obj/item/projectile/bullet/weakbullet/rubber" + projectile_type = /obj/item/projectile/bullet/weakbullet/rubber materials = list(MAT_METAL=250) - /obj/item/ammo_casing/shotgun/improvised name = "improvised shell" desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards." icon_state = "gshell" - projectile_type = "/obj/item/projectile/bullet/pellet/weak" + projectile_type = /obj/item/projectile/bullet/pellet/weak materials = list(MAT_METAL=250) pellets = 5 - deviation = 30 + variance = 25 /obj/item/ammo_casing/shotgun/improvised/overload name = "overloaded improvised shell" desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards. This one has been packed with even more \ propellant. It's like playing russian roulette, with a shotgun." icon_state = "improvshell" - projectile_type = "/obj/item/projectile/bullet/pellet/random" + projectile_type = /obj/item/projectile/bullet/pellet/overload materials = list(MAT_METAL=250) pellets = 5 - deviation = 30 + variance = 40 /obj/item/ammo_casing/shotgun/improvised/overload/New() ..() @@ -132,15 +150,20 @@ name = "taser slug" desc = "A stunning taser slug." icon_state = "stunshell" - projectile_type = "/obj/item/projectile/bullet/stunshot" + projectile_type = /obj/item/projectile/bullet/stunshot materials = list(MAT_METAL=250) - /obj/item/ammo_casing/shotgun/meteorshot name = "meteorshot shell" desc = "A shotgun shell rigged with CMC technology, which launches a massive slug when fired." icon_state = "mshell" - projectile_type = "/obj/item/projectile/bullet/meteorshot" + projectile_type = /obj/item/projectile/bullet/meteorshot + +/obj/item/ammo_casing/shotgun/breaching + name = "breaching shell" + desc = "An economic version of the meteorshot, utilizing similar technologies. Great for busting down doors." + icon_state = "mshell" + projectile_type = /obj/item/projectile/bullet/meteorshot/weak /obj/item/ammo_casing/shotgun/pulseslug name = "pulse slug" @@ -148,42 +171,42 @@ energy blast. While the heat and power drain limit it to one use, it can still allow an operator to engage targets that ballistic ammunition \ would have difficulty with." icon_state = "pshell" - projectile_type = "/obj/item/projectile/beam/pulse/shot" + projectile_type = /obj/item/projectile/beam/pulse/shot /obj/item/ammo_casing/shotgun/incendiary name = "incendiary slug" desc = "An incendiary-coated shotgun slug." icon_state = "ishell" - projectile_type = "/obj/item/projectile/bullet/incendiary/shell" + projectile_type = /obj/item/projectile/bullet/incendiary/shell /obj/item/ammo_casing/shotgun/frag12 name = "FRAG-12 slug" desc = "A high explosive breaching round for a 12 gauge shotgun." icon_state = "heshell" - projectile_type = "/obj/item/projectile/bullet/frag12" + projectile_type = /obj/item/projectile/bullet/frag12 /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath name = "dragonsbreath shell" desc = "A shotgun shell which fires a spread of incendiary pellets." icon_state = "ishell2" - projectile_type = "/obj/item/projectile/bullet/incendiary/shell/dragonsbreath" + projectile_type = /obj/item/projectile/bullet/incendiary/shell/dragonsbreath pellets = 4 - deviation = 30 + variance = 35 /obj/item/ammo_casing/shotgun/ion name = "ion shell" desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \ The unique properties of the crystal splot the pulse into a spread of individually weaker bolts." icon_state = "ionshell" - projectile_type = "/obj/item/projectile/ion/weak" + projectile_type = /obj/item/projectile/ion/weak pellets = 4 - deviation = 30 + variance = 35 /obj/item/ammo_casing/shotgun/laserslug name = "laser slug" desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package." icon_state = "lshell" - projectile_type = "/obj/item/projectile/beam" + projectile_type = /obj/item/projectile/beam /obj/item/ammo_casing/shotgun/techshell name = "unloaded technological shell" @@ -195,7 +218,7 @@ name = "shotgun dart" desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical." icon_state = "cshell" - projectile_type = "/obj/item/projectile/bullet/dart" + projectile_type = /obj/item/projectile/bullet/dart /obj/item/ammo_casing/shotgun/dart/New() ..() @@ -206,93 +229,116 @@ /obj/item/ammo_casing/shotgun/dart/attackby() return +/obj/item/ammo_casing/shotgun/dart/bioterror + desc = "A shotgun dart filled with deadly toxins." + +/obj/item/ammo_casing/shotgun/dart/bioterror/New() + ..() + reagents.add_reagent("neurotoxin", 6) + reagents.add_reagent("spores", 6) + reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT + reagents.add_reagent("coniine", 6) + reagents.add_reagent("sodium_thiopental", 6) + /obj/item/ammo_casing/shotgun/tranquilizer name = "tranquilizer darts" desc = "A tranquilizer round used to subdue individuals utilizing stimulants." icon_state = "cshell" - projectile_type = "/obj/item/projectile/bullet/dart/syringe/tranquilizer" + projectile_type = /obj/item/projectile/bullet/dart/syringe/tranquilizer materials = list(MAT_METAL=250) -/obj/item/ammo_casing/syringegun - name = "syringe gun spring" - desc = "A high-power spring that throws syringes." - projectile_type = null +/obj/item/ammo_casing/a556 + desc = "A 5.56mm bullet casing." + caliber = "a556" + projectile_type = /obj/item/projectile/bullet/heavybullet /obj/item/ammo_casing/shotgun/fakebeanbag name = "beanbag shell" desc = "A weak beanbag shell." icon_state = "bshell" - projectile_type = "/obj/item/projectile/bullet/weakbullet/booze" - -/obj/item/ammo_casing/a762 - desc = "A 7.62mm bullet casing." - icon_state = "762-casing" - caliber = "a762" - projectile_type = "/obj/item/projectile/bullet" - -/obj/item/ammo_casing/a556 - desc = "A 5.56mm bullet casing." - caliber = "a556" - projectile_type = "/obj/item/projectile/bullet/heavybullet" + projectile_type = /obj/item/projectile/bullet/weakbullet/booze /obj/item/ammo_casing/rocket name = "rocket shell" desc = "A high explosive designed to be fired from a launcher." icon_state = "rocketshell" - projectile_type = "/obj/item/missile" + projectile_type = /obj/item/missile caliber = "rocket" /obj/item/ammo_casing/caseless desc = "A caseless bullet casing." +/obj/item/ammo_casing/caseless/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet) + if (..()) + loc = null + return 1 + else + return 0 + /obj/item/ammo_casing/caseless/a75 desc = "A .75 bullet casing." caliber = "75" - projectile_type = "/obj/item/projectile/bullet/gyro" + projectile_type = /obj/item/projectile/bullet/gyro /obj/item/ammo_casing/a40mm name = "40mm HE shell" desc = "A cased high explosive grenade that can only be activated once fired out of a grenade launcher." caliber = "40mm" icon_state = "40mmHE" - projectile_type = "/obj/item/projectile/bullet/a40mm" + projectile_type = /obj/item/projectile/bullet/a40mm -//FOAM DARTS /obj/item/ammo_casing/caseless/foam_dart name = "foam dart" desc = "It's nerf or nothing! Ages 8 and up." - projectile_type = "/obj/item/projectile/bullet/reusable/foam_dart" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart caliber = "foam_force" - icon = 'icons/obj/toyguns.dmi' + icon = 'icons/obj/guns/toy.dmi' icon_state = "foamdart" var/modified = 0 /obj/item/ammo_casing/caseless/foam_dart/update_icon() - if(modified) - icon_state = "foamdart_empty" - -/obj/item/ammo_casing/caseless/foam_dart/attackby(var/obj/item/weapon/A as obj, mob/user as mob, params) ..() - if(istype(A, /obj/item/weapon/screwdriver) && !modified) - modified = 1 - BB.damage_type = BRUTE + if (modified) icon_state = "foamdart_empty" - desc = "It's nerf or nothing! ...Although, this one doesn't look too safe." - to_chat(user, "You pop the safety cap off of [src].") - else if((istype(A, /obj/item/weapon/pen)) && modified && !BB.contents.len) + desc = "Its nerf or nothing! ... Although, this one doesn't look too safe." + if(BB) + BB.icon_state = "foamdart_empty" + else + icon_state = "foamdart" + desc = "Its nerf or nothing! Ages 8 and up." + if(BB) + BB.icon_state = "foamdart_empty" + +/obj/item/ammo_casing/caseless/foam_dart/attackby(obj/item/A, mob/user, params) + ..() + var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB + if (istype(A, /obj/item/weapon/screwdriver) && !modified) + modified = 1 + FD.damage_type = BRUTE + update_icon() + else if ((istype(A, /obj/item/weapon/pen)) && modified && !FD.pen) if(!user.unEquip(A)) return - A.forceMove(BB) - BB.damage = 5 - BB.nodamage = 0 + A.loc = FD + FD.pen = A + FD.damage = 5 + FD.nodamage = 0 to_chat(user, "You insert [A] into [src].") return +/obj/item/ammo_casing/caseless/foam_dart/attack_self(mob/living/user) + var/obj/item/projectile/bullet/reusable/foam_dart/FD = BB + if(FD.pen) + FD.damage = initial(FD.damage) + FD.nodamage = initial(FD.nodamage) + user.put_in_hands(FD.pen) + to_chat(user, "You remove [FD.pen] from [src].") + FD.pen = null /obj/item/ammo_casing/caseless/foam_dart/riot name = "riot foam dart" desc = "Whose smart idea was it to use toys as crowd control? Ages 18 and up." - projectile_type = "/obj/item/projectile/bullet/reusable/foam_dart/riot" + projectile_type = /obj/item/projectile/bullet/reusable/foam_dart/riot icon_state = "foamdart_riot" /obj/item/ammo_casing/shotgun/dart/assassination @@ -301,3 +347,8 @@ /obj/item/ammo_casing/shotgun/dart/assassination/New() ..() reagents.add_reagent("neurotoxin", 6) + +/obj/item/ammo_casing/cap + desc = "A cap for children toys." + caliber = "caps" + projectile_type = /obj/item/projectile/bullet/cap diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index eb998823b6a..894b5ac25b1 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -1,5 +1,6 @@ /obj/item/ammo_box/a357 name = "speed loader (.357)" + desc = "Designed to quickly reload revolvers." icon_state = "357" ammo_type = /obj/item/ammo_casing/a357 max_ammo = 7 @@ -7,18 +8,12 @@ /obj/item/ammo_box/c38 name = "speed loader (.38)" + desc = "Designed to quickly reload revolvers." icon_state = "38" ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 multiple_sprites = 1 -/obj/item/ammo_box/caps - name = "speed loader (caps)" - icon_state = "357" - ammo_type = /obj/item/ammo_casing/cap - max_ammo = 7 - multiple_sprites = 1 - /obj/item/ammo_box/c9mm name = "ammo box (9mm)" icon_state = "9mmbox" @@ -55,6 +50,13 @@ max_ammo = 5 multiple_sprites = 1 +/obj/item/ammo_box/n762 + name = "ammo box (7.62x38mmR)" + icon_state = "10mmbox" + origin_tech = "combat=2" + ammo_type = /obj/item/ammo_casing/n762 + max_ammo = 14 + /obj/item/ammo_box/shotgun name = "Ammunition Box (slug)" icon_state = "9mmbox" @@ -91,7 +93,7 @@ //FOAM DARTS /obj/item/ammo_box/foambox name = "ammo box (Foam Darts)" - icon = 'icons/obj/toyguns.dmi' + icon = 'icons/obj/guns/toy.dmi' icon_state = "foambox" ammo_type = /obj/item/ammo_casing/caseless/foam_dart max_ammo = 40 @@ -99,3 +101,10 @@ /obj/item/ammo_box/foambox/riot icon_state = "foambox_riot" ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot + +/obj/item/ammo_box/caps + name = "speed loader (caps)" + icon_state = "357" + ammo_type = /obj/item/ammo_casing/cap + max_ammo = 7 + multiple_sprites = 1 diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm new file mode 100644 index 00000000000..7ed6fd4d9ed --- /dev/null +++ b/code/modules/projectiles/ammunition/energy.dm @@ -0,0 +1,247 @@ +/obj/item/ammo_casing/energy + name = "energy weapon lens" + desc = "The part of the gun that makes the laser go pew" + caliber = "energy" + projectile_type = /obj/item/projectile/energy + var/e_cost = 1000 //The amount of energy a cell needs to expend to create this shot. + var/select_name = "energy" + fire_sound = 'sound/weapons/Laser.ogg' + +/obj/item/ammo_casing/energy/laser + projectile_type = /obj/item/projectile/beam/laser + select_name = "kill" + +/obj/item/ammo_casing/energy/lasergun + projectile_type = /obj/item/projectile/beam/laser + e_cost = 830 + select_name = "kill" + +/obj/item/ammo_casing/energy/laser/hos //allows balancing of HoS and blueshit guns seperately from other energy weapons + +/obj/item/ammo_casing/energy/laser/practice + projectile_type = /obj/item/projectile/beam/practice + select_name = "practice" + +/obj/item/ammo_casing/energy/laser/scatter + projectile_type = /obj/item/projectile/beam/scatter + pellets = 5 + variance = 25 + select_name = "scatter" + +/obj/item/ammo_casing/energy/laser/heavy + projectile_type = /obj/item/projectile/beam/laser/heavylaser + select_name = "anti-vehicle" + fire_sound = 'sound/weapons/lasercannonfire.ogg' + +/obj/item/ammo_casing/energy/laser/pulse + projectile_type = /obj/item/projectile/beam/pulse + e_cost = 200 + select_name = "DESTROY" + fire_sound = 'sound/weapons/pulse.ogg' + +/obj/item/ammo_casing/energy/laser/scatter/pulse + projectile_type = /obj/item/projectile/beam/pulse + e_cost = 2000 + select_name = "ANNIHILATE" + fire_sound = 'sound/weapons/pulse.ogg' + +/obj/item/ammo_casing/energy/laser/bluetag + projectile_type = /obj/item/projectile/beam/lasertag/bluetag + select_name = "bluetag" + +/obj/item/ammo_casing/energy/laser/redtag + projectile_type = /obj/item/projectile/beam/lasertag/redtag + select_name = "redtag" + +/obj/item/ammo_casing/energy/xray + projectile_type = /obj/item/projectile/beam/xray + e_cost = 500 + fire_sound = 'sound/weapons/laser3.ogg' + +/obj/item/ammo_casing/energy/immolator + projectile_type = /obj/item/projectile/beam/immolator + fire_sound = 'sound/weapons/laser3.ogg' + e_cost = 1250 + +/obj/item/ammo_casing/energy/electrode + projectile_type = /obj/item/projectile/energy/electrode + select_name = "stun" + fire_sound = 'sound/weapons/taser.ogg' + e_cost = 2000 + delay = 15 + +/obj/item/ammo_casing/energy/electrode/gun + fire_sound = 'sound/weapons/gunshot.ogg' + e_cost = 1000 + +/obj/item/ammo_casing/energy/electrode/hos //allows balancing of HoS and blueshit guns seperately from other energy weapons + +/obj/item/ammo_casing/energy/ion + projectile_type = /obj/item/projectile/ion + select_name = "ion" + fire_sound = 'sound/weapons/IonRifle.ogg' + +/obj/item/ammo_casing/energy/declone + projectile_type = /obj/item/projectile/energy/declone + select_name = "declone" + fire_sound = 'sound/weapons/pulse3.ogg' + +/obj/item/ammo_casing/energy/mindflayer + projectile_type = /obj/item/projectile/beam/mindflayer + select_name = "MINDFUCK" + fire_sound = 'sound/weapons/Laser.ogg' + +/obj/item/ammo_casing/energy/flora + fire_sound = 'sound/effects/stealthoff.ogg' + +/obj/item/ammo_casing/energy/flora/yield + projectile_type = /obj/item/projectile/energy/florayield + select_name = "yield" + +/obj/item/ammo_casing/energy/flora/mut + projectile_type = /obj/item/projectile/energy/floramut + select_name = "mutation" + +/obj/item/ammo_casing/energy/temp + projectile_type = /obj/item/projectile/temp + e_cost = 100 + fire_sound = 'sound/weapons/pulse3.ogg' + +/obj/item/ammo_casing/energy/temp/New() + ..() + BB = null + +/obj/item/ammo_casing/energy/temp/newshot(shot_temp, shot_cost) + e_cost = shot_cost + ..(shot_temp) + +/obj/item/ammo_casing/energy/meteor + projectile_type = /obj/item/projectile/meteor + select_name = "goddamn meteor" + +/obj/item/ammo_casing/energy/kinetic + projectile_type = /obj/item/projectile/kinetic + select_name = "kinetic" + e_cost = 5000 + fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap + +/obj/item/ammo_casing/energy/kinetic/super + projectile_type = /obj/item/projectile/kinetic/super + +/obj/item/ammo_casing/energy/kinetic/hyper + projectile_type = /obj/item/projectile/kinetic/hyper + +/obj/item/ammo_casing/energy/disabler + projectile_type = /obj/item/projectile/beam/disabler + select_name = "disable" + e_cost = 500 + fire_sound = "sound/weapons/taser2.ogg" + +/obj/item/ammo_casing/energy/plasma + projectile_type = /obj/item/projectile/plasma + select_name = "plasma burst" + fire_sound = 'sound/weapons/plasma_cutter.ogg' + delay = 15 + e_cost = 250 + +/obj/item/ammo_casing/energy/plasma/adv + projectile_type = /obj/item/projectile/plasma/adv + delay = 10 + e_cost = 100 + +/obj/item/ammo_casing/energy/wormhole + projectile_type = /obj/item/projectile/beam/wormhole + e_cost = 0 + fire_sound = "sound/weapons/pulse3.ogg" + var/obj/item/weapon/gun/energy/wormhole_projector/gun = null + select_name = "blue" + +/obj/item/ammo_casing/energy/wormhole/New(var/obj/item/weapon/gun/energy/wormhole_projector/wh) + gun = wh + +/obj/item/ammo_casing/energy/wormhole/orange + projectile_type = /obj/item/projectile/beam/wormhole/orange + select_name = "orange" + +/obj/item/ammo_casing/energy/bolt + projectile_type = /obj/item/projectile/energy/bolt + select_name = "bolt" + e_cost = 5000 + fire_sound = 'sound/weapons/Genhit.ogg' + +/obj/item/ammo_casing/energy/bolt/large + projectile_type = /obj/item/projectile/energy/bolt/large + select_name = "heavy bolt" + +/obj/item/ammo_casing/energy/dart + projectile_type = /obj/item/projectile/energy/dart + fire_sound = 'sound/weapons/Genhit.ogg' + e_cost = 5000 + select_name = "toxic dart" + +/obj/item/ammo_casing/energy/instakill + projectile_type = /obj/item/projectile/beam/instakill + e_cost = 0 + select_name = "DESTROY" + +/obj/item/ammo_casing/energy/instakill/blue + projectile_type = /obj/item/projectile/beam/instakill/blue + +/obj/item/ammo_casing/energy/instakill/red + projectile_type = /obj/item/projectile/beam/instakill/red + +/obj/item/ammo_casing/energy/plasma + projectile_type = /obj/item/projectile/plasma + select_name = "plasma burst" + fire_sound = 'sound/weapons/pulse.ogg' + +/obj/item/ammo_casing/energy/plasma/adv + projectile_type = /obj/item/projectile/plasma/adv + +/obj/item/ammo_casing/energy/shock_revolver + fire_sound = 'sound/magic/lightningbolt.ogg' + e_cost = 2000 + select_name = "lightning beam" + projectile_type = /obj/item/projectile/energy/shock_revolver + +/obj/item/ammo_casing/energy/toxplasma + projectile_type = /obj/item/projectile/energy/toxplasma + fire_sound = "sound/weapons/taser2.ogg" + select_name = "plasma dart" + +/obj/item/ammo_casing/energy/clown + projectile_type = /obj/item/projectile/clown + fire_sound = 'sound/weapons/Gunshot_smg.ogg' + select_name = "clown" + +/obj/item/ammo_casing/energy/sniper + projectile_type = /obj/item/projectile/beam/sniper + fire_sound = 'sound/weapons/marauder.ogg' + delay = 50 + select_name = "snipe" + +/obj/item/ammo_casing/energy/teleport + projectile_type = /obj/item/projectile/energy/teleport + fire_sound = 'sound/weapons/wave.ogg' + e_cost = 1250 + select_name = "teleport beam" + var/teleport_target + +/obj/item/ammo_casing/energy/teleport/New() + ..() + BB = null + +/obj/item/ammo_casing/energy/teleport/newshot(teleport_target) + ..() + +/obj/item/ammo_casing/energy/mimic + projectile_type = /obj/item/projectile/mimic + fire_sound = 'sound/weapons/bite.ogg' + select_name = "gun mimic" + +/obj/item/ammo_casing/energy/mimic/New() + ..() + BB = null + +/obj/item/ammo_casing/energy/mimic/newshot(mimic_type) + ..() diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 32c3eeaa37c..c77dcc07595 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -1,113 +1,169 @@ ////////////////INTERNAL MAGAZINES////////////////////// +/obj/item/ammo_box/magazine/internal + desc = "Oh god, this shouldn't be here" + +//internals magazines are accessible, so replace spent ammo if full when trying to put a live one in +/obj/item/ammo_box/magazine/internal/give_round(obj/item/ammo_casing/R) + return ..(R,1) + +// Revolver internal mags /obj/item/ammo_box/magazine/internal/cylinder name = "revolver cylinder" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/a357" + ammo_type = /obj/item/ammo_casing/a357 caliber = "357" max_ammo = 7 -/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(var/countempties = 1) - if (!countempties) - var/boolets = 0 - for (var/i = 1, i <= stored_ammo.len, i++) - var/obj/item/ammo_casing/bullet = stored_ammo[i] - if (bullet.BB) - boolets++ - return boolets - else - return stored_ammo.len +/obj/item/ammo_box/magazine/internal/cylinder/ammo_count(countempties = 1) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in stored_ammo) + if(bullet && (bullet.BB || countempties)) + boolets++ + return boolets -/obj/item/ammo_box/magazine/internal/cylinder/rus357 - name = "russian revolver cylinder" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/a357" - caliber = "357" - max_ammo = 6 - multiload = 0 +/obj/item/ammo_box/magazine/internal/cylinder/get_round(keep = 0) + rotate() -/obj/item/ammo_box/magazine/internal/cylinder/rus357/New() - stored_ammo += new ammo_type(src) + var/b = stored_ammo[1] + if(!keep) + stored_ammo[1] = null + + return b + +/obj/item/ammo_box/magazine/internal/cylinder/proc/rotate() + var/b = stored_ammo[1] + stored_ammo.Cut(1,2) + stored_ammo.Insert(0, b) + +/obj/item/ammo_box/magazine/internal/cylinder/proc/spin() + for(var/i in 1 to rand(0, max_ammo*2)) + rotate() + +/obj/item/ammo_box/magazine/internal/cylinder/give_round(obj/item/ammo_casing/R, replace_spent = 0) + if(!R || (caliber && R.caliber != caliber) || (!caliber && R.type != ammo_type)) + return 0 + + for(var/i in 1 to stored_ammo.len) + var/obj/item/ammo_casing/bullet = stored_ammo[i] + if(!bullet || !bullet.BB) // found a spent ammo + stored_ammo[i] = R + R.loc = src + + if(bullet) + bullet.loc = get_turf(loc) + return 1 + + return 0 /obj/item/ammo_box/magazine/internal/cylinder/rev38 - name = "d-tiv revolver cylinder" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/c38" + name = "detective revolver cylinder" + ammo_type = /obj/item/ammo_casing/c38 caliber = "38" max_ammo = 6 +/obj/item/ammo_box/magazine/internal/cylinder/rev762 + name = "nagant revolver cylinder" + ammo_type = /obj/item/ammo_casing/n762 + caliber = "n762" + max_ammo = 7 + /obj/item/ammo_box/magazine/internal/cylinder/cap name = "cap gun revolver cylinder" desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/cap" + ammo_type = /obj/item/ammo_casing/cap caliber = "cap" max_ammo = 7 +// Shotgun internal mags /obj/item/ammo_box/magazine/internal/shot name = "shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag caliber = "shotgun" max_ammo = 4 multiload = 0 -/obj/item/ammo_box/magazine/internal/shotcom +/obj/item/ammo_box/magazine/internal/shot/ammo_count(countempties = 1) + if (!countempties) + var/boolets = 0 + for(var/obj/item/ammo_casing/bullet in stored_ammo) + if(bullet.BB) + boolets++ + return boolets + else + return ..() + +/obj/item/ammo_box/magazine/internal/shot/tube + name = "dual feed shotgun internal tube" + ammo_type = /obj/item/ammo_casing/shotgun/rubbershot + max_ammo = 4 + +/obj/item/ammo_box/magazine/internal/shot/lethal + ammo_type = /obj/item/ammo_casing/shotgun/buckshot + +/obj/item/ammo_box/magazine/internal/shot/com name = "combat shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot max_ammo = 6 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/dualshot +/obj/item/ammo_box/magazine/internal/shot/dual name = "double-barrel shotgun internal magazine" - desc = "This doesn't even exist" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" - caliber = "shotgun" max_ammo = 2 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/improvised +/obj/item/ammo_box/magazine/internal/shot/improvised name = "improvised shotgun internal magazine" - desc = "This doesn't even exist" - ammo_type = "/obj/item/ammo_casing/shotgun/improvised" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/improvised max_ammo = 1 - multiload = 0 -/obj/item/ammo_box/magazine/internal/shotriot +/obj/item/ammo_box/magazine/internal/shot/riot name = "riot shotgun internal magazine" - desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/shotgun/rubbershot" - caliber = "shotgun" + ammo_type = /obj/item/ammo_casing/shotgun/rubbershot max_ammo = 6 - multiload = 0 -/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher +/obj/item/ammo_box/magazine/internal/grenadelauncher name = "grenade launcher internal magazine" - ammo_type = "/obj/item/ammo_casing/a40mm" + ammo_type = /obj/item/ammo_casing/a40mm caliber = "40mm" max_ammo = 1 /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi - ammo_type = "/obj/item/ammo_casing/a40mm" + ammo_type = /obj/item/ammo_casing/a40mm max_ammo = 6 +/obj/item/ammo_box/magazine/internal/speargun + name = "speargun internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/magspear + caliber = "speargun" + max_ammo = 1 + +/obj/item/ammo_box/magazine/internal/rus357 + name = "russian revolver cylinder" + ammo_type = /obj/item/ammo_casing/a357 + caliber = "357" + max_ammo = 6 + multiload = 0 + +/obj/item/ammo_box/magazine/internal/rus357/New() + stored_ammo += new ammo_type(src) + /obj/item/ammo_box/magazine/internal/boltaction name = "bolt action rifle internal magazine" desc = "Oh god, this shouldn't be here" - ammo_type = "/obj/item/ammo_casing/a762" + ammo_type = /obj/item/ammo_casing/a762 caliber = "a762" max_ammo = 5 multiload = 1 +/obj/item/ammo_box/magazine/internal/boltaction/enchanted + max_ammo =1 + ammo_type = /obj/item/ammo_casing/a762/enchanted + /obj/item/ammo_box/magazine/internal/shot/toy - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart caliber = "foam_force" max_ammo = 4 /obj/item/ammo_box/magazine/internal/shot/toy/crossbow - max_ammo = 5 + max_ammo = 5 /obj/item/ammo_box/magazine/internal/shot/toy/tommygun max_ammo = 10 @@ -116,17 +172,18 @@ /obj/item/ammo_box/magazine/m10mm name = "pistol magazine (10mm)" + desc = "A gun magazine." icon_state = "9x19p" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c10mm" + ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 8 multiple_sprites = 2 /obj/item/ammo_box/magazine/m45 name = "handgun magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45" + icon_state = "45-8" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 8 @@ -137,7 +194,7 @@ /obj/item/ammo_box/magazine/wt550m9 name = "wt550 magazine (4.6x30mm)" icon_state = "46x30mmt-20" - ammo_type = "/obj/item/ammo_casing/c46x30mm" + ammo_type = /obj/item/ammo_casing/c46x30mm caliber = "4.6x30mm" max_ammo = 20 @@ -147,20 +204,20 @@ /obj/item/ammo_box/magazine/wt550m9/wtap name = "wt550 magazine (Armour Piercing 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mmap" + ammo_type = /obj/item/ammo_casing/c46x30mmap /obj/item/ammo_box/magazine/wt550m9/wttx name = "wt550 magazine (Toxin Tipped 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mmtox" + ammo_type = /obj/item/ammo_casing/c46x30mmtox /obj/item/ammo_box/magazine/wt550m9/wtic name = "wt550 magazine (Incindiary 4.6x30mm)" - ammo_type = "/obj/item/ammo_casing/c46x30mminc" + ammo_type = /obj/item/ammo_casing/c46x30mminc /obj/item/ammo_box/magazine/uzim9mm name = "uzi magazine (9mm)" icon_state = "uzi9mm-32" - ammo_type = "/obj/item/ammo_casing/c9mm" + ammo_type = /obj/item/ammo_casing/c9mm caliber = "9mm" max_ammo = 32 @@ -171,35 +228,46 @@ /obj/item/ammo_box/magazine/smgm9mm name = "SMG magazine (9mm)" icon_state = "smg9mm" - ammo_type = "/obj/item/ammo_casing/c9mm" + ammo_type = /obj/item/ammo_casing/c9mm caliber = "9mm" - max_ammo = 30 + max_ammo = 21 materials = list(MAT_METAL = 2000) /obj/item/ammo_box/magazine/smgm9mm/ap name = "SMG magazine (Armour Piercing 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mmap" + ammo_type = /obj/item/ammo_casing/c9mmap materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/toxin name = "SMG magazine (Toxin Tipped 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mmtox" + ammo_type = /obj/item/ammo_casing/c9mmtox materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/fire name = "SMG Magazine (Incendiary 9mm)" - ammo_type = "/obj/item/ammo_casing/c9mminc" + ammo_type = /obj/item/ammo_casing/c9mminc materials = list(MAT_METAL = 3000) /obj/item/ammo_box/magazine/smgm9mm/update_icon() ..() icon_state = "[initial(icon_state)]-[round(ammo_count(),6)]" +/obj/item/ammo_box/magazine/pistolm9mm + name = "pistol magazine (9mm)" + icon_state = "9x19p-8" + ammo_type = /obj/item/ammo_casing/c9mm + caliber = "9mm" + max_ammo = 15 + +/obj/item/ammo_box/magazine/pistolm9mm/update_icon() + ..() + icon_state = "9x19p-[ammo_count() ? "8" : "0"]" + /obj/item/ammo_box/magazine/smgm45 name = "SMG magazine (.45)" icon_state = "c20r45" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c45" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 20 @@ -210,7 +278,7 @@ /obj/item/ammo_box/magazine/tommygunm45 name = "drum magazine (.45)" icon_state = "drum45" - ammo_type = "/obj/item/ammo_casing/c45" + ammo_type = /obj/item/ammo_casing/c45 caliber = ".45" max_ammo = 50 @@ -218,7 +286,7 @@ name = "handgun magazine (.50ae)" icon_state = "50ae" origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a50" + ammo_type = /obj/item/ammo_casing/a50 caliber = ".50" max_ammo = 7 multiple_sprites = 1 @@ -226,7 +294,7 @@ /obj/item/ammo_box/magazine/m75 name = "specialized magazine (.75)" icon_state = "75" - ammo_type = "/obj/item/ammo_casing/caseless/a75" + ammo_type = /obj/item/ammo_casing/caseless/a75 caliber = "75" multiple_sprites = 2 max_ammo = 8 @@ -235,50 +303,16 @@ name = "toploader magazine (5.56mm)" icon_state = "5.56m" origin_tech = "combat=5;syndicate=1" - ammo_type = "/obj/item/ammo_casing/a556" + ammo_type = /obj/item/ammo_casing/a556 caliber = "a556" max_ammo = 30 multiple_sprites = 2 -/obj/item/ammo_box/magazine/m762 - name = "box magazine (7.62mm)" - icon_state = "a762" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a762" - caliber = "a762" - max_ammo = 50 - -/obj/item/ammo_box/magazine/m762/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),10)]" - -/obj/item/ammo_box/magazine/m762/buckshot - name = "box magazine (buckshot)" - icon_state = "b762" - caliber = "shotgun" - ammo_type ="/obj/item/ammo_casing/shotgun/buckshot" - max_ammo = 300 // Bluespace! - -/obj/item/ammo_box/magazine/m762/buckshot/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),60)]" - -/obj/item/ammo_box/magazine/m762/he // I am not a good person. - name = "box magazine (40mm high explosive)" - icon_state = "g762" - caliber = "40mm" - ammo_type ="/obj/item/ammo_casing/a40mm" - max_ammo = 25 - -/obj/item/ammo_box/magazine/m762/he/update_icon() - ..() - icon_state = "[initial(icon_state)]-[round(ammo_count(),5)]" - - /obj/item/ammo_box/magazine/m12g name = "shotgun magazine (12g slugs)" + desc = "A drum magazine." icon_state = "m12gb" - ammo_type = "/obj/item/ammo_casing/shotgun" + ammo_type = /obj/item/ammo_casing/shotgun origin_tech = "combat=3;syndicate=1" caliber = "shotgun" max_ammo = 8 @@ -290,36 +324,45 @@ /obj/item/ammo_box/magazine/m12g/buckshot name = "shotgun magazine (12g buckshot slugs)" icon_state = "m12gb" - ammo_type = "/obj/item/ammo_casing/shotgun/buckshot" + ammo_type = /obj/item/ammo_casing/shotgun/buckshot /obj/item/ammo_box/magazine/m12g/stun name = "shotgun magazine (12g taser slugs)" icon_state = "m12gs" - ammo_type = "/obj/item/ammo_casing/shotgun/stunslug" + ammo_type = /obj/item/ammo_casing/shotgun/stunslug /obj/item/ammo_box/magazine/m12g/dragon name = "shotgun magazine (12g dragon's breath)" icon_state = "m12gf" - ammo_type = "/obj/item/ammo_casing/shotgun/incendiary/dragonsbreath" + ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath + +/obj/item/ammo_box/magazine/m12g/bioterror + name = "shotgun magazine (12g bioterror)" + icon_state = "m12gt" + ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror + +/obj/item/ammo_box/magazine/m12g/breach + name = "shotgun magazine (12g breacher slugs)" + icon_state = "m12gbc" + ammo_type = /obj/item/ammo_casing/shotgun/breaching -//FOAM DARTS /obj/item/ammo_box/magazine/toy name = "foam force META magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart caliber = "foam_force" /obj/item/ammo_box/magazine/toy/smg name = "foam force SMG magazine" icon_state = "smg9mm-30" - max_ammo = 30 + max_ammo = 20 /obj/item/ammo_box/magazine/toy/smg/update_icon() ..() - icon_state = "smg9mm-[round(ammo_count(),6)]" + icon_state = "smg9mm-[round(ammo_count(),5)]" /obj/item/ammo_box/magazine/toy/smg/riot - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot /obj/item/ammo_box/magazine/toy/pistol name = "foam force pistol magazine" @@ -328,11 +371,11 @@ multiple_sprites = 2 /obj/item/ammo_box/magazine/toy/pistol/riot - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot /obj/item/ammo_box/magazine/toy/smgm45 name = "donksoft SMG magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 20 /obj/item/ammo_box/magazine/toy/smgm45/update_icon() @@ -341,7 +384,7 @@ /obj/item/ammo_box/magazine/toy/m762 name = "donksoft box magazine" - ammo_type = "/obj/item/ammo_casing/caseless/foam_dart/riot" + ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot max_ammo = 50 /obj/item/ammo_box/magazine/toy/m762/update_icon() diff --git a/code/modules/projectiles/ammunition/special.dm b/code/modules/projectiles/ammunition/special.dm new file mode 100644 index 00000000000..d17d65e9fc8 --- /dev/null +++ b/code/modules/projectiles/ammunition/special.dm @@ -0,0 +1,49 @@ +/obj/item/ammo_casing/magic + name = "magic casing" + desc = "I didn't even know magic needed ammo..." + projectile_type = /obj/item/projectile/magic + +/obj/item/ammo_casing/magic/change + projectile_type = /obj/item/projectile/magic/change + +/obj/item/ammo_casing/magic/animate + projectile_type = /obj/item/projectile/magic/animate + +/obj/item/ammo_casing/magic/heal + projectile_type = /obj/item/projectile/magic/resurrection + +/obj/item/ammo_casing/magic/death + projectile_type = /obj/item/projectile/magic/death + +/obj/item/ammo_casing/magic/teleport + projectile_type = /obj/item/projectile/magic/teleport + +/obj/item/ammo_casing/magic/door + projectile_type = /obj/item/projectile/magic/door + +/obj/item/ammo_casing/magic/fireball + projectile_type = /obj/item/projectile/magic/fireball + +/obj/item/ammo_casing/magic/chaos + projectile_type = /obj/item/projectile/magic + +/obj/item/ammo_casing/magic/chaos/newshot() + projectile_type = pick(typesof(/obj/item/projectile/magic)) + ..() + +/obj/item/ammo_casing/magic/honk + projectile_type = /obj/item/projectile/bullet/honker + +/obj/item/ammo_casing/forcebolt + projectile_type = /obj/item/projectile/forcebolt + +/obj/item/ammo_casing/syringegun + name = "syringe gun spring" + desc = "A high-power spring that throws syringes." + projectile_type = null + +/obj/item/ammo_casing/energy/c3dbullet + projectile_type = /obj/item/projectile/bullet/midbullet3 + select_name = "spraydown" + fire_sound = 'sound/weapons/gunshot_smg.ogg' + e_cost = 200 diff --git a/code/modules/projectiles/firing.dm b/code/modules/projectiles/firing.dm new file mode 100644 index 00000000000..2a75004f223 --- /dev/null +++ b/code/modules/projectiles/firing.dm @@ -0,0 +1,95 @@ +/obj/item/ammo_casing/proc/fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params, distro, quiet, zone_override = "", spread) + distro += variance + for (var/i = max(1, pellets), i > 0, i--) + var/targloc = get_turf(target) + ready_proj(target, user, quiet, zone_override) + if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now... + if(randomspread) + spread = round((rand() - 0.5) * distro) + else //Smart spread + spread = round((i / pellets - 0.5) * distro) + if(!throw_proj(target, targloc, user, params, spread)) + return 0 + if(i > 1) + newshot() + if(click_cooldown_override) + user.changeNext_move(click_cooldown_override) + else + user.changeNext_move(CLICK_CD_RANGE) + user.newtonian_move(get_dir(target, user)) + update_icon() + return 1 + +/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if (!BB) + return + BB.original = target + BB.firer = user + if (zone_override) + BB.def_zone = zone_override + else + BB.def_zone = user.zone_sel.selecting + BB.suppressed = quiet + + if(reagents && BB.reagents) + reagents.trans_to(BB, reagents.total_volume) //For chemical darts/bullets + qdel(reagents) + +/obj/item/ammo_casing/proc/throw_proj(atom/target, turf/targloc, mob/living/user, params, spread) + var/turf/curloc = get_turf(user) + if (!istype(targloc) || !istype(curloc) || !BB) + return 0 + BB.ammo_casing = src + if(targloc == curloc) + if(target) //if the target is right on our location we go straight to bullet_act() + target.bullet_act(BB, BB.def_zone) + qdel(BB) + BB = null + return 1 + + BB.preparePixelProjectile(target, targloc, user, params, spread) + if(BB) + BB.fire() + BB = null + return 1 + +/obj/item/ammo_casing/proc/spread(turf/target, turf/current, distro) + var/dx = abs(target.x - current.x) + var/dy = abs(target.y - current.y) + return locate(target.x + round(gaussian(0, distro) * (dy+2)/8, 1), target.y + round(gaussian(0, distro) * (dx+2)/8, 1), target.z) + +/obj/item/projectile/proc/preparePixelProjectile(atom/target, var/turf/targloc, mob/living/user, params, spread) + var/turf/curloc = get_turf(user) + loc = get_turf(user) + starting = get_turf(user) + current = curloc + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x + + if(params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + p_x = text2num(mouse_control["icon-x"]) + if(mouse_control["icon-y"]) + p_y = text2num(mouse_control["icon-y"]) + if(mouse_control["screen-loc"]) + //Split screen-loc up into X+Pixel_X and Y+Pixel_Y + var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") + + //Split X+Pixel_X up into list(X, Pixel_X) + var/list/screen_loc_X = splittext(screen_loc_params[1],":") + + //Split Y+Pixel_Y up into list(Y, Pixel_Y) + var/list/screen_loc_Y = splittext(screen_loc_params[2],":") + var/x = text2num(screen_loc_X[1]) * world.icon_size + text2num(screen_loc_X[2]) - world.icon_size + (user.client ? user.client.pixel_x : 0) + var/y = text2num(screen_loc_Y[1]) * world.icon_size + text2num(screen_loc_Y[2]) - world.icon_size + (user.client ? user.client.pixel_y : 0) + + //Calculate the "resolution" of screen based on client's view and world's icon size. This will work if the user can view more tiles than average. + var/screenview = (user.client.view * 2 + 1) * world.icon_size //Refer to http://www.byond.com/docs/ref/info.html#/client/var/view for mad maths + + var/ox = round(screenview/2) //"origin" x + var/oy = round(screenview/2) //"origin" y + var/angle = Atan2(y - oy, x - ox) + Angle = angle + if(spread) + Angle += spread diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index cb4f21d2497..29faec1ac97 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,54 +1,59 @@ - #define SAWN_INTACT 0 - #define SAWN_OFF 1 - #define SAWN_SAWING -1 - /obj/item/weapon/gun name = "gun" - desc = "Its a gun. It's pretty terrible, though." - icon = 'icons/obj/gun.dmi' + desc = "It's a gun. It's pretty terrible, though." + icon = 'icons/obj/guns/projectile.dmi' icon_state = "detective" item_state = "gun" - lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' - righthand_file = 'icons/mob/inhands/guns_righthand.dmi' flags = CONDUCT slot_flags = SLOT_BELT materials = list(MAT_METAL=2000) - w_class = 3.0 + w_class = 3 throwforce = 5 - throw_speed = 4 + throw_speed = 3 throw_range = 5 - force = 5.0 + force = 5 origin_tech = "combat=1" needs_permit = 1 attack_verb = list("struck", "hit", "bashed") - var/fire_sound = 'sound/weapons/Gunshot.ogg' - var/obj/item/projectile/in_chamber = null - var/silenced = 0 - var/ghettomodded = 0 - var/recoil = 0 + var/fire_sound = "gunshot" + var/fire_sound_text = "gunshot" //the fire sound that shows in chat messages: laser blast, gunshot, etc. + var/suppressed = 0 //whether or not a message is displayed when fired var/can_suppress = 0 var/can_unsuppress = 1 + var/recoil = 0 //boom boom shake the room var/clumsy_check = 1 - var/sawn_desc = null + var/obj/item/ammo_casing/chambered = null + var/trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers + var/sawn_desc = null //description change if weapon is sawn-off var/sawn_state = SAWN_INTACT - var/obj/item/ammo_casing/chambered = null // The round (not bullet) that is in the chamber. THIS MISPLACED ITEM BROUGHT TO YOU BY HACKY BUCKSHOT. - var/tmp/list/mob/living/target //List of who yer targeting. - var/tmp/lock_time = -100 - var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.> - var/automatic = 0 //Used to determine if you can target multiple people. - var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person. - var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them. - var/firerate = 1 // 0 for one bullet after tarrget moves and aim is lowered, - //1 for keep shooting until aim is lowered - var/fire_delay = 0 - var/last_fired = 0 + var/burst_size = 1 //how large a burst is + var/fire_delay = 0 //rate of fire for burst firing and semi auto + var/firing_burst = 0 //Prevent the weapon from firing again while already firing + var/semicd = 0 //cooldown handler + var/weapon_weight = WEAPON_LIGHT + var/list/restricted_species + + var/spread = 0 + var/randomspread = 1 + + var/unique_rename = 0 //allows renaming with a pen + var/unique_reskin = 0 //allows one-time reskinning + var/current_skin = null //the skin choice if we had a reskin + var/list/options = list() + + lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi' + righthand_file = 'icons/mob/inhands/guns_righthand.dmi' + var/obj/item/device/flashlight/F = null var/can_flashlight = 0 - var/heavy_weapon = 0 - var/randomspread = 0 - var/burst_size = 1 + var/list/upgrades = list() + + var/ammo_x_offset = 0 //used for positioning ammo count overlay on sprite + var/ammo_y_offset = 0 + var/flight_x_offset = 0 + var/flight_y_offset = 0 //Zooming var/zoomable = FALSE //whether the gun generates a Zoom action on creation @@ -56,312 +61,200 @@ var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect) var/datum/action/toggle_scope_zoom/azoom - proc/ready_to_fire() - if(world.time >= last_fired + fire_delay) - last_fired = world.time - return 1 - else - return 0 - - proc/process_chambered() - return 0 - - - proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver. - if(!M.IsAdvancedToolUser()) - return 0 - return 1 - - - proc/shoot_with_empty_chamber(mob/living/user as mob|obj) - to_chat(user, "*click*") - playsound(user, 'sound/weapons/emptyclick.ogg', 40, 1) - return - - emp_act(severity) - for(var/obj/O in contents) - O.emp_act(severity) - - proc/prepare_shot(var/obj/item/projectile/proj) //Transfer properties from the gun to the bullet - proj.shot_from = src - proj.silenced = silenced - return - /obj/item/weapon/gun/New() + ..() + if(F) + verbs += /obj/item/weapon/gun/proc/toggle_gunlight build_zooming() + +/obj/item/weapon/gun/examine(mob/user) ..() + if(unique_reskin && !current_skin) + to_chat(user, "Alt-click it to reskin it.") + if(unique_rename) + to_chat(user, "Use a pen on it to rename it.") -/obj/item/weapon/gun/pickup(mob/user) +/obj/item/weapon/gun/proc/process_chamber() + return 0 - if(azoom) - azoom.Grant(user) - ..() - -/obj/item/weapon/gun/dropped(mob/user) - - zoom(user,FALSE) - if(azoom) - azoom.Remove(user) - ..() - -/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) - if(flag) return //we're placing gun on a table or in backpack - if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? - Fire(A,user,params) //Otherwise, fire normally. - -/obj/item/weapon/gun/proc/isHandgun() +//check if there's enough ammo/energy/whatever to shoot one time +//i.e if clicking would make it shoot +/obj/item/weapon/gun/proc/can_shoot() return 1 -/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this +/obj/item/weapon/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) + to_chat(user, "*click*") + playsound(user, 'sound/weapons/empty.ogg', 100, 1) + +/obj/item/weapon/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) + if(recoil) + shake_camera(user, recoil + 1, recoil) + + if(suppressed) + playsound(user, fire_sound, 10, 1) + else + playsound(user, fire_sound, 50, 1) + if(!message) + return + if(pointblank) + user.visible_message("[user] fires [src] point blank at [pbtarget]!", "You fire [src] point blank at [pbtarget]!", "You hear \a [fire_sound_text]!") + else + user.visible_message("[user] fires [src]!", "You fire [src]!", "You hear \a [fire_sound_text]!") + + if(weapon_weight >= WEAPON_MEDIUM) + if(user.get_inactive_hand()) + if(prob(15)) + if(user.drop_item()) + user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") + +/obj/item/weapon/gun/emp_act(severity) + for(var/obj/O in contents) + O.emp_act(severity) + +/obj/item/weapon/gun/afterattack(atom/target, mob/living/user, flag, params) + if(firing_burst) + return + if(flag) //It's adjacent, is the user, or is on the user's person + if(target in user.contents) //can't shoot stuff inside us. + return + if(!ismob(target) || user.a_intent == "harm") //melee attack + return + if(target == user && user.zone_sel.selecting != "mouth") //so we can't shoot ourselves (unless mouth selected) + return + + if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can. + var/mob/living/L = user + if(!can_trigger_gun(L)) + return + + if(!can_shoot()) //Just because you can pull the trigger doesn't mean it can't shoot. + shoot_with_empty_chamber(user) + return + + if(flag) + if(user.zone_sel.selecting == "mouth") + handle_suicide(user, target, params) + return + + //Exclude lasertag guns from the CLUMSY check. if(clumsy_check) - if(istype(user, /mob/living)) - var/mob/living/M = user - if ((CLUMSY in M.mutations) && prob(50)) - to_chat(M, "[src] blows up in your face.") - M.take_organ_damage(0,20) - M.drop_item() - qdel(src) + if(istype(user)) + if((CLUMSY in user.mutations) && prob(40)) + to_chat(user, "You shoot yourself in the foot with \the [src]!") + var/shot_leg = pick("l_foot", "r_foot") + process_fire(user, user, 0, params, zone_override = shot_leg) + user.drop_item() return - if (!user.IsAdvancedToolUser() || istype(user, /mob/living/simple_animal/diona)) - to_chat(user, "You don't have the dexterity to do this!") + if(weapon_weight == WEAPON_HEAVY && user.get_inactive_hand()) + to_chat(user, "You need both hands free to fire \the [src]!") return - if(istype(user, /mob/living)) - var/mob/living/M = user - if (HULK in M.mutations) - to_chat(M, "Your meaty finger is much too large for the trigger guard!") - return - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.species.flags & NOGUNS) - to_chat(user, "Your fingers don't fit in the trigger guard!") - return - if(H.martial_art && H.martial_art.name == "The Sleeping Carp") //great dishonor to famiry - to_chat(user, "Use of ranged weaponry would bring dishonor to the clan.") - return + process_fire(target,user,1,params) + +/obj/item/weapon/gun/proc/can_trigger_gun(var/mob/living/user) + if(!user.can_use_guns(src)) + return 0 + if(restricted_species && restricted_species.len && !(user.get_species() in restricted_species)) + to_chat(user, "[src] is incompatible with your biology!") + return 0 + return 1 + +obj/item/weapon/gun/proc/newshot(params) + return + +/obj/item/weapon/gun/proc/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) add_fingerprint(user) - if(!special_check(user)) + if(semicd) return - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - to_chat(user, "[src] is not ready to fire again!") - return - - if(heavy_weapon) + if(weapon_weight) if(user.get_inactive_hand()) recoil = 4 //one-handed kick else recoil = initial(recoil) - if (istype(in_chamber, /obj/item/projectile/bullet/blank)) // A hacky way of making blank shotgun shells work again. Honk. - in_chamber.delete() - in_chamber = null - return - - user.changeNext_move(CLICK_CD_RANGE) - - var/spread = 0 - var/turf/targloc = get_turf(target) - for(var/f = 1 to burst_size) - if(!process_chambered()) //CHECK - return click_empty(user) - - if(chambered) - for (var/i = max(1, chambered.pellets), i > 0, i--) //Previous way of doing it fucked up math for spreading. This way, even the first projectile is part of the spread code. - if(i != max(1, chambered.pellets)) //Have we fired the initial chambered bullet yet? - in_chamber = new chambered.projectile_type() - ready_projectile(target, user) - prepare_shot(in_chamber) - if(chambered.deviation) - if(randomspread) //Random spread - spread = (rand() - 0.5) * chambered.deviation - else //Smart spread - spread = (i / chambered.pellets - 0.5) * chambered.deviation - if(!process_projectile(targloc, user, params, spread)) - return 0 - else - ready_projectile(target, user) - prepare_shot(in_chamber) - if(!process_projectile(targloc, user, params, spread)) - return 0 - - if(recoil) - spawn() - shake_camera(user, recoil + 1, recoil) - - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(f == 1) // Only print this once - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - - if(heavy_weapon) - if(user.get_inactive_hand()) - if(prob(15)) - user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!") - user.drop_item() + if(burst_size > 1) + firing_burst = 1 + for(var/i = 1 to burst_size) + if(!user) + break + if(!issilicon(user)) + if( i>1 && !(src in get_both_hands(user))) //for burst firing break - - user.newtonian_move(get_dir(target, user)) + if(chambered) + var/sprd = 0 + if(randomspread) + sprd = round((rand() - 0.5) * spread) + else + sprd = round((i / burst_size - 0.5) * spread) + if(!chambered.fire(target, user, params, ,suppressed, zone_override, sprd)) + shoot_with_empty_chamber(user) + break + else + if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot + shoot_live_shot(user, 1, target, message) + else + shoot_live_shot(user, 0, target, message) + else + shoot_with_empty_chamber(user) + break + process_chamber() + update_icon() + sleep(fire_delay) + firing_burst = 0 + else + if(chambered) + if(!chambered.fire(target, user, params, , suppressed, zone_override, spread)) + shoot_with_empty_chamber(user) + return + else + if(get_dist(user, target) <= 1) //Making sure whether the target is in vicinity for the pointblank shot + shoot_live_shot(user, 1, target, message) + else + shoot_live_shot(user, 0, target, message) + else + shoot_with_empty_chamber(user) + return + process_chamber() update_icon() + semicd = 1 + spawn(fire_delay) + semicd = 0 + + if(user) if(user.hand) user.update_inv_l_hand() else user.update_inv_r_hand() - sleep(fire_delay) + feedback_add_details("gun_fired","[type]") -/obj/item/weapon/gun/proc/ready_projectile(atom/target as mob|obj|turf, mob/living/user) - in_chamber.firer = user - in_chamber.def_zone = user.zone_sel.selecting - in_chamber.original = target - return - -/obj/item/weapon/gun/proc/process_projectile(var/turf/targloc, mob/living/user as mob|obj, params, spread) - var/turf/curloc = user.loc - if (!istype(targloc) || !istype(curloc) || !in_chamber) - return 0 - if(targloc == curloc) //Fire the projectile - user.bullet_act(in_chamber) - del(in_chamber) - update_icon() - return 1 - - in_chamber.loc = get_turf(user) - in_chamber.starting = get_turf(user) - in_chamber.current = curloc - in_chamber.OnFired() - in_chamber.yo = targloc.y - curloc.y - in_chamber.xo = targloc.x - curloc.x - if(params) - var/list/mouse_control = params2list(params) - if(mouse_control["icon-x"]) - in_chamber.p_x = text2num(mouse_control["icon-x"]) - if(mouse_control["icon-y"]) - in_chamber.p_y = text2num(mouse_control["icon-y"]) - if(mouse_control["screen-loc"]) - //Split screen-loc up into X+Pixel_X and Y+Pixel_Y - var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",") - - //Split X+Pixel_X up into list(X, Pixel_X) - var/list/screen_loc_X = splittext(screen_loc_params[1],":") - - //Split Y+Pixel_Y up into list(Y, Pixel_Y) - var/list/screen_loc_Y = splittext(screen_loc_params[2],":") - - var/x = text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32 - var/y = text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32 - var/ox = round(480/2) //"origin" x - Basically center of the screen. This is a bad way of doing it because if you are able to view MORE than 17 tiles at a time your aim will get fucked. - var/oy = round(480/2) //"origin" y - Basically center of the screen. - - var/angle = Atan2(y - oy, x - ox) - - in_chamber.Angle = angle - - if(istype(user, /mob/living/carbon)) //Increase spread based on shock - var/mob/living/carbon/mob = user - if(mob.shock_stage > 120) - spread += rand(-5,5) - else if(mob.shock_stage > 70) - spread += rand(-2,2) - - if(spread) - in_chamber.Angle += spread - if(in_chamber) - in_chamber.process() - in_chamber = null - return 1 - -/obj/item/weapon/gun/proc/can_fire() - return process_chambered() - -/obj/item/weapon/gun/proc/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return in_chamber.check_fire(target,user) - -/obj/item/weapon/gun/proc/click_empty(mob/user = null) - if (user) - user.visible_message("*click click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) +/obj/item/weapon/gun/attack(mob/M as mob, mob/user) + if(user.a_intent == "harm") //Flogging + ..() else - src.visible_message("*click click*") - playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) + return -/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - //Suicide handling. - if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot) - mouthshoot = 1 - M.visible_message(" [user] sticks their gun in their mouth, ready to pull the trigger...") - if(!do_after(user, 40, target = M)) - M.visible_message(" [user] decided life was worth living") - mouthshoot = 0 - return - if (process_chambered()) - user.visible_message("[user] pulls the trigger.") - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(istype(in_chamber, /obj/item/projectile/lasertag) || istype(in_chamber, /obj/item/projectile/bullet/reusable/foam_dart)) - user.show_message("You feel rather silly, trying to commit suicide with a toy.") - mouthshoot = 0 - return - in_chamber.on_hit(M) - if (in_chamber.damage_type != STAMINA) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) - user.death() - else - to_chat(user, "Ow...") - user.apply_effect(110,STAMINA,0) - del(in_chamber) - mouthshoot = 0 - return - else - click_empty(user) - mouthshoot = 0 - return - - if (src.process_chambered()) - //Point blank shooting if on harm intent or target we were targeting. - if(user.a_intent == I_HARM) - user.visible_message("\red \The [user] fires \the [src] point blank at [M]!") - if(istype(in_chamber)) in_chamber.damage *= 1.3 - Fire(M,user,0,0,1) - return - else if(target && M in target) - Fire(M,user,0,0,1) ///Otherwise, shoot! - return - else - return ..() //Pistolwhippin' - - -/obj/item/weapon/gun/attackby(var/obj/item/A as obj, mob/user as mob, params) - if(istype(A, /obj/item/device/flashlight/seclite)) - var/obj/item/device/flashlight/seclite/S = A +/obj/item/weapon/gun/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/device/flashlight/seclite)) + var/obj/item/device/flashlight/seclite/S = I if(can_flashlight) if(!F) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") + if(!user.unEquip(I)) return - user.drop_item() to_chat(user, "You click [S] into place on [src].") if(S.on) set_light(0) F = S - A.loc = src + I.loc = src update_icon() update_gunlight(user) verbs += /obj/item/weapon/gun/proc/toggle_gunlight - if(istype(A, /obj/item/weapon/screwdriver)) - if(F) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") - return + + if(istype(I, /obj/item/weapon/screwdriver)) + if(F && can_flashlight) for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") F = null @@ -370,8 +263,11 @@ S.update_brightness(user) update_icon() verbs -= /obj/item/weapon/gun/proc/toggle_gunlight + + if(unique_rename) + if(istype(I, /obj/item/weapon/pen)) + rename_gun(user) ..() - return /obj/item/weapon/gun/proc/toggle_gunlight() set name = "Toggle Gunlight" @@ -383,15 +279,14 @@ var/mob/living/carbon/human/user = usr if(!isturf(user.loc)) - to_chat(user, "You cannot turn the light on while in this [user.loc].") + to_chat(user, "You cannot turn the light on while in this [user.loc]!") F.on = !F.on to_chat(user, "You toggle the gunlight [F.on ? "on":"off"].") playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_gunlight(user) - return -/obj/item/weapon/gun/proc/update_gunlight(var/mob/user = null) +/obj/item/weapon/gun/proc/update_gunlight(mob/user = null) if(F) if(F.on) set_light(F.brightness_on) @@ -400,7 +295,80 @@ update_icon() else set_light(0) + +/obj/item/weapon/gun/pickup(mob/user) + ..() + if(azoom) + azoom.Grant(user) + +/obj/item/weapon/gun/dropped(mob/user) + ..() + zoom(user,FALSE) + if(azoom) + azoom.Remove(user) + +/obj/item/weapon/gun/AltClick(mob/user) + ..() + if(user.incapacitated()) + to_chat(user, "You can't do that right now!") return + if(unique_reskin && !current_skin && loc == user) + reskin_gun(user) + +/obj/item/weapon/gun/proc/reskin_gun(mob/M) + var/choice = input(M,"Warning, you can only reskin your weapon once!","Reskin Gun") in options + + if(src && choice && !current_skin && !M.incapacitated() && in_range(M,src)) + if(options[choice] == null) + return + current_skin = options[choice] + to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.") + update_icon() + +/obj/item/weapon/gun/proc/rename_gun(mob/M) + var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src) && !M.restrained() && M.canmove) + name = input + to_chat(M, "You name the gun [input]. Say hello to your new friend.") + return + +/obj/item/weapon/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params) + if(!ishuman(user) || !ishuman(target)) + return + + if(semicd) + return + + if(user == target) + target.visible_message("[user] sticks [src] in their mouth, ready to pull the trigger...", \ + "You stick [src] in your mouth, ready to pull the trigger...") + else + target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \ + "[user] points [src] at your head, ready to pull the trigger...") + + semicd = 1 + + if(!do_mob(user, target, 120) || user.zone_sel.selecting != "mouth") + if(user) + if(user == target) + user.visible_message("[user] decided life was worth living.") + else if(target && target.Adjacent(user)) + target.visible_message("[user] has decided to spare [target]'s life.", "[user] has decided to spare your life!") + semicd = 0 + return + + semicd = 0 + + target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!") + + if(chambered && chambered.BB) + chambered.BB.damage *= 5 + + process_fire(target, user, 1, params) + +/obj/item/weapon/gun/proc/isHandgun() + return 1 ///////////// // ZOOMING // @@ -424,8 +392,6 @@ gun.zoom(L, FALSE) ..() - - /obj/item/weapon/gun/proc/zoom(mob/living/user, forced_zoom) if(!user || !user.client) return diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index eeb775be84a..de217a9715d 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -1,108 +1,100 @@ -//Vox pinning weapon. -/obj/item/weapon/gun/launcher/spikethrower - - name = "Vox spike thrower" +/obj/item/weapon/gun/projectile/automatic/spikethrower + name = "\improper Vox spike thrower" desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive." - - var/last_regen = 0 - var/spike_gen_time = 100 - var/max_spikes = 3 - var/spikes = 3 - release_force = 30 - icon = 'icons/obj/gun.dmi' - icon_state = "spikethrower3" + icon_state = "spikethrower" item_state = "spikethrower" + w_class = 2 fire_sound_text = "a strange noise" - fire_sound = 'sound/weapons/bladeslice.ogg' + mag_type = /obj/item/ammo_box/magazine/internal/spikethrower + burst_size = 2 + fire_delay = 3 + can_suppress = 0 + var/charge_tick = 0 + var/charge_delay = 15 + restricted_species = list("Vox", "Vox Armalis") -/obj/item/weapon/gun/launcher/spikethrower/New() +/obj/item/weapon/gun/projectile/automatic/spikethrower/New() ..() processing_objects.Add(src) - last_regen = world.time -/obj/item/weapon/gun/launcher/spikethrower/Destroy() +/obj/item/weapon/gun/projectile/automatic/spikethrower/Destroy() processing_objects.Remove(src) return ..() -/obj/item/weapon/gun/launcher/spikethrower/process() - - if(spikes < max_spikes && world.time > last_regen + spike_gen_time) - spikes++ - last_regen = world.time - update_icon() - -/obj/item/weapon/gun/launcher/spikethrower/examine(mob/user) - ..(user) - to_chat(user, "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining.") - -/obj/item/weapon/gun/launcher/spikethrower/update_icon() - icon_state = "spikethrower[spikes]" - -/obj/item/weapon/gun/launcher/spikethrower/emp_act(severity) +/obj/item/weapon/gun/projectile/automatic/spikethrower/update_icon() return -/obj/item/weapon/gun/launcher/spikethrower/special_check(user) - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") - to_chat(user, "\red \The [src] does not respond to you!") - return 0 +/obj/item/weapon/gun/projectile/automatic/spikethrower/process() + charge_tick++ + if(charge_tick < charge_delay || !magazine) + return + charge_tick = 0 + var/obj/item/ammo_casing/caseless/spike/S = new(get_turf(src)) + magazine.give_round(S) return 1 -/obj/item/weapon/gun/launcher/spikethrower/update_release_force() +/obj/item/weapon/gun/projectile/automatic/spikethrower/attack_self() return -/obj/item/weapon/gun/launcher/spikethrower/chamber_round() - if(in_chamber) return 1 - if(spikes < 1) return 0 +/obj/item/weapon/gun/projectile/automatic/spikethrower/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() - spikes-- - in_chamber = new /obj/item/weapon/spike(src) - return 1 +/obj/item/ammo_box/magazine/internal/spikethrower + name = "\improper Vox spikethrower internal magazine" + ammo_type = /obj/item/ammo_casing/caseless/spike + caliber = "spike" + max_ammo = 10 -/obj/item/weapon/gun/launcher/spikethrower/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(..()) update_icon() +/obj/item/ammo_casing/caseless/spike + name = "alloy spike" + desc = "A broadhead spike made out of a weird silvery metal." + projectile_type = /obj/item/projectile/bullet/spike + sharp = 1 + edge = 0 + throwforce = 5 + w_class = 3 + caliber = "spike" + icon_state = "bolt" + fire_sound = 'sound/weapons/bladeslice.ogg' + +/obj/item/projectile/bullet/spike + name = "alloy spike" + desc = "It's about a foot of weird silvery metal with a wicked point." + damage = 25 + stun = 1 + armour_penetration = 30 + icon_state = "magspear" + +/obj/item/projectile/bullet/spike/on_hit(atom/target, blocked = 0) + if((blocked != 100) && istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + H.drip(500) + ..() //This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. /obj/item/weapon/gun/energy/noisecannon - name = "alien heavy cannon" desc = "It's some kind of enormous alien weapon, as long as a man is tall." - - icon = 'icons/obj/gun.dmi' //Actual on-sprite is handled by icon_override. icon_state = "noisecannon" item_state = "noisecannon" recoil = 1 - force = 10 - projectile_type = "/obj/item/projectile/energy/sonic" - cell_type = "/obj/item/weapon/stock_parts/cell/super" - fire_delay = 40 - fire_sound = 'sound/effects/basscannon.ogg' - - var/mode = 1 - -/obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob) - if(loc != user) - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.species.name == "Vox Armalis") - ..() - return - to_chat(user, "\red \The [src] is far too large for you to pick up.") - return - -/obj/item/weapon/gun/energy/noisecannon/process_chambered() //Does not have ammo. - in_chamber = new projectile_type(src) - return 1 + ammo_type = list(/obj/item/ammo_casing/energy/sonic) + cell_type = /obj/item/weapon/stock_parts/cell/super + restricted_species = list("Vox Armalis") /obj/item/weapon/gun/energy/noisecannon/update_icon() return +//Casing +/obj/item/ammo_casing/energy/sonic + projectile_type = /obj/item/projectile/energy/sonic + fire_sound = 'sound/effects/basscannon.ogg' + delay = 40 + //Projectile. /obj/item/projectile/energy/sonic name = "distortion" - icon = 'icons/obj/machines/particle_accelerator.dmi' icon_state = "particle" damage = 60 damage_type = BRUTE @@ -112,7 +104,3 @@ embed = 0 weaken = 5 stun = 5 - -/obj/item/projectile/energy/sonic/proc/split() - //TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf. - return \ No newline at end of file diff --git a/code/modules/reagents/dartgun.dm b/code/modules/projectiles/guns/dartgun.dm similarity index 94% rename from code/modules/reagents/dartgun.dm rename to code/modules/projectiles/guns/dartgun.dm index 4fb705dbcf9..2e55b19b4a9 100644 --- a/code/modules/reagents/dartgun.dm +++ b/code/modules/projectiles/guns/dartgun.dm @@ -33,9 +33,8 @@ var/list/starting_chems = null /obj/item/weapon/gun/dartgun/update_icon() - if(!cartridge) - icon_state = "dartgun-empty" + icon_state = "dartgun-e" return 1 if(!cartridge.darts) @@ -47,7 +46,6 @@ return 1 /obj/item/weapon/gun/dartgun/New() - ..() if(starting_chems) for(var/chem in starting_chems) @@ -104,7 +102,7 @@ to_chat(user, "[src] is empty.") @@ -305,7 +301,7 @@ anchored = 1 density = 0 - New() - var/datum/reagents/R = new/datum/reagents(15) - reagents = R - R.my_atom = src \ No newline at end of file +/obj/effect/syringe_gun_dummy/New() + var/datum/reagents/R = new/datum/reagents(15) + reagents = R + R.my_atom = src diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 8add6a5caf9..76e86d74699 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -2,25 +2,26 @@ icon_state = "energy" name = "energy gun" desc = "A basic energy-based gun." - fire_sound = 'sound/weapons/Taser.ogg' + icon = 'icons/obj/guns/energy.dmi' + fire_sound_text = "laser blast" var/obj/item/weapon/stock_parts/cell/power_supply //What type of power cell this uses - var/charge_cost = 1000 //How much energy is needed to fire. - var/cell_type = "/obj/item/weapon/stock_parts/cell" - var/projectile_type = "/obj/item/projectile/beam" - var/modifystate + var/cell_type = /obj/item/weapon/stock_parts/cell + var/modifystate = 0 + var/list/ammo_type = list(/obj/item/ammo_casing/energy) + var/select = 1 //The state of the select fire switch. Determines from the ammo_type list what kind of shot is fired next. var/can_charge = 1 - - //self-recharging - var/self_recharge = 0 //if set, the weapon will recharge itself + var/charge_sections = 4 + ammo_x_offset = 2 + var/shaded_charge = 0 //if this gun uses a stateful charge bar for more detail + var/selfcharge = 0 var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically - var/recharge_time = 4 var/charge_tick = 0 + var/charge_delay = 4 /obj/item/weapon/gun/energy/emp_act(severity) - if(power_supply) - power_supply.use(round(power_supply.charge / severity)) - update_icon() + power_supply.use(round(power_supply.charge / severity)) + update_icon() /obj/item/weapon/gun/energy/New() ..() @@ -29,39 +30,147 @@ else power_supply = new(src) power_supply.give(power_supply.maxcharge) - if(self_recharge) + var/obj/item/ammo_casing/energy/shot + for (var/i = 1, i <= ammo_type.len, i++) + var/shottype = ammo_type[i] + shot = new shottype(src) + ammo_type[i] = shot + shot = ammo_type[select] + fire_sound = shot.fire_sound + fire_delay = shot.delay + if(selfcharge) processing_objects.Add(src) update_icon() /obj/item/weapon/gun/energy/Destroy() - if(self_recharge) + if(selfcharge) processing_objects.Remove(src) return ..() /obj/item/weapon/gun/energy/process() - if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the cyborg + if(selfcharge) //Every [recharge_time] ticks, recharge a shot for the cyborg charge_tick++ - if(charge_tick < recharge_time) return 0 + if(charge_tick < charge_delay) + return charge_tick = 0 - - if(!power_supply || power_supply.charge >= power_supply.maxcharge) - return 0 // check if we actually need to recharge - + if(!power_supply) + return // check if we actually need to recharge + var/obj/item/ammo_casing/energy/E = ammo_type[select] if(use_external_power) var/obj/item/weapon/stock_parts/cell/external = get_external_power_supply() - if(!external || !external.use(charge_cost/10)) //Take power from the borg... - return 0 //Note, uses /10 because of shitty mods to the cell system - - power_supply.give(charge_cost) //... to recharge the shot + if(!external || !external.use((E.e_cost)/10)) //Take power from the borg... + return //Note, uses /10 because of shitty mods to the cell system + power_supply.give(1000) //... to recharge the shot update_icon() - return 1 + +/obj/item/weapon/gun/energy/attack_self(mob/living/user as mob) + if(ammo_type.len > 1) + select_fire(user) + update_icon() + if(istype(user,/mob/living/carbon/human)) //This has to be here or else if you toggle modes by clicking the gun in hand + var/mob/living/carbon/human/H = user //Otherwise the mob icon doesn't update, blame shitty human update_icons() code + H.update_inv_l_hand() + H.update_inv_r_hand() + +/obj/item/weapon/gun/energy/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) + newshot() //prepare a new shot + ..() + +/obj/item/weapon/gun/energy/can_shoot() + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + return power_supply.charge >= shot.e_cost + +/obj/item/weapon/gun/energy/newshot(params) + if (!ammo_type || !power_supply) + return + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge >= shot.e_cost) //if there's enough power in the power_supply cell... + chambered = shot //...prepare a new shot based on the current ammo type selected + chambered.newshot(params) + return + +/obj/item/weapon/gun/energy/process_chamber() + if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... + var/obj/item/ammo_casing/energy/shot = chambered + power_supply.use(shot.e_cost)//... drain the power_supply cell + chambered = null //either way, released the prepared shot + return + +/obj/item/weapon/gun/energy/proc/select_fire(mob/living/user) + select++ + if (select > ammo_type.len) + select = 1 + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + fire_sound = shot.fire_sound + fire_delay = shot.delay + if (shot.select_name) + to_chat(user, "[src] is now set to [shot.select_name].") + update_icon() + return + +/obj/item/weapon/gun/energy/update_icon() + overlays.Cut() + var/ratio = Ceiling((power_supply.charge / power_supply.maxcharge) * charge_sections) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + var/iconState = "[icon_state]_charge" + var/itemState = null + if(!initial(item_state)) + itemState = icon_state + if (modifystate) + overlays += "[icon_state]_[shot.select_name]" + iconState += "_[shot.select_name]" + if(itemState) + itemState += "[shot.select_name]" + if(power_supply.charge < shot.e_cost) + overlays += "[icon_state]_empty" + else + if(!shaded_charge) + for(var/i = ratio, i >= 1, i--) + overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1)) + else + overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]") + if(F && can_flashlight) + var/iconF = "flight" + if(F.on) + iconF = "flight_on" + overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset) + if(itemState) + itemState += "[ratio]" + item_state = itemState + +/obj/item/weapon/gun/energy/ui_action_click() + toggle_gunlight() + +/obj/item/weapon/gun/energy/suicide_act(mob/user) + if (can_shoot()) + user.visible_message("[user] is putting the barrel of the [name] in \his mouth. It looks like \he's trying to commit suicide.") + sleep(25) + if(user.l_hand == src || user.r_hand == src) + user.visible_message("[user] melts \his face off with the [name]!") + playsound(loc, fire_sound, 50, 1, -1) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + power_supply.use(shot.e_cost) + update_icon() + return(FIRELOSS) + else + user.visible_message("[user] panics and starts choking to death!") + return(OXYLOSS) + else + user.visible_message("[user] is pretending to blow \his brains out with the [name]! It looks like \he's trying to commit suicide!") + playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + return (OXYLOSS) + +/obj/item/weapon/gun/energy/proc/robocharge() + if(isrobot(loc)) + var/mob/living/silicon/robot/R = loc + if(R && R.cell) + var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot + if(R.cell.use(shot.e_cost/10)) //Take power from the borg... //Divided by 10 because cells and charge costs are fucked. + power_supply.give(shot.e_cost) //... to recharge the shot /obj/item/weapon/gun/energy/proc/get_external_power_supply() - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - return R.cell - if(istype(src.loc, /obj/item/rig_module)) - var/obj/item/rig_module/module = src.loc + if(istype(loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = loc if(module.holder && module.holder.wearer) var/mob/living/carbon/human/H = module.holder.wearer if(istype(H) && H.back) @@ -69,29 +178,3 @@ if(istype(suit)) return suit.cell return null - -/obj/item/weapon/gun/energy/process_chambered() - if(in_chamber) return 1 - if(!power_supply) return 0 - if(!power_supply.use(charge_cost)) return 0 - if(!projectile_type) return 0 - in_chamber = new projectile_type(src) - return 1 - -/obj/item/weapon/gun/energy/update_icon() - if(cell_type) - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - if(modifystate) - icon_state = "[modifystate][ratio]" - else - icon_state = "[initial(icon_state)][ratio]" - else - icon_state = "energy0" - overlays.Cut() - if(F) - if(F.on) - overlays += "flight-on" - else - overlays += "flight" - return diff --git a/code/modules/projectiles/guns/energy/advtaser.dm b/code/modules/projectiles/guns/energy/advtaser.dm deleted file mode 100644 index 8601a388f15..00000000000 --- a/code/modules/projectiles/guns/energy/advtaser.dm +++ /dev/null @@ -1,40 +0,0 @@ -/obj/item/weapon/gun/energy/advtaser - name = "hybrid taser" - desc = "A hybrid taser designed to fire both short-range high-power electrodes and long-range disabler beams." - icon_state = "advtaser" - item_state = null //so the human update icon uses the icon_state instead. - cell_type = "/obj/item/weapon/stock_parts/cell" - origin_tech = null - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" - charge_cost = 2000 - modifystate = "advtaserstun" - can_flashlight = 1 - fire_delay = 15 - - var/mode = 0 //0 = stun, 1 = disable - - - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/taser2.ogg' - to_chat(user, "\red [src.name] is now set to Disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "advtaserdisable" - fire_delay = 0 - if(1) - mode = 0 - charge_cost = 2000 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - modifystate = "advtaserstun" - fire_delay = 15 - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() diff --git a/code/modules/projectiles/guns/energy/blueshield.dm b/code/modules/projectiles/guns/energy/blueshield.dm deleted file mode 100644 index 914b92e19a6..00000000000 --- a/code/modules/projectiles/guns/energy/blueshield.dm +++ /dev/null @@ -1,37 +0,0 @@ -/obj/item/weapon/gun/energy/blueshield - name = "advanced stun revolver" - desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers." - icon_state = "bsgun_stun" - item_state = "gun" - modifystate = "bsgun_stun" - force = 7 - fire_sound = 'sound/weapons/gunshot.ogg' - charge_cost = 2000 - projectile_type = "/obj/item/projectile/energy/electrode" - fire_delay = 15 - var/fire_mode = 0 // 0 for taser, 1 for lethals. - -/obj/item/weapon/gun/energy/blueshield/attack_self(mob/living/user as mob) - if(!fire_mode) - fire_mode = 1 - charge_cost = 1000 - fire_delay = 0 - - fire_sound = 'sound/weapons/Laser.ogg' - projectile_type = "/obj/item/projectile/beam" - modifystate = "bsgun_kill" - - to_chat(user, "You adjust [src.name] to the kill setting.") - - else - fire_mode = 0 - charge_cost = 2000 - fire_delay = 15 - - projectile_type = "/obj/item/projectile/energy/electrode" - fire_sound = 'sound/weapons/gunshot.ogg' - modifystate = "bsgun_stun" - - to_chat(user, "You adjust [src.name] to the stun setting.") - - update_icon() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/hos.dm b/code/modules/projectiles/guns/energy/hos.dm deleted file mode 100644 index 6bcb9992c4d..00000000000 --- a/code/modules/projectiles/guns/energy/hos.dm +++ /dev/null @@ -1,45 +0,0 @@ -/obj/item/weapon/gun/energy/hos - name = "head of security's energy gun" - desc = "This is a modern recreation of the captain's antique laser gun. This gun has several unique fire modes, but lacks the ability to recharge over time." - icon_state = "hoslaser" - item_state = null //so the human update icon uses the icon_state instead. - force = 10 - fire_sound = 'sound/weapons/Taser.ogg' - origin_tech = "combat=3;magnets=2" - charge_cost = 2000 - modifystate = "hoslaserstun" - projectile_type = "/obj/item/projectile/energy/electrode" - fire_delay = 15 - var/mode = 2 - - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 1000 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - modifystate = "hoslaserkill" - fire_delay = 0 - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/taser2.ogg' - to_chat(user, "\red [src.name] is now set to disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "hoslaserdisable" - fire_delay = 0 - if(1) - mode = 2 - charge_cost = 2000 - fire_sound = 'sound/weapons/taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - modifystate = "hoslaserstun" - fire_delay = 15 - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 330d9136f17..40356f8a7d9 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -1,59 +1,65 @@ /obj/item/weapon/gun/energy/laser name = "laser gun" - desc = "a basic weapon designed kill with concentrated energy bolts" + desc = "A basic energy-based laser gun that fires concentrated beams of light which pass through glass and thin metal." icon_state = "laser" item_state = "laser" - fire_sound = 'sound/weapons/Laser.ogg' - charge_cost = 760 - w_class = 3.0 + w_class = 3 materials = list(MAT_METAL=2000) origin_tech = "combat=3;magnets=2" - projectile_type = "/obj/item/projectile/beam" + ammo_type = list(/obj/item/ammo_casing/energy/lasergun) + ammo_x_offset = 1 + shaded_charge = 1 /obj/item/weapon/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." - projectile_type = "/obj/item/projectile/practice" + ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 needs_permit = 0 -obj/item/weapon/gun/energy/laser/retro +/obj/item/weapon/gun/energy/laser/retro name ="retro laser gun" icon_state = "retro" - desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." - + desc = "An older model of the basic lasergun, no longer used by Nanotrasen's private security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." + ammo_x_offset = 3 /obj/item/weapon/gun/energy/laser/captain - name = "captain's antique laser gun" + name = "antique laser gun" icon_state = "caplaser" item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 10 origin_tech = null + ammo_x_offset = 3 + selfcharge = 1 - self_recharge = 1 - +/obj/item/weapon/gun/energy/laser/captain/scattershot + name = "scatter shot laser rifle" + icon_state = "lasercannon" + item_state = "laser" + desc = "An industrial-grade heavy-duty laser rifle with a modified laser lense to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theorically infinite use." + origin_tech = "combat=5;materials=4;powerstorage=4" + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) + shaded_charge = 0 /obj/item/weapon/gun/energy/laser/cyborg + can_charge = 0 desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" + origin_tech = null -/obj/item/weapon/gun/energy/laser/cyborg/process() - return 1 - -/obj/item/weapon/gun/energy/laser/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell && R.cell.charge >= 83) - R.cell.use(83) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/laser/cyborg/newshot() + ..() + robocharge() /obj/item/weapon/gun/energy/laser/cyborg/emp_act() return +/obj/item/weapon/gun/energy/laser/scatter + name = "scatter laser gun" + desc = "A laser gun equipped with a refraction kit that spreads bolts." + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) + +///Laser Cannon /obj/item/weapon/gun/energy/lasercannon name = "accelerator laser cannon" @@ -64,13 +70,18 @@ obj/item/weapon/gun/energy/laser/retro force = 10 flags = CONDUCT slot_flags = SLOT_BACK - fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" - projectile_type = "/obj/item/projectile/beam/laser/accelerator" + ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator) + ammo_x_offset = 3 /obj/item/weapon/gun/energy/lasercannon/isHandgun() return 0 +/obj/item/ammo_casing/energy/laser/accelerator + projectile_type = /obj/item/projectile/beam/laser/accelerator + select_name = "accelerator" + fire_sound = 'sound/weapons/lasercannonfire.ogg' + /obj/item/projectile/beam/laser/accelerator name = "accelerator laser" icon_state = "heavylaser" @@ -83,40 +94,34 @@ obj/item/weapon/gun/energy/laser/retro /obj/item/weapon/gun/energy/lasercannon/mounted name = "mounted laser cannon" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 - recharge_time = 10 + charge_delay = 10 +/obj/item/weapon/gun/energy/lasercannon/cyborg -/obj/item/weapon/gun/energy/lasercannon/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(250) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/lasercannon/cyborg/newshot() + ..() + robocharge() + +/obj/item/weapon/gun/energy/lasercannon/cyborg/emp_act() + return /obj/item/weapon/gun/energy/xray name = "xray laser gun" desc = "A high-power laser gun capable of expelling concentrated xray blasts." icon_state = "xray" - fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" - projectile_type = "/obj/item/projectile/beam/xray" - charge_cost = 500 + ammo_type = list(/obj/item/ammo_casing/energy/xray) /obj/item/weapon/gun/energy/immolator name = "Immolator laser gun" desc = "A modified laser gun, shooting highly concetrated beams with higher intensity that ignites the target, for the cost of draining more power per shot" icon_state = "immolator" item_state = "laser" - fire_sound = 'sound/weapons/laser3.ogg' - projectile_type = "/obj/item/projectile/beam/immolator" + ammo_type = list(/obj/item/ammo_casing/energy/immolator) origin_tech = "combat=4;materials=4;magnets=3;plasmatech=2" - charge_cost = 1250 + shaded_charge = 1 ////////Laser Tag//////////////////// @@ -124,34 +129,20 @@ obj/item/weapon/gun/energy/laser/retro name = "laser tag gun" icon_state = "bluetag" desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/lasertag/blue" + ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/laser/bluetag/special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) - return 1 - to_chat(M, "\red You need to be wearing your laser tag vest!") - return 0 + ammo_x_offset = 2 + selfcharge = 1 /obj/item/weapon/gun/energy/laser/redtag name = "laser tag gun" icon_state = "redtag" desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/lasertag/red" + ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag) origin_tech = "combat=1;magnets=2" clumsy_check = 0 needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/laser/redtag/special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) - return 1 - to_chat(M, "\red You need to be wearing your laser tag vest!") - return 0 \ No newline at end of file + ammo_x_offset = 2 + selfcharge = 1 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 5bc164c5d76..2ef193a6c37 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -1,192 +1,132 @@ /obj/item/weapon/gun/energy/gun name = "energy gun" desc = "A basic energy-based gun with two settings: kill and disable." - icon_state = "energystun100" + icon_state = "energy" item_state = null //so the human update icon uses the icon_state instead. - fire_sound = 'sound/weapons/Taser2.ogg' - charge_cost = 500 - projectile_type = "/obj/item/projectile/beam/disabler" + ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) origin_tech = "combat=3;magnets=2" - modifystate = "energystun" + modifystate = 2 can_flashlight = 1 - - var/mode = 0 //0 = disable, 1 = kill - - - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 1000 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - modifystate = "energykill" - if(1) - mode = 0 - charge_cost = 500 - fire_sound = 'sound/weapons/Taser2.ogg' - to_chat(user, "\red [src.name] is now set to disable.") - projectile_type = "/obj/item/projectile/beam/disabler" - modifystate = "energystun" - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() + ammo_x_offset = 3 + flight_x_offset = 15 + flight_y_offset = 10 /obj/item/weapon/gun/energy/gun/cyborg desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" -/obj/item/weapon/gun/energy/gun/cyborg/process() - return 1 - -/obj/item/weapon/gun/energy/gun/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell && R.cell.charge >= 83) - R.cell.use(83) - in_chamber = new projectile_type(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/gun/cyborg/newshot() + ..() + robocharge() +/obj/item/weapon/gun/energy/gun/cyborg/emp_act() + return /obj/item/weapon/gun/energy/gun/mounted name = "mounted energy gun" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 -/obj/item/weapon/gun/energy/gun/nuclear - name = "Advanced Energy Gun" - desc = "An energy gun with an experimental miniaturized reactor." - icon_state = "nucgun" - origin_tech = "combat=3;materials=5;powerstorage=3" - var/lightfail = 0 - can_flashlight = 0 - can_charge = 0 +/obj/item/weapon/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." + icon_state = "mini" + item_state = "gun" + w_class = 2 + ammo_x_offset = 2 + charge_sections = 3 + can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update - New() - ..() - processing_objects.Add(src) +/obj/item/weapon/gun/energy/gun/mini/New() + F = new /obj/item/device/flashlight/seclite(src) + ..() + power_supply.maxcharge = 6000 + power_supply.charge = 6000 +/obj/item/weapon/gun/energy/gun/mini/update_icon() + ..() + if(F && F.on) + overlays += "mini-light" - Destroy() - processing_objects.Remove(src) - return ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - if((power_supply.charge / power_supply.maxcharge) != 1) - if(!failcheck()) return 0 - power_supply.give(1000) - update_icon() - return 1 - - - proc - failcheck() - lightfail = 0 - if (prob(src.reliability)) return 1 //No failure - if (prob(src.reliability)) - for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it - if (src in M.contents) - to_chat(M, "\red Your gun feels pleasantly warm for a moment.") - else - to_chat(M, "\red You feel a warm sensation.") - M.apply_effect(rand(3,120), IRRADIATE) - lightfail = 1 - else - for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES - if (src in M.contents) - to_chat(M, "\red Your gun's reactor overloads!") - to_chat(M, "\red You feel a wave of heat wash over you.") - M.apply_effect(300, IRRADIATE) - crit_fail = 1 //break the gun so it stops recharging - processing_objects.Remove(src) - update_icon() - return 0 - - - update_charge() - if (crit_fail) - overlays += "nucgun-whee" - return - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - overlays += "nucgun-[ratio]" - - - update_reactor() - if(crit_fail) - overlays += "nucgun-crit" - return - if(lightfail) - overlays += "nucgun-medium" - else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) - overlays += "nucgun-light" - else - overlays += "nucgun-clean" - - - update_mode() - if (mode == 0) - overlays += "nucgun-stun" - else if (mode == 1) - overlays += "nucgun-kill" - - emp_act(severity) - ..() - reliability = max(reliability - round(15/severity), 0) //Do not allow it to go negative! - - - update_icon() - overlays.Cut() - update_charge() - update_reactor() - update_mode() +/obj/item/weapon/gun/energy/gun/hos + name = "\improper X-01 MultiPhase Energy Gun" + desc = "This is a expensive, modern recreation of a antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." + icon_state = "hoslaser" + force = 10 + ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler) + ammo_x_offset = 4 +/obj/item/weapon/gun/energy/gun/blueshield + name = "advanced stun revolver" + desc = "An advanced stun revolver with the capacity to shoot both electrodes and lasers." + icon_state = "bsgun" + force = 7 + ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos) + ammo_x_offset = 1 + shaded_charge = 1 /obj/item/weapon/gun/energy/gun/turret name = "hybrid turret gun" desc = "A heavy hybrid energy cannon with two settings: Stun and kill." icon_state = "turretlaser" + item_state = "turretlaser" slot_flags = null w_class = 5 - heavy_weapon = 1 + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) + weapon_weight = WEAPON_MEDIUM can_flashlight = 0 - projectile_type = /obj/item/projectile/energy/electrode - charge_cost = 1000 - fire_delay = 15 + trigger_guard = TRIGGER_GUARD_NONE + ammo_x_offset = 2 -/obj/item/weapon/gun/energy/gun/turret/update_icon() - icon_state = initial(icon_state) +/obj/item/weapon/gun/energy/gun/nuclear + name = "advanced energy gun" + desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell." + icon_state = "nucgun" + item_state = "nucgun" + origin_tech = "combat=3;materials=5;powerstorage=3" + var/fail_tick = 0 + charge_delay = 5 + can_charge = 0 + ammo_x_offset = 1 + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler) + selfcharge = 1 -/obj/item/weapon/gun/energy/gun/turret/attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 500 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = /obj/item/projectile/beam - modifystate = "energykill" - fire_delay = 0 - if(1) - mode = 0 - charge_cost = 1000 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = /obj/item/projectile/energy/electrode - modifystate = "energystun" - fire_delay = 15 +/obj/item/weapon/gun/energy/gun/nuclear/process() + if(fail_tick > 0) + fail_tick-- + ..() + +/obj/item/weapon/gun/energy/gun/nuclear/shoot_live_shot() + failcheck() update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() + ..() + +/obj/item/weapon/gun/energy/gun/nuclear/proc/failcheck() + if(!prob(reliability) && istype(loc, /mob/living)) + var/mob/living/M = loc + switch(fail_tick) + if(0 to 200) + fail_tick += (2*(100-reliability)) + M.apply_effect(rand(3,120), IRRADIATE) + to_chat(M, "Your [name] feels warmer.") + if(201 to INFINITY) + processing_objects.Remove(src) + M.apply_effect(300, IRRADIATE) + crit_fail = 1 + to_chat(M, "Your [name]'s reactor overloads!") + +/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity) + ..() + reliability = max(reliability - round(15/severity), 0) //Do not allow it to go negative! + +/obj/item/weapon/gun/energy/gun/nuclear/update_icon() + ..() + if(crit_fail) + overlays += "[icon_state]_fail_3" else - user.update_inv_r_hand() \ No newline at end of file + switch(fail_tick) + if(0) + overlays += "[icon_state]_fail_0" + if(1 to 150) + overlays += "[icon_state]_fail_1" + if(151 to INFINITY) + overlays += "[icon_state]_fail_2" diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index bc7704d709a..c155cfb9dff 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -1,93 +1,72 @@ -/obj/item/weapon/gun/energy/pulse_rifle +/obj/item/weapon/gun/energy/pulse name = "pulse rifle" - desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel." + desc = "A heavy-duty, multifaceted energy rifle with three modes. Preferred by front-line combat personnel." icon_state = "pulse" - item_state = null //so the human update icon uses the icon_state instead. + item_state = null + w_class = 4 force = 10 - fire_sound = 'sound/weapons/pulse.ogg' - charge_cost = 200 - projectile_type = "/obj/item/projectile/beam/pulse" - cell_type = "/obj/item/weapon/stock_parts/cell/super" - var/mode = 2 + flags = CONDUCT slot_flags = SLOT_BACK - w_class = 4.0 + ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) + cell_type = /obj/item/weapon/stock_parts/cell/pulse - emp_act() - return +/obj/item/weapon/gun/energy/pulse/emp_act(severity) + return - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 50 - fire_sound = 'sound/weapons/Taser.ogg' - to_chat(user, "\red [src.name] is now set to stun.") - projectile_type = "/obj/item/projectile/energy/electrode" - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - to_chat(user, "\red [src.name] is now set to kill.") - projectile_type = "/obj/item/projectile/beam" - if(1) - mode = 2 - charge_cost = 200 - fire_sound = 'sound/weapons/pulse.ogg' - to_chat(user, "\red [src.name] is now set to DESTROY.") - projectile_type = "/obj/item/projectile/beam/pulse" - return - - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/pulse_rifle/cyborg/process_chambered() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) - in_chamber = new projectile_type(src) - return 1 +/obj/item/weapon/gun/energy/pulse/isHandgun() return 0 +/obj/item/weapon/gun/energy/pulse/cyborg -/obj/item/weapon/gun/energy/pulse_rifle/destroyer - name = "pulse destroyer" - desc = "A heavy-duty, pulse-based energy weapon." - cell_type = "/obj/item/weapon/stock_parts/cell/infinite" +/obj/item/weapon/gun/energy/pulse/cyborg/newshot() + ..() + robocharge() - attack_self(mob/living/user as mob) - to_chat(user, "\red [src.name] has three settings, and they are all DESTROY.") - -/obj/item/weapon/gun/energy/pulse_rifle/carbine +/obj/item/weapon/gun/energy/pulse/carbine name = "pulse carbine" desc = "A compact variant of the pulse rifle with less firepower but easier storage." w_class = 3 slot_flags = SLOT_BELT icon_state = "pulse_carbine" item_state = "pulse" - cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine" + cell_type = /obj/item/weapon/stock_parts/cell/pulse/carbine can_flashlight = 1 + flight_x_offset = 18 + flight_y_offset = 12 - -/obj/item/weapon/gun/energy/pulse_rifle/pistol +/obj/item/weapon/gun/energy/pulse/pistol name = "pulse pistol" desc = "A pulse rifle in an easily concealed handgun package with low capacity." w_class = 2 slot_flags = SLOT_BELT icon_state = "pulse_pistol" item_state = "gun" - cell_type = "/obj/item/weapon/stock_parts/cell/pulse/pistol" + cell_type = /obj/item/weapon/stock_parts/cell/pulse/pistol + can_charge = 0 -/obj/item/weapon/gun/energy/pulse_rifle/pistol/isHandgun() +/obj/item/weapon/gun/energy/pulse/pistol/isHandgun() return 1 -/obj/item/weapon/gun/energy/pulse_rifle/pistol/m1911 +/obj/item/weapon/gun/energy/pulse/destroyer + name = "pulse destroyer" + desc = "A heavy-duty, pulse-based energy weapon." + cell_type = /obj/item/weapon/stock_parts/cell/infinite + ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse) + +/obj/item/weapon/gun/energy/pulse/destroyer/attack_self(mob/living/user) + to_chat(user, "[name] has three settings, and they are all DESTROY.") + +/obj/item/weapon/gun/energy/pulse/destroyer/annihilator + name = "pulse ANNIHILATOR" + desc = "For when the situation calls for a little more than a pulse destroyer." + ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter/pulse) + +/obj/item/weapon/gun/energy/pulse/pistol/m1911 name = "\improper M1911-P" desc = "A compact pulse core in a classic handgun frame for Nanotrasen officers. It's not the size of the gun, it's the size of the hole it puts through people." - icon_state = "m1911-p" + icon_state = "m1911" item_state = "gun" - cell_type = "/obj/item/weapon/stock_parts/cell/infinite" - isHandgun() - return 1 \ No newline at end of file + cell_type = /obj/item/weapon/stock_parts/cell/infinite + +/obj/item/weapon/gun/energy/pulse/pistol/m1911/isHandgun() + return 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d6c0ad7beb3..3c4766fd58b 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -8,7 +8,10 @@ w_class = 5.0 flags = CONDUCT slot_flags = SLOT_BACK - projectile_type = "/obj/item/projectile/ion" + ammo_type = list(/obj/item/ammo_casing/energy/ion) + ammo_x_offset = 3 + flight_x_offset = 17 + flight_y_offset = 9 /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) return @@ -17,10 +20,12 @@ name = "ion carbine" desc = "The MK.II Prototype Ion Projector is a lightweight carbine version of the larger ion rifle, built to be ergonomic and efficient." icon_state = "ioncarbine" - item_state = "ioncarbine" origin_tech = "combat=4;magnets=4;materials=4" w_class = 3 slot_flags = SLOT_BELT + ammo_x_offset = 2 + flight_x_offset = 18 + flight_y_offset = 11 /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" @@ -28,65 +33,38 @@ icon_state = "decloner" fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" - projectile_type = "/obj/item/projectile/energy/declone" + ammo_type = list(/obj/item/ammo_casing/energy/declone) + ammo_x_offset = 1 +/obj/item/weapon/gun/energy/decloner/update_icon() + ..() + var/obj/item/ammo_casing/energy/shot = ammo_type[select] + if(power_supply.charge > shot.e_cost) + overlays += "decloner_spin" /obj/item/weapon/gun/energy/floragun name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." - icon_state = "floramut100" + icon_state = "flora" item_state = "gun" fire_sound = 'sound/effects/stealthoff.ogg' - projectile_type = "/obj/item/projectile/energy/floramut" + ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut) origin_tech = "materials=2;biotech=3;powerstorage=3" - modifystate = "floramut" - var/mode = 0 //0 = mutate, 1 = yield boost - needs_permit = 0 - - self_recharge = 1 - -/obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 1000 - to_chat(user, "\red The [src.name] is now set to increase yield.") - projectile_type = "/obj/item/projectile/energy/florayield" - modifystate = "florayield" - if(1) - mode = 0 - charge_cost = 1000 - to_chat(user, "\red The [src.name] is now set to induce mutations.") - projectile_type = "/obj/item/projectile/energy/floramut" - modifystate = "floramut" - update_icon() - return - - -/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag) - - if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = target - if(process_chambered()) - user.visible_message("\red \The [user] fires \the [src] into \the [tray]!") - Fire(target,user) - return - - ..() + modifystate = 1 + ammo_x_offset = 1 + selfcharge = 1 /obj/item/weapon/gun/energy/meteorgun name = "meteor gun" desc = "For the love of god, make sure you're aiming this the right way!" + icon = 'icons/obj/guns/projectile.dmi' icon_state = "riotgun" item_state = "c20r" w_class = 4 - projectile_type = "/obj/item/projectile/meteor" - cell_type = "/obj/item/weapon/stock_parts/cell/potato" + ammo_type = list(/obj/item/ammo_casing/energy/meteor) + cell_type = /obj/item/weapon/stock_parts/cell/potato clumsy_check = 0 //Admin spawn only, might as well let clowns use it. - - self_recharge = 1 - recharge_time = 5 //Time it takes for shots to recharge (in ticks) - + selfcharge = 1 /obj/item/weapon/gun/energy/meteorgun/pen name = "meteor pen" @@ -98,119 +76,116 @@ righthand_file = 'icons/mob/inhands/items_righthand.dmi' w_class = 1 - /obj/item/weapon/gun/energy/mindflayer name = "\improper Mind Flayer" desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon." icon_state = "xray" - projectile_type = "/obj/item/projectile/beam/mindflayer" - fire_sound = 'sound/weapons/Laser.ogg' - -obj/item/weapon/gun/energy/staff/focus - name = "mental focus" - desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." - icon = 'icons/obj/wizard.dmi' - icon_state = "focus" - item_state = "focus" - projectile_type = "/obj/item/projectile/forcebolt" - /* - attack_self(mob/living/user as mob) - if(projectile_type == "/obj/item/projectile/forcebolt") - charge_cost = 200 - to_chat(user, "\red The [src.name] will now strike a small area.") - projectile_type = "/obj/item/projectile/forcebolt/strong" - else - charge_cost = 100 - to_chat(user, "\red The [src.name] will now strike only a single person.") - projectile_type = "/obj/item/projectile/forcebolt" - */ - -/obj/item/weapon/gun/energy/clown - name = "HONK Rifle" - desc = "Clown Planet's finest." - icon_state = "energy" - projectile_type = "/obj/item/projectile/clown" - fire_sound = 'sound/weapons/Gunshot_smg.ogg' - clumsy_check = 0 - - - -/obj/item/weapon/gun/energy/toxgun - name = "plasma pistol" - desc = "A specialized firearm designed to fire lethal bolts of toxins." - icon_state = "toxgun" - fire_sound = 'sound/effects/stealthoff.ogg' - w_class = 3.0 - origin_tech = "combat=4;plasmatech=3" - projectile_type = "/obj/item/projectile/energy/plasma" - -/obj/item/weapon/gun/energy/sniperrifle - name = "L.W.A.P. Sniper Rifle" - desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." - icon = 'icons/obj/gun.dmi' - icon_state = "esniper" - fire_sound = 'sound/weapons/marauder.ogg' - origin_tech = "combat=6;materials=5;powerstorage=4" - projectile_type = "/obj/item/projectile/beam/sniper" - slot_flags = SLOT_BACK - charge_cost = 2500 - fire_delay = 50 - w_class = 4.0 - zoomable = TRUE - zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. - + item_state = null + ammo_type = list(/obj/item/ammo_casing/energy/mindflayer) + ammo_x_offset = 2 /obj/item/weapon/gun/energy/kinetic_accelerator name = "proto-kinetic accelerator" desc = "According to Nanotrasen accounting, this is mining equipment. It's been modified for extreme power output to crush rocks, but often serves as a miner's first defense against hostile alien life; it's not very powerful unless used in a low pressure environment." icon_state = "kineticgun" item_state = "kineticgun" - projectile_type = "/obj/item/projectile/kinetic" - fire_sound = 'sound/weapons/Kenetic_accel.ogg' - charge_cost = 5000 - cell_type = "/obj/item/weapon/stock_parts/cell/emproof" - needs_permit = 0 // Aparently these are safe to carry? I'm sure Golliaths would disagree. - fire_delay = 16 //Because guncode is bad and you can bug the reload for rapid fire otherwise. - var/recently_fired = 0 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic) + cell_type = /obj/item/weapon/stock_parts/cell/emproof + // Apparently these are safe to carry? I'm sure goliaths would disagree. + needs_permit = 0 + var/overheat_time = 16 + unique_rename = 1 + weapon_weight = WEAPON_LIGHT + origin_tech = "combat=2;powerstorage=1" + var/holds_charge = FALSE + var/unique_frequency = FALSE // modified by KA modkits + + var/overheat = FALSE /obj/item/weapon/gun/energy/kinetic_accelerator/super name = "super-kinetic accelerator" desc = "An upgraded, superior version of the proto-kinetic accelerator." icon_state = "kineticgun_u" - projectile_type = "/obj/item/projectile/kinetic/super" - fire_delay = 15 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic/super) + overheat_time = 15 origin_tech = "combat=3;powerstorage=2" /obj/item/weapon/gun/energy/kinetic_accelerator/hyper name = "hyper-kinetic accelerator" desc = "An upgraded, even more superior version of the proto-kinetic accelerator." icon_state = "kineticgun_h" - projectile_type = "/obj/item/projectile/kinetic/hyper" - fire_delay = 13 + ammo_type = list(/obj/item/ammo_casing/energy/kinetic/hyper) + overheat_time = 14 origin_tech = "combat=4;powerstorage=3" /obj/item/weapon/gun/energy/kinetic_accelerator/cyborg - flags = NODROP + holds_charge = TRUE + unique_frequency = TRUE -/obj/item/weapon/gun/energy/kinetic_accelerator/Fire() - if(!recently_fired) - recently_fired = 1 - spawn(fire_delay) - reload(usr) - ..() +/obj/item/weapon/gun/energy/kinetic_accelerator/New() + . = ..() + if(!holds_charge) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot() + . = ..() + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user) + . = ..() + if(!can_shoot()) + attempt_reload() + +/obj/item/weapon/gun/energy/kinetic_accelerator/dropped() + . = ..() + if(!holds_charge) + // Put it on a delay because moving item from slot to hand + // calls dropped(). + spawn(1) + if(!ismob(loc)) + empty() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty() + power_supply.use(5000) + update_icon() + +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload() + if(overheat) + return + overheat = TRUE + + var/carried = 0 + if(!unique_frequency) + for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \ + loc.GetAllContents()) + + carried++ + + carried = max(carried, 1) + else + carried = 1 + + spawn(overheat_time * carried) + reload() + overheat = FALSE /obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity) return -/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload(mob/living/user) +/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload() power_supply.give(5000) - if(!silenced) - playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) - else if(user) - to_chat(usr, "You silently charge [src].") - recently_fired = 0 + if(!suppressed) + playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + else + to_chat(loc, "[src] silently charges up.") update_icon() +/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon() + if(!can_shoot()) + icon_state = "[initial(icon_state)]_empty" + else + icon_state = initial(icon_state) + /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow name = "mini energy crossbow" desc = "A weapon favored by syndicate stealth specialists." @@ -219,10 +194,17 @@ obj/item/weapon/gun/energy/staff/focus w_class = 2 materials = list(MAT_METAL=2000) origin_tech = "combat=2;magnets=2;syndicate=5" - silenced = 1 - projectile_type = "/obj/item/projectile/energy/bolt" - fire_sound = 'sound/weapons/Genhit.ogg' - fire_delay = 20 + suppressed = 1 + ammo_type = list(/obj/item/ammo_casing/energy/bolt) + weapon_weight = WEAPON_LIGHT + unique_rename = 0 + overheat_time = 20 + holds_charge = TRUE + unique_frequency = TRUE + +/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja + name = "energy dart thrower" + ammo_type = list(/obj/item/ammo_casing/energy/dart) /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large name = "energy crossbow" @@ -231,8 +213,8 @@ obj/item/weapon/gun/energy/staff/focus w_class = 3 materials = list(MAT_METAL=4000) origin_tech = "combat=2;magnets=2;syndicate=3" //can be further researched for more syndie tech - silenced = 0 - projectile_type = "/obj/item/projectile/energy/bolt/large" + suppressed = 0 + ammo_type = list(/obj/item/ammo_casing/energy/bolt/large) /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/large/cyborg desc = "One and done!" @@ -240,27 +222,35 @@ obj/item/weapon/gun/energy/staff/focus origin_tech = null materials = list() +/obj/item/weapon/gun/energy/kinetic_accelerator/suicide_act(mob/user) + if(!suppressed) + playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1) + user.visible_message("[user] cocks the [name] and pretends to blow \his brains out! It looks like \he's trying to commit suicide!") + shoot_live_shot() + return (OXYLOSS) + /obj/item/weapon/gun/energy/plasmacutter name = "plasma cutter" desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off of xenos! Or, you know, mine stuff." icon_state = "plasmacutter" item_state = "plasmacutter" - modifystate = "plasmacutter" + modifystate = -1 origin_tech = "combat=1;materials=3;magnets=2;plasmatech=2;engineering=1" - projectile_type = /obj/item/projectile/plasma + ammo_type = list(/obj/item/ammo_casing/energy/plasma) fire_sound = 'sound/weapons/laser.ogg' flags = CONDUCT | OPENCONTAINER attack_verb = list("attacked", "slashed", "cut", "sliced") - charge_cost = 250 - fire_delay = 15 + force = 12 + sharp = 1 + edge = 1 can_charge = 0 /obj/item/weapon/gun/energy/plasmacutter/examine(mob/user) - ..(user) + ..() if(power_supply) to_chat(user, "[src] is [round(power_supply.percent())]% charged.") -/obj/item/weapon/gun/energy/plasmacutter/attackby(var/obj/item/A, var/mob/user) +/obj/item/weapon/gun/energy/plasmacutter/attackby(obj/item/A, mob/user) if(istype(A, /obj/item/stack/sheet/mineral/plasma)) var/obj/item/stack/sheet/S = A S.use(1) @@ -273,92 +263,35 @@ obj/item/weapon/gun/energy/staff/focus else ..() +/obj/item/weapon/gun/energy/plasmacutter/update_icon() + return + /obj/item/weapon/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" modifystate = "adv_plasmacutter" origin_tech = "combat=3;materials=4;magnets=3;plasmatech=3;engineering=2" - projectile_type = /obj/item/projectile/plasma/adv - fire_delay = 10 - charge_cost = 100 - -/obj/item/weapon/gun/energy/disabler - name = "disabler" - desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." - icon_state = "disabler" - item_state = null - projectile_type = /obj/item/projectile/beam/disabler - fire_sound = 'sound/weapons/taser2.ogg' - cell_type = "/obj/item/weapon/stock_parts/cell" - charge_cost = 500 - -/obj/item/weapon/gun/energy/disabler/cyborg - name = "cyborg disabler" - desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating." - - self_recharge = 1 - use_external_power = 1 - recharge_time = 2.5 - - -/* 3d printer 'pseudo guns' for borgs */ - -/obj/item/weapon/gun/energy/printer - name = "cyborg lmg" - desc = "A machinegun that fires 3d-printed flachettes slowly regenerated using a cyborg's internal power source." - icon_state = "l6closed0" - icon = 'icons/obj/gun.dmi' - fire_sound = 'sound/weapons/Gunshot_smg.ogg' - cell_type = "/obj/item/weapon/stock_parts/cell/secborg" - projectile_type = "/obj/item/projectile/bullet/midbullet3" - charge_cost = 200 //Yeah, let's NOT give them a 300 round clip that recharges, 20 is more reasonable and will actually hurt the borg's battery for overuse. - - self_recharge = 1 - use_external_power = 1 - recharge_time = 5 - -/obj/item/weapon/gun/energy/printer/update_icon() - return + ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) + force = 15 /obj/item/weapon/gun/energy/wormhole_projector name = "bluespace wormhole projector" desc = "A projector that emits high density quantum-coupled bluespace beams." - projectile_type = "/obj/item/projectile/beam/wormhole" - charge_cost = 0 - fire_sound = "sound/weapons/pulse3.ogg" + ammo_type = list(/obj/item/ammo_casing/energy/wormhole, /obj/item/ammo_casing/energy/wormhole/orange) item_state = null icon_state = "wormhole_projector100" - modifystate = "wormhole_projector" var/obj/effect/portal/blue var/obj/effect/portal/orange - var/mode = 0 //0 = blue 1 = orange +/obj/item/weapon/gun/energy/wormhole_projector/update_icon() + icon_state = "[initial(icon_state)][select]" + item_state = icon_state + return -/obj/item/weapon/gun/energy/wormhole_projector/attack_self(mob/living/user as mob) - switch_modes() - -/obj/item/weapon/gun/energy/wormhole_projector/proc/switch_modes(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - to_chat(user, "[name] is now set to orange.") - projectile_type = "/obj/item/projectile/beam/wormhole/orange" - modifystate = "wormhole_projector_orange" - if(1) - mode = 0 - to_chat(user, "[name] is now set to blue.") - projectile_type = "/obj/item/projectile/beam/wormhole" - modifystate = "wormhole_projector" - update_icon() - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - -/obj/item/weapon/gun/energy/wormhole_projector/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/energy/wormhole_projector/process_chamber() ..() - switch_modes(user) + select_fire() /obj/item/weapon/gun/energy/wormhole_projector/proc/portal_destroyed(obj/effect/portal/P) if(P.icon_state == "portal") @@ -373,7 +306,6 @@ obj/item/weapon/gun/energy/staff/focus /obj/item/weapon/gun/energy/wormhole_projector/proc/create_portal(obj/item/projectile/beam/wormhole/W) var/obj/effect/portal/P = new /obj/effect/portal(get_turf(W), null, src) P.precision = 0 - P.failchance = 0 if(W.name == "bluespace beam") qdel(blue) blue = P @@ -383,4 +315,270 @@ obj/item/weapon/gun/energy/staff/focus orange = P if(orange && blue) blue.target = get_turf(orange) - orange.target = get_turf(blue) \ No newline at end of file + orange.target = get_turf(blue) + +/* 3d printer 'pseudo guns' for borgs */ + +/obj/item/weapon/gun/energy/printer + name = "cyborg lmg" + desc = "A machinegun that fires 3d-printed flachettes slowly regenerated using a cyborg's internal power source." + icon_state = "l6closed0" + icon = 'icons/obj/guns/projectile.dmi' + cell_type = /obj/item/weapon/stock_parts/cell/secborg + ammo_type = list(/obj/item/ammo_casing/energy/c3dbullet) + can_charge = 0 + +/obj/item/weapon/gun/energy/printer/update_icon() + return + +/obj/item/weapon/gun/energy/printer/emp_act() + return + +/obj/item/weapon/gun/energy/printer/newshot() + ..() + robocharge() + +/obj/item/weapon/gun/energy/laser/instakill + name = "instakill rifle" + icon_state = "instagib" + item_state = "instagib" + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." + ammo_type = list(/obj/item/ammo_casing/energy/instakill) + force = 60 + origin_tech = null + +/obj/item/weapon/gun/energy/laser/instakill/emp_act() //implying you could stop the instagib + return + +/obj/item/weapon/gun/energy/laser/instakill/red + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." + icon_state = "instagibred" + item_state = "instagibred" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/red) + +/obj/item/weapon/gun/energy/laser/instakill/blue + desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a blue design." + icon_state = "instagibblue" + item_state = "instagibblue" + ammo_type = list(/obj/item/ammo_casing/energy/instakill/blue) + +/obj/item/weapon/gun/energy/clown + name = "HONK Rifle" + desc = "Clown Planet's finest." + icon_state = "disabler" + ammo_type = list(/obj/item/ammo_casing/energy/clown) + clumsy_check = 0 + ammo_x_offset = 3 + +/obj/item/weapon/gun/energy/toxgun + name = "plasma pistol" + desc = "A specialized firearm designed to fire lethal bolts of toxins." + icon_state = "toxgun" + fire_sound = 'sound/effects/stealthoff.ogg' + w_class = 3 + origin_tech = "combat=4;plasmatech=3" + ammo_type = list(/obj/item/ammo_casing/energy/toxplasma) + shaded_charge = 1 + +/obj/item/weapon/gun/energy/sniperrifle + name = "L.W.A.P. Sniper Rifle" + desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." + icon_state = "esniper" + origin_tech = "combat=6;materials=5;powerstorage=4" + ammo_type = list(/obj/item/ammo_casing/energy/sniper) + slot_flags = SLOT_BACK + w_class = 4 + zoomable = TRUE + zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. + shaded_charge = 1 + +/obj/item/weapon/gun/energy/temperature + name = "temperature gun" + icon = 'icons/obj/guns/gun_temperature.dmi' + icon_state = "tempgun_4" + item_state = "tempgun_4" + slot_flags = SLOT_BACK + w_class = 4 + fire_sound = 'sound/weapons/pulse3.ogg' + desc = "A gun that changes the body temperature of its targets." + var/temperature = 300 + var/target_temperature = 300 + var/e_cost = 1000 + origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" + + ammo_type = list(/obj/item/ammo_casing/energy/temp) + cell_type = /obj/item/weapon/stock_parts/cell + + var/powercost = "" + var/powercostcolor = "" + + var/emagged = 0 //ups the temperature cap from 500 to 1000, targets hit by beams over 500 Kelvin will burst into flames + var/dat = "" + +/obj/item/weapon/gun/energy/temperature/New() + ..() + update_icon() + processing_objects.Add(src) + + +/obj/item/weapon/gun/energy/temperature/Destroy() + processing_objects.Remove(src) + return ..() + +/obj/item/weapon/gun/energy/temperature/newshot() + ..(temperature, e_cost) + +/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) + user.set_machine(src) + update_dat() + user << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x120") + onclose(user, "tempgun") + +/obj/item/weapon/gun/energy/temperature/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/card/emag) && !emagged) + emagged = 1 + to_chat(user, "You double the gun's temperature cap! Targets hit by searing beams will burst into flames!") + desc = "A gun that changes the body temperature of its targets. Its temperature cap has been hacked." + +/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) + if (..()) + return + usr.set_machine(src) + add_fingerprint(usr) + + if(href_list["temp"]) + var/amount = text2num(href_list["temp"]) + if(amount > 0) + target_temperature = min((500 + 500*emagged), target_temperature+amount) + else + target_temperature = max(0, target_temperature+amount) + if (istype(loc, /mob)) + attack_self(loc) + add_fingerprint(usr) + return + +/obj/item/weapon/gun/energy/temperature/process() + switch(temperature) + if(0 to 100) + e_cost = 3000 + powercost = "High" + if(100 to 250) + e_cost = 2000 + powercost = "Medium" + if(251 to 300) + e_cost = 1000 + powercost = "Low" + if(301 to 400) + e_cost = 2000 + powercost = "Medium" + if(401 to 1000) + e_cost = 3000 + powercost = "High" + switch(powercost) + if("High") powercostcolor = "orange" + if("Medium") powercostcolor = "green" + else powercostcolor = "blue" + if(target_temperature != temperature) + var/difference = abs(target_temperature - temperature) + if(difference >= (10 + 40*emagged)) //so emagged temp guns adjust their temperature much more quickly + if(target_temperature < temperature) + temperature -= (10 + 40*emagged) + else + temperature += (10 + 40*emagged) + else + temperature = target_temperature + update_icon() + + if (istype(loc, /mob/living/carbon)) + var /mob/living/carbon/M = loc + if (src == M.machine) + update_dat() + M << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x102") + return + +/obj/item/weapon/gun/energy/temperature/proc/update_dat() + dat = "" + dat += "Current output temperature: " + if(temperature > 500) + dat += "[temperature] ([round(temperature-T0C)]°C)" + dat += " SEARING!" + else if(temperature > (T0C + 50)) + dat += "[temperature] ([round(temperature-T0C)]°C)" + else if(temperature > (T0C - 50)) + dat += "[temperature] ([round(temperature-T0C)]°C)" + else + dat += "[temperature] ([round(temperature-T0C)]°C)" + dat += "
" + dat += "Target output temperature: " //might be string idiocy, but at least it's easy to read + dat += "- " + dat += "- " + dat += "- " + dat += "[target_temperature] " + dat += "+ " + dat += "+ " + dat += "+" + dat += "
" + dat += "Power cost: " + dat += "[powercost]" + +/obj/item/weapon/gun/energy/temperature/proc/update_temperature() + switch(temperature) + if(501 to INFINITY) + item_state = "tempgun_8" + if(400 to 500) + item_state = "tempgun_7" + if(360 to 400) + item_state = "tempgun_6" + if(335 to 360) + item_state = "tempgun_5" + if(295 to 335) + item_state = "tempgun_4" + if(260 to 295) + item_state = "tempgun_3" + if(200 to 260) + item_state = "tempgun_2" + if(120 to 260) + item_state = "tempgun_1" + if(-INFINITY to 120) + item_state = "tempgun_0" + icon_state = item_state + +/obj/item/weapon/gun/energy/temperature/update_icon() + overlays = 0 + update_temperature() + update_user() + update_charge() + +/obj/item/weapon/gun/energy/temperature/proc/update_user() + if (istype(loc,/mob/living/carbon)) + var/mob/living/carbon/M = loc + M.update_inv_back() + M.update_inv_l_hand() + M.update_inv_r_hand() + +/obj/item/weapon/gun/energy/temperature/proc/update_charge() + var/charge = power_supply.charge + switch(charge) + if(9000 to INFINITY) overlays += "900" + if(8000 to 9000) overlays += "800" + if(7000 to 8000) overlays += "700" + if(6000 to 7000) overlays += "600" + if(5000 to 6000) overlays += "500" + if(4000 to 5000) overlays += "400" + if(3000 to 4000) overlays += "300" + if(2000 to 3000) overlays += "200" + if(1000 to 2002) overlays += "100" + if(-INFINITY to 1000) overlays += "0" + +/obj/item/weapon/gun/energy/mimicgun + name = "mimic gun" + desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse. Why does this one have teeth?" + icon_state = "disabler" + ammo_type = list(/obj/item/ammo_casing/energy/mimic) + clumsy_check = 0 //Admin spawn only, might as well let clowns use it. + selfcharge = 1 + ammo_x_offset = 3 + var/mimic_type = /obj/item/weapon/gun/projectile/automatic/pistol //Setting this to the mimicgun type does exactly what you think it will. + +/obj/item/weapon/gun/energy/mimicgun/newshot() + ..(mimic_type) diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 37d22ba5ff7..9728a9442e1 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -1,84 +1,67 @@ - /obj/item/weapon/gun/energy/taser name = "taser gun" desc = "A small, low capacity gun used for non-lethal takedowns." icon_state = "taser" item_state = null //so the human update icon uses the icon_state instead. - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/stock_parts/cell/crap" - fire_delay = 15 + ammo_type = list(/obj/item/ammo_casing/energy/electrode) + ammo_x_offset = 3 + cell_type = /obj/item/weapon/stock_parts/cell/crap /obj/item/weapon/gun/energy/taser/mounted name = "mounted taser gun" - self_recharge = 1 + selfcharge = 1 use_external_power = 1 /obj/item/weapon/gun/energy/taser/cyborg name = "taser gun" desc = "A small, low capacity gun used for non-lethal takedowns." icon_state = "taser" - fire_sound = 'sound/weapons/Taser.ogg' - projectile_type = "/obj/item/projectile/energy/electrode" - cell_type = "/obj/item/weapon/stock_parts/cell/secborg" + cell_type = /obj/item/weapon/stock_parts/cell/secborg - self_recharge = 1 - recharge_time = 10 //Time it takes for shots to recharge (in ticks) +/obj/item/weapon/gun/energy/disabler/cyborg/newshot() + ..() + robocharge() /obj/item/weapon/gun/energy/shock_revolver name = "tesla revolver" desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers." icon_state = "stunrevolver" item_state = "gun" - fire_sound = 'sound/weapons/gunshot.ogg' - projectile_type = "/obj/item/projectile/energy/shock_revolver" - charge_cost = 2000 + ammo_type = list(/obj/item/ammo_casing/energy/shock_revolver) can_flashlight = 0 + shaded_charge = 1 -/obj/item/projectile/energy/shock_revolver - name = "shock bolt" - icon_state = "purple_laser" - var/chain +/obj/item/weapon/gun/energy/gun/advtaser + name = "hybrid taser" + desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams." + icon_state = "advtaser" + ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler) + origin_tech = null + ammo_x_offset = 2 -/obj/item/projectile/energy/shock_revolver/OnFired() - spawn(1) - chain = Beam(firer, icon_state="purple_lightning", icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) +/obj/item/weapon/gun/energy/gun/advtaser/cyborg + name = "cyborg taser" + desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The weapon contains a limiter to prevent the cyborg's power cell from overheating." + can_flashlight = 0 + can_charge = 0 -/obj/item/projectile/energy/shock_revolver/on_hit(atom/target) - . = ..() - if(isliving(target)) - tesla_zap(src, 3, 10000) - qdel(chain) +/obj/item/weapon/gun/energy/gun/advtaser/cyborg/newshot() + ..() + robocharge() -/obj/item/weapon/gun/energy/crossbow - name = "mini energy-crossbow" - desc = "A weapon favored by many of the syndicates stealth specialists." - icon_state = "crossbow" - w_class = 2.0 - item_state = "crossbow" - materials = list(MAT_METAL=2000) - origin_tech = "combat=2;magnets=2;syndicate=5" - silenced = 1 - fire_sound = 'sound/weapons/Genhit.ogg' - projectile_type = "/obj/item/projectile/energy/bolt" - cell_type = "/obj/item/weapon/stock_parts/cell/crap" - - self_recharge = 1 - -/obj/item/weapon/gun/energy/crossbow/ninja - name = "energy dart thrower" - projectile_type = /obj/item/projectile/energy/dart - -/obj/item/weapon/gun/energy/crossbow/update_icon() - return -/obj/item/weapon/gun/energy/crossbow/largecrossbow - name = "Energy Crossbow" - desc = "A weapon favored by syndicate carp hunters." - icon_state = "crossbowlarge" - silenced = 0 - w_class = 3.0 - force = 10 - materials = list(MAT_METAL=4000) - projectile_type = "/obj/item/projectile/energy/bolt/large" +/obj/item/weapon/gun/energy/disabler + name = "disabler" + desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." + icon_state = "disabler" + item_state = null + ammo_type = list(/obj/item/ammo_casing/energy/disabler) + ammo_x_offset = 3 +/obj/item/weapon/gun/energy/disabler/cyborg + name = "cyborg disabler" + desc = "An integrated disabler that draws from a cyborg's power cell. This weapon contains a limiter to prevent the cyborg's power cell from overheating." + can_charge = 0 +/obj/item/weapon/gun/energy/disabler/cyborg/newshot() + ..() + robocharge() diff --git a/code/modules/projectiles/guns/energy/telegun.dm b/code/modules/projectiles/guns/energy/telegun.dm index 3819401e031..e8a882d7c80 100644 --- a/code/modules/projectiles/guns/energy/telegun.dm +++ b/code/modules/projectiles/guns/energy/telegun.dm @@ -5,11 +5,10 @@ desc = "An extremely high-tech bluespace energy gun capable of teleporting targets to far off locations." icon_state = "telegun" item_state = "ionrifle" - fire_sound = 'sound/weapons/wave.ogg' origin_tech = "combat=6;materials=7;powerstorage=5;bluespace=5;syndicate=4" - cell_type = "/obj/item/weapon/stock_parts/cell/crap" - projectile_type = "/obj/item/projectile/energy/teleport" - charge_cost = 1250 + cell_type = /obj/item/weapon/stock_parts/cell/crap + ammo_type = list(/obj/item/ammo_casing/energy/teleport) + shaded_charge = 1 var/teleport_target = null /obj/item/weapon/gun/energy/telegun/Destroy() @@ -36,4 +35,7 @@ L[tmpname] = R var/desc = input("Please select a location to lock in.", "Telegun Target Interface") in L - teleport_target = L[desc] \ No newline at end of file + teleport_target = L[desc] + +/obj/item/weapon/gun/energy/telegun/newshot() + ..(teleport_target) diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm deleted file mode 100644 index 1e0eb5d08c2..00000000000 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ /dev/null @@ -1,182 +0,0 @@ -/obj/item/weapon/gun/energy/temperature - name = "temperature gun" - icon = 'icons/obj/gun_temperature.dmi' - icon_state = "tempgun_4" - item_state = "tempgun_4" - slot_flags = SLOT_BACK - w_class = 4.0 - fire_sound = 'sound/weapons/pulse3.ogg' - desc = "A gun that changes the body temperature of its targets." - var/temperature = 300 - var/target_temperature = 300 - charge_cost = 90 - origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" - - projectile_type = /obj/item/projectile/temp - cell_type = /obj/item/weapon/stock_parts/cell/temperaturegun - - var/powercost = "" - var/powercostcolor = "" - - var/emagged = 0 //ups the temperature cap from 500 to 1000, targets hit by beams over 500 Kelvin will burst into flames - var/dat = "" - -/obj/item/weapon/gun/energy/temperature/New() - ..() - update_icon() - processing_objects.Add(src) - - -/obj/item/weapon/gun/energy/temperature/Destroy() - processing_objects.Remove(src) - return ..() - - -/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) - user.set_machine(src) - update_dat() - - user << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x120") - onclose(user, "tempgun") - -/obj/item/weapon/gun/energy/temperature/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/card/emag) && !emagged) - emagged = 1 - to_chat(user, "You double the gun's temperature cap! Targets hit by searing beams will burst into flames!") - desc = "A gun that changes the body temperature of its targets. Its temperature cap has been hacked." - -/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - add_fingerprint(usr) - - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - target_temperature = min((500 + 500*emagged), target_temperature+amount) - else - target_temperature = max(0, target_temperature+amount) - if (istype(loc, /mob)) - attack_self(loc) - add_fingerprint(usr) - return - - -/obj/item/weapon/gun/energy/temperature/process() - switch(temperature) - if(0 to 100) - charge_cost = 300 - powercost = "High" - if(100 to 250) - charge_cost = 180 - powercost = "Medium" - if(251 to 300) - charge_cost = 90 - powercost = "Low" - if(301 to 400) - charge_cost = 180 - powercost = "Medium" - if(401 to 1000) - charge_cost = 300 - powercost = "High" - switch(powercost) - if("High") powercostcolor = "orange" - if("Medium") powercostcolor = "green" - else powercostcolor = "blue" - if(target_temperature != temperature) - var/difference = abs(target_temperature - temperature) - if(difference >= (10 + 40*emagged)) //so emagged temp guns adjust their temperature much more quickly - if(target_temperature < temperature) - temperature -= (10 + 40*emagged) - else - temperature += (10 + 40*emagged) - else - temperature = target_temperature - update_icon() - - if (istype(loc, /mob/living/carbon)) - var /mob/living/carbon/M = loc - if (src == M.machine) - update_dat() - M << browse("Temperature Gun Configuration
[dat]", "window=tempgun;size=510x102") - - - if(power_supply) - power_supply.give(50) - update_icon() - return - -/obj/item/weapon/gun/energy/temperature/proc/update_dat() - dat = "" - dat += "Current output temperature: " - if(temperature > 500) - dat += "[temperature] ([round(temperature-T0C)]°C)" - dat += " SEARING!" - else if(temperature > (T0C + 50)) - dat += "[temperature] ([round(temperature-T0C)]°C)" - else if(temperature > (T0C - 50)) - dat += "[temperature] ([round(temperature-T0C)]°C)" - else - dat += "[temperature] ([round(temperature-T0C)]°C)" - dat += "
" - dat += "Target output temperature: " //might be string idiocy, but at least it's easy to read - dat += "- " - dat += "- " - dat += "- " - dat += "[target_temperature] " - dat += "+ " - dat += "+ " - dat += "+" - dat += "
" - dat += "Power cost: " - dat += "[powercost]" - -/obj/item/weapon/gun/energy/temperature/proc/update_temperature() - switch(temperature) - if(501 to INFINITY) - item_state = "tempgun_8" - if(400 to 500) - item_state = "tempgun_7" - if(360 to 400) - item_state = "tempgun_6" - if(335 to 360) - item_state = "tempgun_5" - if(295 to 335) - item_state = "tempgun_4" - if(260 to 295) - item_state = "tempgun_3" - if(200 to 260) - item_state = "tempgun_2" - if(120 to 260) - item_state = "tempgun_1" - if(-INFINITY to 120) - item_state = "tempgun_0" - icon_state = item_state - -/obj/item/weapon/gun/energy/temperature/proc/update_charge() - var/charge = power_supply.charge - switch(charge) - if(900 to INFINITY) overlays += "900" - if(800 to 900) overlays += "800" - if(700 to 800) overlays += "700" - if(600 to 700) overlays += "600" - if(500 to 600) overlays += "500" - if(400 to 500) overlays += "400" - if(300 to 400) overlays += "300" - if(200 to 300) overlays += "200" - if(100 to 200) overlays += "100" - if(-INFINITY to 100) overlays += "0" - -/obj/item/weapon/gun/energy/temperature/proc/update_user() - if (istype(loc,/mob/living/carbon)) - var/mob/living/carbon/M = loc - M.update_inv_back() - M.update_inv_l_hand() - M.update_inv_r_hand() - -/obj/item/weapon/gun/energy/temperature/update_icon() - overlays = 0 - update_temperature() - update_user() - update_charge() \ No newline at end of file diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm new file mode 100644 index 00000000000..5abac9ebad9 --- /dev/null +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -0,0 +1,54 @@ +/obj/item/weapon/gun/grenadelauncher + name = "grenade launcher" + desc = "a terrible, terrible thing. it's really awful!" + icon = 'icons/obj/guns/projectile.dmi' + icon_state = "riotgun" + item_state = "riotgun" + w_class = 4 + throw_speed = 2 + throw_range = 10 + force = 5 + var/list/grenades = new/list() + var/max_grenades = 3 + + materials = list(MAT_METAL=2000) + +/obj/item/weapon/gun/grenadelauncher/examine(mob/user) + if(..(user, 2)) + to_chat(user, "[grenades.len] / [max_grenades] grenades.") + +/obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) + if((istype(I, /obj/item/weapon/grenade))) + if(grenades.len < max_grenades) + if(!user.unEquip(I)) + return + I.loc = src + grenades += I + to_chat(user, "You put the grenade in the [name].") + to_chat(user, "[grenades.len] / [max_grenades] grenades.") + else + to_chat(user, "The grenade launcher cannot hold more grenades.") + +/obj/item/weapon/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) + if(target == user) + return + + if(grenades.len) + fire_grenade(target,user) + else + to_chat(user, "The grenade launcher is empty.") + +/obj/item/weapon/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) + user.visible_message("[user] fired a grenade!", \ + "You fire the grenade launcher!") + var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! + grenades -= F + F.loc = user.loc + F.throw_at(target, 30, 2, user) + message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([name]).") + log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([name]).") + F.active = 1 + F.icon_state = initial(icon_state) + "_active" + playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) + spawn(15) + F.prime() diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 13f92bcef86..0c7f54bb21a 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -1,35 +1,29 @@ /obj/item/weapon/gun/magic name = "staff of nothing" desc = "This staff is boring to watch because even though it came first you've seen everything it can do in other staves for years." - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/magic.dmi' icon_state = "staffofnothing" item_state = "staff" - lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands - righthand_file = 'icons/mob/inhands/items_righthand.dmi' fire_sound = 'sound/weapons/emitter.ogg' + fire_sound_text = "energy blast" flags = CONDUCT w_class = 5 - var/projectile_type = /obj/item/projectile/magic var/max_charges = 6 var/charges = 0 var/recharge_rate = 4 var/charge_tick = 0 var/can_charge = 1 + var/ammo_type var/no_den_usage origin_tech = null clumsy_check = 0 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead -/obj/item/weapon/gun/magic/emp_act(severity) - return + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' //not really a gun and some toys use these inhands + righthand_file = 'icons/mob/inhands/items_righthand.dmi' -/obj/item/weapon/gun/magic/process_chambered() - if(in_chamber) return 1 - if(!charges) return 0 - if(!projectile_type) return 0 - in_chamber = new projectile_type(src) - return 1 - -/obj/item/weapon/gun/magic/afterattack(atom/target as mob, mob/living/user as mob, flag) +/obj/item/weapon/gun/magic/afterattack(atom/target, mob/living/user, flag) + newshot() if(no_den_usage) var/area/A = get_area(user) if(istype(A, /area/wizard_station)) @@ -38,22 +32,38 @@ else no_den_usage = 0 ..() - if(charges && !in_chamber && !flag) charges-- + +/obj/item/weapon/gun/magic/can_shoot() + return charges + +/obj/item/weapon/gun/magic/newshot(params) + if (charges && chambered) + chambered.newshot(params) + return + +/obj/item/weapon/gun/magic/process_chamber() + if(chambered && !chambered.BB) //if BB is null, i.e the shot has been fired... + charges--//... drain a charge + return /obj/item/weapon/gun/magic/New() ..() charges = max_charges - if(can_charge) processing_objects.Add(src) + chambered = new ammo_type(src) + if(can_charge) + processing_objects.Add(src) /obj/item/weapon/gun/magic/Destroy() - if(can_charge) processing_objects.Remove(src) + if(can_charge) + processing_objects.Remove(src) return ..() /obj/item/weapon/gun/magic/process() charge_tick++ - if(charge_tick < recharge_rate || charges >= max_charges) return 0 + if(charge_tick < recharge_rate || charges >= max_charges) + return 0 charge_tick = 0 charges++ return 1 @@ -63,4 +73,9 @@ /obj/item/weapon/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "The [name] whizzles quietly.") - return \ No newline at end of file + return + +/obj/item/weapon/gun/magic/suicide_act(mob/user) + user.visible_message("[user] is twisting the [name] above \his head, releasing a magical blast! It looks like \he's trying to commit suicide.") + playsound(loc, fire_sound, 50, 1, -1) + return FIRELOSS diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index 16fc552397d..9ef7de7f369 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -1,52 +1,65 @@ -obj/item/weapon/gun/magic/staff/ +/obj/item/weapon/gun/magic/staff slot_flags = SLOT_BACK + ammo_type = /obj/item/ammo_casing/magic -obj/item/weapon/gun/magic/staff/change +/obj/item/weapon/gun/magic/staff/change name = "staff of change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" - projectile_type = "/obj/item/projectile/magic/change" + ammo_type = /obj/item/ammo_casing/magic/change icon_state = "staffofchange" item_state = "staffofchange" -obj/item/weapon/gun/magic/staff/animate +/obj/item/weapon/gun/magic/staff/animate name = "staff of animation" desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - projectile_type = "/obj/item/projectile/magic/animate" + ammo_type = /obj/item/ammo_casing/magic/animate icon_state = "staffofanimation" item_state = "staffofanimation" -obj/item/weapon/gun/magic/staff/healing +/obj/item/weapon/gun/magic/staff/healing name = "staff of healing" desc = "An artefact that spits bolts of restoring magic which can remove ailments of all kinds and even raise the dead." - projectile_type = "/obj/item/projectile/magic/resurrection" + ammo_type = /obj/item/ammo_casing/magic/heal icon_state = "staffofhealing" item_state = "staffofhealing" -obj/item/weapon/gun/magic/staff/chaos +/obj/item/weapon/gun/magic/staff/healing/handle_suicide() //Stops people trying to commit suicide to heal themselves + return + +/obj/item/weapon/gun/magic/staff/chaos name = "staff of chaos" desc = "An artefact that spits bolts of chaotic magic that can potentially do anything." - projectile_type = "/obj/item/projectile/magic" + ammo_type = /obj/item/ammo_casing/magic/chaos icon_state = "staffofchaos" item_state = "staffofchaos" max_charges = 10 recharge_rate = 2 - no_den_usage = 1 -/obj/item/weapon/gun/magic/staff/chaos/process_chambered() //Snowflake proc, because this uses projectile_type instead of ammo_casing for whatever reason. - projectile_type = pick(typesof(/obj/item/projectile/magic)) - if(in_chamber) return 1 - if(!charges) return 0 - in_chamber = new projectile_type(src) - return 1 - -obj/item/weapon/gun/magic/staff/door +/obj/item/weapon/gun/magic/staff/door name = "staff of door creation" desc = "An artefact that spits bolts of transformative magic that can create doors in walls." - projectile_type = "/obj/item/projectile/magic/door" + ammo_type = /obj/item/ammo_casing/magic/door icon_state = "staffofdoor" item_state = "staffofdoor" max_charges = 10 recharge_rate = 2 + no_den_usage = 1 - no_den_usage = 1 \ No newline at end of file +/obj/item/weapon/gun/magic/staff/honk + name = "staff of the honkmother" + desc = "Honk" + fire_sound = "sound/items/airhorn.ogg" + ammo_type = /obj/item/ammo_casing/magic/honk + icon_state = "honker" + item_state = "honker" + max_charges = 4 + recharge_rate = 8 + +/obj/item/weapon/gun/magic/staff/focus + name = "mental focus" + desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." + icon = 'icons/obj/wizard.dmi' + icon_state = "focus" + item_state = "focus" + ammo_type = list(/obj/item/ammo_casing/forcebolt) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 6be4e0936bf..abde404e87d 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -1,21 +1,13 @@ /obj/item/weapon/gun/magic/wand/ name = "wand of nothing" desc = "It's not just a stick, it's a MAGIC stick!" - projectile_type = "/obj/item/projectile/magic" + ammo_type = /obj/item/ammo_casing/magic icon_state = "nothingwand" item_state = "wand" w_class = 2 can_charge = 0 max_charges = 100 //100, 50, 50, 34 (max charge distribution by 25%ths) var/variable_charges = 1 - var/drained = 0 - -/obj/item/projectile/magic/fireball/Range() - var/mob/living/L = locate(/mob/living) in (range(src, 1) - firer) - if(L && L.stat != DEAD) - Bump(L) //Magic Bullet #teachthecontroversy - return - ..() /obj/item/weapon/gun/magic/wand/New() if(prob(75) && variable_charges) //25% chance of listed max charges, 50% chance of 1/2 max charges, 25% chance of 1/3 max charges @@ -26,26 +18,21 @@ ..() /obj/item/weapon/gun/magic/wand/examine(mob/user) - ..(user) + ..() to_chat(user, "Has [charges] charge\s remaining.") -/obj/item/weapon/gun/magic/wand/attack_self(mob/living/user as mob) - if(charges) - zap_self(user) - else - to_chat(user, "The [name] whizzles quietly.") - ..() +/obj/item/weapon/gun/magic/wand/update_icon() + icon_state = "[initial(icon_state)][charges ? "" : "-drained"]" -/obj/item/weapon/gun/magic/wand/attack(atom/target as mob, mob/living/user as mob) + +/obj/item/weapon/gun/magic/wand/attack(atom/target, mob/living/user) if(target == user) return ..() -/obj/item/weapon/gun/magic/wand/afterattack(atom/target as mob, mob/living/user as mob) - if(!charges && !drained) - to_chat(user, "The [name] whizzles quietly.") - icon_state = "[icon_state]-drained" - drained = 1 +/obj/item/weapon/gun/magic/wand/afterattack(atom/target, mob/living/user) + if(!charges) + shoot_with_empty_chamber(user) return if(target == user) if(no_den_usage) @@ -53,74 +40,83 @@ if(istype(A, /area/wizard_station)) to_chat(user, "You know better than to violate the security of The Den, best wait until you leave to use [src].") return - else - no_den_usage = 0 + else + no_den_usage = 0 zap_self(user) else ..() + update_icon() -/obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user as mob) - user.visible_message("[user] zaps \himself with [src]!") +/obj/item/weapon/gun/magic/wand/proc/zap_self(mob/living/user) + user.visible_message("[user] zaps \himself with [src].") + playsound(user, fire_sound, 50, 1) + user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] zapped \himself with a [src]" + +///////////////////////////////////// +//WAND OF DEATH +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/death name = "wand of death" desc = "This deadly wand overwhelms the victim's body with pure energy, slaying them without fail." - projectile_type = "/obj/item/projectile/magic/death" + ammo_type = /obj/item/ammo_casing/magic/death icon_state = "deathwand" max_charges = 3 //3, 2, 2, 1 -/obj/item/weapon/gun/magic/wand/death/zap_self(mob/living/user as mob) - if(alert(user, "You really want to zap yourself with the wand of death?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - var/message ="You irradiate yourself with pure energy! " - message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") - to_chat(user, message) - user.adjustOxyLoss(500) - charges-- - ..() +/obj/item/weapon/gun/magic/wand/death/zap_self(mob/living/user) + var/message ="You irradiate yourself with pure energy! " + message += pick("Do not pass go. Do not collect 200 zorkmids.","You feel more confident in your spell casting skills.","You Die...","Do you want your possessions identified?") + to_chat(user, message) + user.adjustFireLoss(500) + charges-- + ..() + +///////////////////////////////////// +//WAND OF HEALING +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/resurrection name = "wand of resurrection" desc = "This wand uses healing magics to heal and revive. They are rarely utilized within the Wizard Federation for some reason." - projectile_type = "/obj/item/projectile/magic/resurrection" + ammo_type = /obj/item/ammo_casing/magic/heal icon_state = "revivewand" max_charges = 3 //3, 2, 2, 1 -/obj/item/weapon/gun/magic/wand/resurrection/zap_self(mob/living/user as mob) - user.setToxLoss(0) - user.setOxyLoss(0) - user.setCloneLoss(0) - user.SetParalysis(0) - user.SetStunned(0) - user.SetWeakened(0) - user.radiation = 0 - user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss()) - user.reagents.clear_reagents() +/obj/item/weapon/gun/magic/wand/resurrection/zap_self(mob/living/user) + user.revive() to_chat(user, "You feel great!") charges-- ..() +///////////////////////////////////// +//WAND OF POLYMORPH +///////////////////////////////////// + /obj/item/weapon/gun/magic/wand/polymorph name = "wand of polymorph" desc = "This wand is attuned to chaos and will radically alter the victim's form." - projectile_type = "/obj/item/projectile/magic/change" + ammo_type = /obj/item/ammo_casing/magic/change icon_state = "polywand" max_charges = 10 //10, 5, 5, 4 -/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user as mob) - if(alert(user, "Your new form might not have arms to zap with... Continue?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - ..() //because the user mob ceases to exists by the time wabbajack fully resolves - wabbajack(user) - charges-- +/obj/item/weapon/gun/magic/wand/polymorph/zap_self(mob/living/user) + ..() //because the user mob ceases to exists by the time wabbajack fully resolves + wabbajack(user) + charges-- + +///////////////////////////////////// +//WAND OF TELEPORTATION +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/teleport name = "wand of teleportation" desc = "This wand will wrench targets through space and time to move them somewhere else." - projectile_type = "/obj/item/projectile/magic/teleport" + ammo_type = /obj/item/ammo_casing/magic/teleport icon_state = "telewand" max_charges = 10 //10, 5, 5, 4 no_den_usage = 1 -/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user as mob) +/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user) do_teleport(user, user, 10) var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread() smoke.set_up(10, 0, user.loc) @@ -128,25 +124,34 @@ charges-- ..() +///////////////////////////////////// +//WAND OF DOOR CREATION +///////////////////////////////////// + /obj/item/weapon/gun/magic/wand/door name = "wand of door creation" desc = "This particular wand can create doors in any wall for the unscrupulous wizard who shuns teleportation magics." - projectile_type = "/obj/item/projectile/magic/door" + ammo_type = /obj/item/ammo_casing/magic/door icon_state = "doorwand" max_charges = 20 //20, 10, 10, 7 -/obj/item/weapon/gun/magic/wand/door/zap_self() - return +/obj/item/weapon/gun/magic/wand/door/zap_self(mob/living/user) + to_chat(user, "You feel vaguely more open with your feelings.") + charges-- + ..() + +///////////////////////////////////// +//WAND OF FIREBALL +///////////////////////////////////// /obj/item/weapon/gun/magic/wand/fireball name = "wand of fireball" desc = "This wand shoots scorching balls of fire that explode into destructive flames." - projectile_type = "/obj/item/projectile/magic/fireball" + ammo_type = /obj/item/ammo_casing/magic/fireball icon_state = "firewand" max_charges = 8 //8, 4, 4, 3 -/obj/item/weapon/gun/magic/wand/fireball/zap_self(mob/living/user as mob) - if(alert(user, "Zapping yourself with a wand of fireball is probably a bad idea, do it anyway?",, "Yes", "No") == "Yes" && charges && user.get_active_hand() == src && isliving(user)) - explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) - charges-- - ..() \ No newline at end of file +/obj/item/weapon/gun/magic/wand/fireball/zap_self(mob/living/user) + explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) + charges-- + ..() diff --git a/code/modules/projectiles/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm similarity index 91% rename from code/modules/projectiles/medbeam.dm rename to code/modules/projectiles/guns/medbeam.dm index 04f8f4b6862..032874c4918 100644 --- a/code/modules/projectiles/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/chronos.dmi' icon_state = "chronogun" item_state = "chronogun" - w_class = 3.0 + w_class = 3 var/mob/living/current_target var/last_check = 0 @@ -13,7 +13,7 @@ var/active = 0 var/datum/beam/current_beam = null - heavy_weapon = 1 + weapon_weight = WEAPON_MEDIUM /obj/item/weapon/gun/medbeam/New() ..() @@ -34,7 +34,7 @@ on_beam_release(current_target) current_target = null -/obj/item/weapon/gun/medbeam/Fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) +/obj/item/weapon/gun/medbeam/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) add_fingerprint(user) if(current_target) @@ -48,7 +48,7 @@ spawn(0) current_beam.Start() - feedback_add_details("gun_fired","[src.type]") + feedback_add_details("gun_fired","[type]") /obj/item/weapon/gun/medbeam/process() var/mob/living/carbon/human/H = loc @@ -113,4 +113,4 @@ return /obj/effect/ebeam/medical - name = "medical beam" \ No newline at end of file + name = "medical beam" diff --git a/code/modules/projectiles/guns/mounted.dm b/code/modules/projectiles/guns/mounted.dm index d0e023d0d6d..ae9c8f06d09 100644 --- a/code/modules/projectiles/guns/mounted.dm +++ b/code/modules/projectiles/guns/mounted.dm @@ -1,31 +1,30 @@ -/obj/item/weapon/gun/energy/advtaser/mounted +/obj/item/weapon/gun/energy/gun/advtaser/mounted name = "mounted taser" desc = "An arm mounted dual-mode weapon that fires electrodes and disabler shots." - icon_state = "armcannonstun" - item_state = "armcannonstun" - modifystate = "armcannonstun" + icon_state = "armcannon" force = 5 - self_recharge = 1 flags = NODROP - slot_flags = null - w_class = 5.0 + w_class = 5 can_flashlight = 0 + selfcharge = 1 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses neural signals instead -/obj/item/weapon/gun/energy/advtaser/mounted/dropped()//if somebody manages to drop this somehow... - src.loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. +/obj/item/weapon/gun/energy/gun/advtaser/mounted/dropped()//if somebody manages to drop this somehow... + ..() + loc = null//send it to nullspace to get retrieved by the implant later on. gotta cover those edge cases. /obj/item/weapon/gun/energy/laser/mounted name = "mounted laser" desc = "An arm mounted cannon that fires lethal lasers. Doesn't come with a charge beam." - icon_state = "armcannonlase" + icon_state = "armcannon" item_state = "armcannonlase" - modifystate = "armcannonlase" force = 5 - self_recharge = 1 flags = NODROP - slot_flags = null - w_class = 5.0 + w_class = 5 materials = null + selfcharge = 1 + trigger_guard = TRIGGER_GUARD_ALLOW_ALL /obj/item/weapon/gun/energy/laser/mounted/dropped() - src.loc = null \ No newline at end of file + ..() + loc = null diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index ffe2cd269b5..03519770eee 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -1,22 +1,13 @@ -#define SPEEDLOADER 0 -#define FROM_BOX 1 -#define MAGAZINE 2 - /obj/item/weapon/gun/projectile desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason" name = "projectile gun" icon_state = "pistol" origin_tech = "combat=2;materials=2" - w_class = 3.0 + w_class = 3 materials = list(MAT_METAL=1000) -// recoil = 1 - var/mag_type = "/obj/item/ammo_box/magazine/m10mm" //Removes the need for max_ammo and caliber info + + var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info var/obj/item/ammo_box/magazine/magazine -// var/obj/item/ammo_casing/chambered = null // The round (not bullet) that is in the chamber. - - - - /obj/item/weapon/gun/projectile/New() ..() @@ -26,31 +17,26 @@ update_icon() return +/obj/item/weapon/gun/projectile/update_icon() + ..() + if(current_skin) + icon_state = "[current_skin][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]" + else + icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_state ? "-sawn" : ""]" -/obj/item/weapon/gun/projectile/process_chambered(var/eject_casing = 1, var/empty_chamber = 1 ) -// if(in_chamber) -// return 1 - +/obj/item/weapon/gun/projectile/process_chamber(eject_casing = 1, empty_chamber = 1) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(isnull(AC) || !istype(AC)) - return 0 + chamber_round() + return if(eject_casing) AC.loc = get_turf(src) //Eject casing onto ground. AC.SpinAnimation(10, 1) //next gen special effects + if(empty_chamber) chambered = null chamber_round() - if(AC.BB) - if(AC.reagents && AC.BB.reagents) - var/datum/reagents/casting_reagents = AC.reagents - casting_reagents.trans_to(AC.BB, casting_reagents.total_volume) //For chemical darts/bullets - qdel(casting_reagents) - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - AC.update_icon() - return 1 - return 0 - + return /obj/item/weapon/gun/projectile/proc/chamber_round() if(chambered || !magazine) @@ -60,12 +46,16 @@ chambered.loc = src return +/obj/item/weapon/gun/projectile/can_shoot() + if(!magazine || !magazine.ammo_count(0)) + return 0 + return 1 /obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob, params) ..() if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A - if(!magazine && istype(AM, text2path(mag_type))) + if(!magazine && istype(AM, mag_type)) user.remove_from_mob(AM) magazine = AM magazine.loc = src @@ -79,13 +69,11 @@ if(istype(A, /obj/item/weapon/suppressor)) var/obj/item/weapon/suppressor/S = A if(can_suppress) - if(!silenced) - if(user.l_hand != src && user.r_hand != src) - to_chat(user, "You'll need [src] in your hands to do that.") + if(!suppressed) + if(!user.unEquip(A)) return - user.drop_item() to_chat(user, "You screw [S] onto [src].") - silenced = A + suppressed = A S.oldsound = fire_sound S.initial_w_class = w_class fire_sound = 'sound/weapons/Gunshot_silenced.ogg' @@ -101,39 +89,45 @@ return return 0 -/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob) +/obj/item/weapon/gun/projectile/attack_hand(mob/user) if(loc == user) - if(silenced && can_unsuppress) - var/obj/item/weapon/suppressor/S = silenced + if(suppressed && can_unsuppress) + var/obj/item/weapon/suppressor/S = suppressed if(user.l_hand != src && user.r_hand != src) ..() return - to_chat(user, "You unscrew [silenced] from [src].") - user.put_in_hands(silenced) + to_chat(user, "You unscrew [suppressed] from [src].") + user.put_in_hands(suppressed) fire_sound = S.oldsound w_class = S.initial_w_class - silenced = 0 + suppressed = 0 update_icon() return ..() /obj/item/weapon/gun/projectile/attack_self(mob/living/user as mob) + var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) - magazine.loc = get_turf(src.loc) + magazine.loc = get_turf(loc) user.put_in_hands(magazine) magazine.update_icon() magazine = null to_chat(user, "You pull the magazine out of \the [src]!") + else if(chambered) + AC.loc = get_turf(src) + AC.SpinAnimation(10, 1) + chambered = null + to_chat(user, "You unload the round from \the [src]'s chamber.") else to_chat(user, "There's no magazine in \the [src].") update_icon() return /obj/item/weapon/gun/projectile/examine(mob/user) - ..(user) + ..() to_chat(user, "Has [get_ammo()] round\s remaining.") -/obj/item/weapon/gun/projectile/proc/get_ammo(var/countchambered = 1) +/obj/item/weapon/gun/projectile/proc/get_ammo(countchambered = 1) var/boolets = 0 //mature var names for mature people if(chambered && countchambered) boolets++ @@ -141,12 +135,68 @@ boolets += magazine.ammo_count() return boolets +/obj/item/weapon/gun/projectile/suicide_act(mob/user) + if (chambered && chambered.BB && !chambered.BB.nodamage) + user.visible_message("[user] is putting the barrel of the [name] in \his mouth. It looks like \he's trying to commit suicide.") + sleep(25) + if(user.l_hand == src || user.r_hand == src) + process_fire(user, user, 0, zone_override = "head") + user.visible_message("[user] blows \his brains out with the [name]!") + return(BRUTELOSS) + else + user.visible_message("[user] panics and starts choking to death!") + return(OXYLOSS) + else + user.visible_message("[user] is pretending to blow \his brains out with the [name]! It looks like \he's trying to commit suicide!") + playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + return (OXYLOSS) + +/obj/item/weapon/gun/projectile/proc/sawoff(mob/user) + if(sawn_state == SAWN_OFF) + to_chat(user, "\The [src] is already shortened!") + return + user.changeNext_move(CLICK_CD_MELEE) + user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src]...") + + //if there's any live ammo inside the gun, makes it go off + if(blow_up(user)) + user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") + return + + if(do_after(user, 30, target = src)) + if(sawn_state == SAWN_OFF) + return + user.visible_message("[user] shortens \the [src]!", "You shorten \the [src].") + name = "sawn-off [name]" + desc = sawn_desc + w_class = 3 + 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 + update_icon() + return 1 + +// Sawing guns related proc +/obj/item/weapon/gun/projectile/proc/blow_up(mob/user) + . = 0 + for(var/obj/item/ammo_casing/AC in magazine.stored_ammo) + if(AC.BB) + process_fire(user, user,0) + . = 1 + /obj/item/weapon/suppressor name = "suppressor" desc = "A universal syndicate small-arms suppressor for maximum espionage." - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" item_state = "suppressor" w_class = 2 var/oldsound = null var/initial_w_class = null + +/obj/item/weapon/suppressor/specialoffer + name = "cheap suppressor" + desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." + icon = 'icons/obj/guns/projectile.dmi' + icon_state = "suppressor" diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index b56344ce039..7544ecc7b50 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -1,6 +1,5 @@ /obj/item/weapon/gun/projectile/automatic w_class = 3.0 - automatic = 1 var/alarmed = 0 var/select = 1 can_suppress = 1 @@ -11,13 +10,6 @@ /obj/item/weapon/gun/projectile/automatic/isHandgun() return 0 -/obj/item/weapon/gun/projectile/automatic/proto - name = "\improper Nanotrasen Saber SMG" - desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." - icon_state = "saber" - mag_type = "/obj/item/ammo_box/magazine/smgm9mm" - origin_tech = "combat=4;materials=2" - /obj/item/weapon/gun/projectile/automatic/update_icon() ..() overlays.Cut() @@ -25,8 +17,7 @@ overlays += "[initial(icon_state)]semi" if(select == 1) overlays += "[initial(icon_state)]burst" - icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" - return + icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/weapon/gun/projectile/automatic/attackby(var/obj/item/A as obj, mob/user as mob, params) . = ..() @@ -34,17 +25,17 @@ return if(istype(A, /obj/item/ammo_box/magazine)) var/obj/item/ammo_box/magazine/AM = A - if(istype(AM, text2path(mag_type))) + if(istype(AM, mag_type)) if(magazine) to_chat(user, "You perform a tactical reload on \the [src], replacing the magazine.") - magazine.forceMove(get_turf(src.loc)) + magazine.loc = get_turf(loc) magazine.update_icon() magazine = null else to_chat(user, "You insert the magazine into \the [src].") user.remove_from_mob(AM) magazine = AM - magazine.forceMove(src) + magazine.loc = src chamber_round() A.update_icon() update_icon() @@ -67,14 +58,22 @@ playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_icon() - return + +/obj/item/weapon/gun/projectile/automatic/can_shoot() + return get_ammo() /obj/item/weapon/gun/projectile/automatic/proc/empty_alarm() if(!chambered && !get_ammo() && !alarmed) - playsound(src.loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) + playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) update_icon() alarmed = 1 - return + +/obj/item/weapon/gun/projectile/automatic/proto + name = "\improper Nanotrasen Saber SMG" + desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." + icon_state = "saber" + mag_type = /obj/item/ammo_box/magazine/smgm9mm + origin_tech = "combat=4;materials=2" /obj/item/weapon/gun/projectile/automatic/c20r name = "\improper C-20r SMG" @@ -82,7 +81,7 @@ icon_state = "c20r" item_state = "c20r" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/smgm45" + mag_type = /obj/item/ammo_box/magazine/smgm45 fire_sound = 'sound/weapons/Gunshot_smg.ogg' fire_delay = 2 burst_size = 2 @@ -90,24 +89,21 @@ /obj/item/weapon/gun/projectile/automatic/c20r/New() ..() update_icon() - return /obj/item/weapon/gun/projectile/automatic/c20r/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) ..() empty_alarm() - return /obj/item/weapon/gun/projectile/automatic/c20r/update_icon() ..() - icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" - return + icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" /obj/item/weapon/gun/projectile/automatic/wt550 name = "security auto rifle" desc = "An outdated personal defense weapon utilized by law enforcement. The WT-550 Automatic Rifle fires 4.6x30mm rounds." icon_state = "wt550" item_state = "arg" - mag_type = "/obj/item/ammo_box/magazine/wt550m9" + mag_type = /obj/item/ammo_box/magazine/wt550m9 fire_delay = 2 can_suppress = 0 burst_size = 1 @@ -116,87 +112,22 @@ /obj/item/weapon/gun/projectile/automatic/wt550/update_icon() ..() icon_state = "wt550[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""]" - return /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "\improper 'Type U3' Uzi" desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." icon_state = "mini-uzi" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/uzim9mm" + mag_type = /obj/item/ammo_box/magazine/uzim9mm burst_size = 2 -/obj/item/weapon/gun/projectile/automatic/l6_saw - name = "\improper L6 SAW" - desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the reciever below the designation." - icon_state = "l6closed100" - item_state = "l6closedmag" - w_class = 5 - slot_flags = 0 - origin_tech = "combat=5;materials=1;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/m762" - fire_sound = 'sound/weapons/Gunshot3.ogg' - - var/cover_open = 0 - can_suppress = 0 - burst_size = 5 - fire_delay = 3 - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob) - cover_open = !cover_open - to_chat(user, "You [cover_open ? "open" : "close"] [src]'s cover.") - update_icon() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() - if(magazine && magazine.caliber != "a762") - icon_state = "l6[cover_open ? "open" : "closed"]0" - icon_state = "l6[cover_open ? "open" : "closed"][magazine ? round(magazine.ammo_count() * 2, 25) : "-empty"]" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays - if(cover_open) - to_chat(user, "[src]'s cover is open! Close it before firing!") - else - ..() - update_icon() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user as mob) - if(loc != user) - ..() - return //let them pick it up - if(!cover_open || (cover_open && !magazine)) - ..() - else if(cover_open && magazine) - //drop the mag - magazine.update_icon() - magazine.loc = get_turf(src.loc) - user.put_in_hands(magazine) - magazine = null - update_icon() - to_chat(user, "You remove the magazine from [src].") - - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob, params) - if(!cover_open && istype(A, mag_type)) - to_chat(user, "[src]'s cover is closed! You can't insert a new mag!") - return - ..() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/devastator - name = "\improper 'Devastator' LMG" - desc = "A heavily modified L6 SAW designed to chamber wide rounds. Commonly used by elite Syndicate boarding teams " - mag_type = "/obj/item/ammo_box/magazine/m762/buckshot" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/devastator/New() - ..() - mag_type = "/obj/item/ammo_box/magazine/m762" // Workaround so it spawns with a shotgun mag loaded, but can still load regular LMG mags. - /obj/item/weapon/gun/projectile/automatic/m90 name = "\improper M-90gl Carbine" desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off." icon_state = "m90" item_state = "m90" origin_tech = "combat=5;materials=2;syndicate=8" - mag_type = "/obj/item/ammo_box/magazine/m556" + mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/Gunshot_smg.ogg' action_button_name = "Toggle Grenade Launcher" can_suppress = 0 @@ -208,19 +139,17 @@ ..() underbarrel = new /obj/item/weapon/gun/projectile/revolver/grenadelauncher(src) update_icon() - return /obj/item/weapon/gun/projectile/automatic/m90/afterattack(var/atom/target, var/mob/living/user, flag, params) if(select == 2) underbarrel.afterattack(target, user, flag, params) else ..() - empty_alarm() return /obj/item/weapon/gun/projectile/automatic/m90/attackby(var/obj/item/A, mob/user, params) if(istype(A, /obj/item/ammo_casing)) - if(istype(A, text2path(underbarrel.magazine.ammo_type))) + if(istype(A, underbarrel.magazine.ammo_type)) underbarrel.attack_self() underbarrel.attackby(A, user, params) else @@ -257,7 +186,6 @@ to_chat(user, "You switch to semi-auto.") playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_icon() - return /obj/item/weapon/gun/projectile/automatic/tommygun name = "\improper Thompson SMG" @@ -267,11 +195,11 @@ w_class = 5 slot_flags = 0 origin_tech = "combat=5;materials=1;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/tommygunm45" + mag_type = /obj/item/ammo_box/magazine/tommygunm45 fire_sound = 'sound/weapons/Gunshot_smg.ogg' can_suppress = 0 - fire_delay = 1 burst_size = 4 + fire_delay = 1 /obj/item/weapon/gun/projectile/automatic/ar name = "ARG" @@ -280,8 +208,42 @@ item_state = "arg" slot_flags = 0 origin_tech = "combat=5;materials=1" - mag_type = "/obj/item/ammo_box/magazine/m556" + mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/Gunshot_smg.ogg' can_suppress = 0 burst_size = 3 fire_delay = 1 + +// Bulldog shotgun // +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog + name = "\improper 'Bulldog' Shotgun" + desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." + icon_state = "bulldog" + item_state = "bulldog" + w_class = 3.0 + origin_tech = "combat=5;materials=4;syndicate=6" + mag_type = /obj/item/ammo_box/magazine/m12g + fire_sound = 'sound/weapons/Gunshot4.ogg' + can_suppress = 0 + burst_size = 1 + fire_delay = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/New() + ..() + update_icon() + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine() + if(magazine) + overlays.Cut() + overlays += "[magazine.icon_state]" + return + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/update_icon() + overlays.Cut() + update_magazine() + icon_state = "bulldog[chambered ? "" : "-e"]" + +/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) + ..() + empty_alarm() diff --git a/code/modules/projectiles/guns/projectile/crossbow.dm b/code/modules/projectiles/guns/projectile/crossbow.dm deleted file mode 100644 index 3645899ab21..00000000000 --- a/code/modules/projectiles/guns/projectile/crossbow.dm +++ /dev/null @@ -1,323 +0,0 @@ -//AMMUNITION - -/obj/item/weapon/arrow - - name = "bolt" - desc = "It's got a tip for you - get the point?" - icon = 'icons/obj/weapons.dmi' - icon_state = "bolt" - item_state = "bolt" - throwforce = 8 - w_class = 3.0 - sharp = 1 - edge = 0 - -/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart. - return - -/obj/item/weapon/spike - name = "alloy spike" - desc = "It's about a foot of weird silver metal with a wicked point." - sharp = 1 - edge = 0 - throwforce = 5 - w_class = 2 - icon = 'icons/obj/weapons.dmi' - icon_state = "metal-rod" - item_state = "bolt" - -/obj/item/weapon/arrow/quill - - name = "vox quill" - desc = "A wickedly barbed quill from some bizarre animal." - icon_state = "quill" - item_state = "quill" - throwforce = 5 - -/obj/item/weapon/arrow/rod - - name = "metal rod" - desc = "Don't cry for me, Orithena." - icon_state = "metal-rod" - -/obj/item/weapon/arrow/rod/removed(mob/user) - if(throwforce == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow. - to_chat(user, "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow.") - var/obj/item/weapon/shard/shrapnel/S = new() - S.loc = get_turf(src) - qdel(src) - -/obj/item/weapon/arrow/baguette - name = "baguette" - desc = "Still warm from the oven!" - icon = 'icons/obj/weapons.dmi' - icon_state = "baguette" - item_state = "baguette" - throwforce = 3 - sharp = 0 - -/obj/item/weapon/gun/launcher/crossbow - - name = "powered crossbow" - desc = "A 2557AD twist on an old classic. Pick up that can." - icon_state = "crossbow" - item_state = "crossbow-solid" - fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise. -// ejectshell = 0 // No spent shells. - mouthshoot = 1 // No suiciding with this weapon, causes runtimes. - fire_sound_text = "a solid thunk" - fire_delay = 25 - - var/tension = 0 // Current draw on the bow. - var/max_tension = 5 // Highest possible tension. - var/release_speed = 5 // Speed per unit of tension. - var/obj/item/weapon/stock_parts/cell/cell = null // Used for firing superheated rods. - var/current_user // Used to check if the crossbow has changed hands since being drawn. - -/obj/item/weapon/gun/launcher/crossbow/emp_act(severity) - if(cell && severity) - cell.use(100*severity) - -/obj/item/weapon/gun/launcher/crossbow/special_check(user) - if(tension <= 0) - to_chat(user, "\red \The [src] is not drawn back!") - return 0 - return 1 - -/obj/item/weapon/gun/launcher/crossbow/update_release_force() - release_force = tension*release_speed - -/obj/item/weapon/gun/launcher/crossbow/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if(!..()) return //Only do this on a successful shot. - icon_state = "crossbow" - tension = 0 - -/obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob) - if(tension) - if(in_chamber && in_chamber.loc == src) //Just in case they click it the tick after firing. - user.visible_message("[user] relaxes the tension on [src]'s string and removes [in_chamber].","You relax the tension on [src]'s string and remove [in_chamber].") - in_chamber.loc = get_turf(src) - var/obj/item/weapon/arrow/A = in_chamber - in_chamber = null - A.removed(user) - else - user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.") - tension = 0 - icon_state = "crossbow" - else - draw(user) - -/obj/item/weapon/gun/launcher/crossbow/proc/draw(var/mob/user as mob) - - if(!in_chamber) - to_chat(user, "You don't have anything nocked to [src].") - return - - if(user.restrained()) - return - - current_user = user - user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") - tension = 1 - spawn(25) increase_tension(user) //TODO: This needs to be changed to something less shit. - -/obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob) - - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. - return - - tension++ - icon_state = "crossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - to_chat(usr, "[src] clunks as you draw the string to its maximum tension!") - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) - -/obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob, params) - if(!in_chamber) - if (istype(W,/obj/item/weapon/arrow)) - user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") - icon_state = "crossbow-nocked" - return - else if(istype(W,/obj/item/stack/rods)) - var/obj/item/stack/rods/R = W - R.use(1) - in_chamber = new /obj/item/weapon/arrow/rod(src) - in_chamber.fingerprintslast = src.fingerprintslast - in_chamber.loc = src - icon_state = "crossbow-nocked" - user.visible_message("[user] jams [in_chamber] into [src].","You jam [in_chamber] into [src].") - superheat_rod(user) - return - - if(istype(W, /obj/item/weapon/stock_parts/cell)) - if(!cell) - user.drop_item() - W.loc = src - cell = W - to_chat(user, "You jam [cell] into [src] and wire it to the firing coil.") - superheat_rod(user) - else - to_chat(user, "[src] already has a cell installed.") - - else if(istype(W, /obj/item/weapon/screwdriver)) - if(cell) - var/obj/item/C = cell - C.loc = get_turf(user) - to_chat(user, "You jimmy [cell] out of [src] with [W].") - cell = null - else - to_chat(user, "[src] doesn't have a cell installed.") - - else - ..() - -/obj/item/weapon/gun/launcher/crossbow/proc/superheat_rod(var/mob/user) - - if(!user || !cell || !in_chamber) return - if(cell.charge < 500) return - if(in_chamber.throwforce >= 15) return - if(!istype(in_chamber,/obj/item/weapon/arrow/rod)) return - - to_chat(user, "[in_chamber] plinks and crackles as it begins to glow red-hot.") - in_chamber.throwforce = 15 - in_chamber.icon_state = "metal-rod-superheated" - cell.use(500) - - -/obj/item/weapon/gun/launcher/crossbow/french - name = "french powered crossbow" - -/obj/item/weapon/gun/launcher/crossbow/french/attackby(obj/item/W as obj, mob/user as mob, params) - if(!in_chamber) - if (istype(W,/obj/item/weapon/reagent_containers/food/snacks/baguette)) - user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") - icon_state = "crossbow-nocked" - return - - else if (istype(W,/obj/item/weapon/arrow)) - user.visible_message("\The [src] only takes baguettes.") - return - else if(istype(W,/obj/item/stack/rods)) - user.visible_message("\The [src] only takes baguettes.") - return - - if(istype(W, /obj/item/weapon/stock_parts/cell)) - user.visible_message("The [src] is too simple be adapted with a cell.") - return - - else - ..() - -/obj/item/weapon/gun/launcher/crossbow/french/increase_tension(var/mob/user as mob) - - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. - return - - tension++ - icon_state = "fcrossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - to_chat(usr, "[src] clunks as you draw the string to its maximum tension!") - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) - -// Crossbow construction. -/obj/item/weapon/crossbowframe - name = "crossbow frame" - desc = "A half-finished crossbow." - icon_state = "crossbowframe0" - item_state = "crossbow-solid" - - var/buildstate = 0 - -/obj/item/weapon/crossbowframe/update_icon() - icon_state = "crossbowframe[buildstate]" - -/obj/item/weapon/crossbowframe/examine(mob/user) - ..(user) - switch(buildstate) - if(1) - to_chat(user, "It has a loose rod frame in place.") - if(2) - to_chat(user, "It has a steel backbone welded in place.") - if(3) - to_chat(user, "It has a steel backbone and a cell mount installed.") - if(4) - to_chat(user, "It has a steel backbone, plastic lath and a cell mount installed.") - if(5) - to_chat(user, "It has a steel cable loosely strung across the lath.") - -/obj/item/weapon/crossbowframe/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/stack/rods)) - if(buildstate == 0) - var/obj/item/stack/rods/R = W - if(R.amount >= 3) - R.use(3) - to_chat(user, "\blue You assemble a backbone of rods around the wooden stock.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least three rods to complete this task.") - return - else if(istype(W,/obj/item/weapon/weldingtool)) - if(buildstate == 1) - var/obj/item/weapon/weldingtool/T = W - if(T.remove_fuel(0,user)) - if(!src || !T.isOn()) return - playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) - to_chat(user, "\blue You weld the rods into place.") - buildstate++ - update_icon() - return - else if(istype(W,/obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(buildstate == 2) - if(C.amount >= 5) - C.use(5) - to_chat(user, "\blue You wire a crude cell mount into the top of the crossbow.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least five segments of cable coil to complete this task.") - return - else if(buildstate == 4) - if(C.amount >= 5) - C.use(5) - to_chat(user, "\blue You string a steel cable across the crossbow's lath.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least five segments of cable coil to complete this task.") - return - else if(istype(W,/obj/item/stack/sheet/mineral/plastic)) - if(buildstate == 3) - var/obj/item/stack/sheet/mineral/plastic/P = W - if(P.amount >= 3) - P.use(3) - to_chat(user, "\blue You assemble and install a heavy plastic lath onto the crossbow.") - buildstate++ - update_icon() - else - to_chat(user, "\blue You need at least three plastic sheets to complete this task.") - return - else if(istype(W,/obj/item/weapon/screwdriver)) - if(buildstate == 5) - to_chat(user, "\blue You secure the crossbow's various parts.") - new /obj/item/weapon/gun/launcher/crossbow(get_turf(src)) - qdel(src) - return - else - ..() diff --git a/code/modules/projectiles/guns/projectile/grenade launcher.dm b/code/modules/projectiles/guns/projectile/grenade launcher.dm deleted file mode 100644 index 28dc0c3a4b9..00000000000 --- a/code/modules/projectiles/guns/projectile/grenade launcher.dm +++ /dev/null @@ -1,91 +0,0 @@ -/obj/item/weapon/gun/launcher - - name = "launcher" - desc = "A device that launches things." - icon = 'icons/obj/weapons.dmi' - w_class = 5.0 - flags = CONDUCT - slot_flags = SLOT_BACK - - var/release_force = 0 - var/fire_sound_text = "a launcher firing" - -//Check if we're drawing and if the bow is loaded. -/obj/item/weapon/gun/launcher/proc/chamber_round() - return (!isnull(in_chamber)) - -//This should not fit in a combat belt or holster. -/obj/item/weapon/gun/launcher/isHandgun() - return 0 - -//Launchers are mechanical, no other impact. -/obj/item/weapon/gun/launcher/emp_act(severity) - return - -//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. -/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return - -//Override this to avoid a runtime with suicide handling. -/obj/item/weapon/gun/launcher/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - if (M == user && user.zone_sel.selecting == "mouth") - to_chat(user, "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it.") - return - ..() - -/obj/item/weapon/gun/launcher/proc/update_release_force() - return 0 - -/obj/item/weapon/gun/launcher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if (!user.IsAdvancedToolUser()) - to_chat(user, "\red You don't have the dexterity to do this!") - return 0 - - add_fingerprint(user) - - //Make sure target turfs both exist. - var/turf/curloc = get_turf(user) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return 0 - - if(!special_check(user)) - return 0 - - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - to_chat(user, "[src] is not ready to fire again!") - return 0 - - if(!chamber_round()) //CHECK - return click_empty(user) - - if(!in_chamber) - return 0 - - update_release_force() - - playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear [fire_sound_text]!") - - in_chamber.loc = get_turf(user) - in_chamber.throw_at(target,10,release_force) - - sleep(1) - - in_chamber = null - - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - - return 1 - -/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) - return \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/launchers.dm b/code/modules/projectiles/guns/projectile/launchers.dm index 6bcca0cdf68..635ab22cc8c 100644 --- a/code/modules/projectiles/guns/projectile/launchers.dm +++ b/code/modules/projectiles/guns/projectile/launchers.dm @@ -1,44 +1,12 @@ //KEEP IN MIND: These are different from gun/grenadelauncher. These are designed to shoot premade rocket and grenade projectiles, not flashbangs or chemistry casings etc. //Put handheld rocket launchers here if someone ever decides to make something so hilarious ~Paprika - -/obj/item/weapon/gun/projectile/automatic/gyropistol - name = "gyrojet pistol" - desc = "A prototype pistol designed to fire self propelled rockets." - icon_state = "gyropistol" - fire_sound = 'sound/effects/Explosion1.ogg' - origin_tech = "combat=3" - mag_type = "/obj/item/ammo_box/magazine/m75" - burst_size = 1 - fire_delay = 0 - -/obj/item/weapon/gun/projectile/automatic/gyropistol/isHandgun() - return 1 - -/obj/item/weapon/gun/projectile/automatic/gyropistol/New() - ..() - update_icon() - return - -/obj/item/weapon/gun/projectile/automatic/gyropistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!chambered && !get_ammo() && !alarmed) - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - alarmed = 1 - return - -/obj/item/weapon/gun/projectile/automatic/gyropistol/update_icon() - ..() - icon_state = "[initial(icon_state)][magazine ? "loaded" : ""]" - return - /obj/item/weapon/gun/projectile/revolver/grenadelauncher//this is only used for underbarrel grenade launchers at the moment, but admins can still spawn it if they feel like being assholes desc = "A break-operated grenade launcher." name = "grenade launcher" icon_state = "dshotgun-sawn" item_state = "gun" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher fire_sound = 'sound/weapons/grenadelaunch.ogg' w_class = 3 @@ -52,7 +20,7 @@ name = "multi grenade launcher" icon_state = "bulldog" item_state = "bulldog" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher/multi /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg desc = "A 6-shot grenade launcher." @@ -60,4 +28,57 @@ icon_state = "mecha_grenadelnchr" /obj/item/weapon/gun/projectile/revolver/grenadelauncher/multi/cyborg/attack_self() - return \ No newline at end of file + return + +/obj/item/weapon/gun/projectile/automatic/gyropistol + name = "gyrojet pistol" + desc = "A prototype pistol designed to fire self propelled rockets." + icon_state = "gyropistol" + fire_sound = 'sound/effects/Explosion1.ogg' + origin_tech = "combat=3" + mag_type = /obj/item/ammo_box/magazine/m75 + burst_size = 1 + fire_delay = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/gyropistol/isHandgun() + return 1 + +/obj/item/weapon/gun/projectile/automatic/gyropistol/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/gyropistol/update_icon() + ..() + icon_state = "[initial(icon_state)][magazine ? "loaded" : ""]" + return + +/obj/item/weapon/gun/projectile/automatic/speargun + name = "kinetic speargun" + desc = "A weapon favored by carp hunters. Fires specialized spears using kinetic energy." + icon_state = "speargun" + item_state = "speargun" + w_class = 4 + force = 10 + can_suppress = 0 + mag_type = /obj/item/ammo_box/magazine/internal/speargun + fire_sound = 'sound/weapons/grenadelaunch.ogg' + burst_size = 1 + fire_delay = 0 + select = 0 + action_button_name = null + +/obj/item/weapon/gun/projectile/automatic/speargun/update_icon() + return + +/obj/item/weapon/gun/projectile/automatic/speargun/attack_self() + return + +/obj/item/weapon/gun/projectile/automatic/speargun/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/speargun/attackby(obj/item/A, mob/user, params) + var/num_loaded = magazine.attackby(A, user, params, 1) + if(num_loaded) + to_chat(user, "You load [num_loaded] spear\s into \the [src].") + update_icon() + chamber_round() diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index 99aded2663b..b2c0aa823be 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -4,27 +4,26 @@ icon_state = "pistol" w_class = 2 origin_tech = "combat=2;materials=2;syndicate=2" - mag_type = "/obj/item/ammo_box/magazine/m10mm" + mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = 1 burst_size = 1 fire_delay = 0 action_button_name = null - + /obj/item/weapon/gun/projectile/automatic/pistol/isHandgun() return 1 /obj/item/weapon/gun/projectile/automatic/pistol/update_icon() ..() - icon_state = "[initial(icon_state)][chambered ? "" : "-e"][silenced ? "-suppressed" : ""]" + icon_state = "[initial(icon_state)][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]" return -/obj/item/weapon/gun/projectile/automatic/pistol/m2411 - name = "M2411" - desc = "John Browning's classic updated for the modern day. Uses .45 rounds." - icon_state = "m2411" - w_class = 3.0 - origin_tech = "combat=3;materials=2" - mag_type = "/obj/item/ammo_box/magazine/m45" +/obj/item/weapon/gun/projectile/automatic/pistol/m1911 + name = "\improper M1911" + desc = "A classic .45 handgun with a small magazine capacity." + icon_state = "m1911" + w_class = 3 + mag_type = /obj/item/ammo_box/magazine/m45 can_suppress = 0 /obj/item/weapon/gun/projectile/automatic/pistol/deagle @@ -32,7 +31,7 @@ desc = "A robust .50 AE handgun." icon_state = "deagle" force = 14.0 - mag_type = "/obj/item/ammo_box/magazine/m50" + mag_type = /obj/item/ammo_box/magazine/m50 can_suppress = 0 /obj/item/weapon/gun/projectile/automatic/pistol/deagle/update_icon() @@ -47,4 +46,16 @@ /obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo." icon_state = "deaglecamo" - item_state = "deagleg" \ No newline at end of file + item_state = "deagleg" + +/obj/item/weapon/gun/projectile/automatic/pistol/APS + name = "stechkin APS pistol" + desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo." + icon_state = "aps" + w_class = 3 + origin_tech = "combat=3;materials=2;syndicate=3" + mag_type = /obj/item/ammo_box/magazine/pistolm9mm + can_suppress = 0 + burst_size = 3 + fire_delay = 2 + action_button_name = "Toggle Firemode" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 2cb3c849e4b..e6868110d0f 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -2,57 +2,80 @@ name = "\improper .357 revolver" desc = "A suspicious revolver. Uses .357 ammo." icon_state = "revolver" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder -/obj/item/weapon/gun/projectile/revolver/chamber_round() - if (chambered || !magazine) - return - else if (magazine.ammo_count()) +/obj/item/weapon/gun/projectile/revolver/New() + ..() + if(!istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) + verbs -= /obj/item/weapon/gun/projectile/revolver/verb/spin + +/obj/item/weapon/gun/projectile/revolver/chamber_round(var/spin = 1) + if(spin) chambered = magazine.get_round(1) + else + chambered = magazine.stored_ammo[1] return -/obj/item/weapon/gun/projectile/revolver/process_chambered() +/obj/item/weapon/gun/projectile/revolver/shoot_with_empty_chamber(mob/living/user as mob|obj) + ..() + chamber_round(1) + +/obj/item/weapon/gun/projectile/revolver/process_chamber() return ..(0, 1) -/obj/item/weapon/gun/projectile/revolver/attackby(var/obj/item/A as obj, mob/user as mob, params) - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_box)) - var/obj/item/ammo_box/AM = A - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - var/didload = magazine.give_round(AC) - if(didload) - AM.stored_ammo -= AC - num_loaded++ - if(!didload || !magazine.multiload) - break - if(istype(A, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/AC = A - if(magazine.give_round(AC)) - user.drop_item() - AC.loc = src - num_loaded++ +/obj/item/weapon/gun/projectile/revolver/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + var/num_loaded = magazine.attackby(A, user, params, 1) if(num_loaded) - to_chat(user, "You load [num_loaded] shell\s into \the [src]!") + to_chat(user, "You load [num_loaded] shell\s into \the [src].") A.update_icon() update_icon() - chamber_round() + chamber_round(0) -/obj/item/weapon/gun/projectile/revolver/attack_self(mob/living/user as mob) + if(unique_rename) + if(istype(A, /obj/item/weapon/pen)) + rename_gun(user) + +/obj/item/weapon/gun/projectile/revolver/attack_self(mob/living/user) var/num_unloaded = 0 + chambered = null while (get_ammo() > 0) var/obj/item/ammo_casing/CB CB = magazine.get_round(0) - chambered = null - CB.loc = get_turf(src.loc) - CB.SpinAnimation(10, 1) - CB.update_icon() - num_unloaded++ + if(CB) + CB.loc = get_turf(loc) + CB.SpinAnimation(10, 1) + CB.update_icon() + num_unloaded++ if (num_unloaded) - to_chat(user, "You unload [num_unloaded] shell\s from [src]!") + to_chat(user, "You unload [num_unloaded] shell\s from [src].") else - to_chat(user, "[src] is empty.") + to_chat(user, "[src] is empty!") -/obj/item/weapon/gun/projectile/revolver/get_ammo(var/countchambered = 0, var/countempties = 1) +/obj/item/weapon/gun/projectile/revolver/verb/spin() + set name = "Spin Chamber" + set category = "Object" + set desc = "Click to spin your revolver's chamber." + + var/mob/M = usr + + if(M.stat || !in_range(M,src)) + return + + if(istype(magazine, /obj/item/ammo_box/magazine/internal/cylinder)) + var/obj/item/ammo_box/magazine/internal/cylinder/C = magazine + C.spin() + chamber_round(0) + usr.visible_message("[usr] spins [src]'s chamber.", "You spin [src]'s chamber.") + else + verbs -= /obj/item/weapon/gun/projectile/revolver/verb/spin + +/obj/item/weapon/gun/projectile/revolver/can_shoot() + return get_ammo(0,0) + +/obj/item/weapon/gun/projectile/revolver/get_ammo(countchambered = 0, countempties = 1) var/boolets = 0 //mature var names for mature people if (chambered && countchambered) boolets++ @@ -61,119 +84,66 @@ return boolets /obj/item/weapon/gun/projectile/revolver/examine(mob/user) - ..(user) + ..() to_chat(user, "[get_ammo(0,0)] of those are live rounds.") -/obj/item/weapon/gun/projectile/revolver/verb/spin_revolver() - set name = "Spin cylinder" - set desc = "Fun when you're bored out of your skull." - set category = "Object" - - usr.visible_message("[usr] spins the chamber of the revolver.", "You spin the revolver's chamber.") - playsound(src.loc, 'sound/weapons/revolver_spin.ogg', 100, 1) - Spin() - -/obj/item/weapon/gun/projectile/revolver/proc/Spin() - chambered = null - var/random = rand(1, magazine.max_ammo) - if(random <= get_ammo(0,0)) - chamber_round() - update_icon() - -/obj/item/weapon/gun/projectile/revolver/capgun - name = "cap gun" - desc = "Looks almost like the real thing! Ages 8 and up." - origin_tech = "combat=1;materials=1" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/cap" - /obj/item/weapon/gun/projectile/revolver/detective desc = "A cheap Martian knock-off of a classic law enforcement firearm. Uses .38-special rounds." name = "\improper .38 Mars Special" icon_state = "detective" origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/rev38" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 + unique_rename = 1 + unique_reskin = 1 - -/obj/item/weapon/gun/projectile/revolver/detective/special_check(var/mob/living/carbon/human/M) - if(!ghettomodded) - return 1 - if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 - to_chat(M, "[src] blows up in your face!") - M.take_organ_damage(0,20) - M.drop_item() - qdel(src) - return 0 - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() - set name = "Name Gun" - set category = "Object" - set desc = "Click to rename your gun." - - var/mob/M = usr - var/input = stripped_input(M,"What do you want to name the gun?", ,"", MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src)) - name = input - to_chat(M, "You name the gun [input]. Say hello to your new friend.") - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/verb/reskin_gun() - set name = "Reskin gun" - set category = "Object" - set desc = "Click to reskin your gun." - - var/mob/M = usr - var/list/options = list() +/obj/item/weapon/gun/projectile/revolver/detective/New() + ..() options["The Original"] = "detective" options["Leopard Spots"] = "detective_leopard" options["Black Panther"] = "detective_panther" options["Gold Trim"] = "detective_gold" options["The Peacemaker"] = "detective_peacemaker" - var/choice = input(M,"What do you want to skin the gun to?","Reskin Gun") in options + options["Cancel"] = null - if(src && choice && !M.stat && in_range(M,src)) - icon_state = options[choice] - to_chat(M, "Your gun is now skinned as [choice]. Say hello to your new friend.") - return 1 - -/obj/item/weapon/gun/projectile/revolver/detective/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/revolver/detective/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "") + if(magazine.caliber != initial(magazine.caliber)) + if(prob(70 - (magazine.ammo_count() * 10))) //minimum probability of 10, maximum of 60 + playsound(user, fire_sound, 50, 1) + to_chat(user, "[src] blows up in your face!") + user.take_organ_damage(0,20) + user.unEquip(src) + return 0 ..() - if(istype(A, /obj/item/weapon/screwdriver) || istype(A, /obj/item/weapon/conversion_kit)) + +/obj/item/weapon/gun/projectile/revolver/detective/attackby(obj/item/A, mob/user, params) + ..() + if(istype(A, /obj/item/weapon/screwdriver)) if(magazine.caliber == "38") - to_chat(user, "You begin to reinforce the barrel of [src].") + to_chat(user, "You begin to reinforce the barrel of [src]...") if(magazine.ammo_count()) afterattack(user, user) //you know the drill - user.visible_message("[src] goes off!", "[src] goes off in your face!") + user.visible_message("[src] goes off!", "[src] goes off in your face!") return if(do_after(user, 30, target = src)) if(magazine.ammo_count()) - to_chat(user, "You can't modify it!") + to_chat(user, "You can't modify it!") return - if (istype(A, /obj/item/weapon/conversion_kit)) - ghettomodded = 0 - else - ghettomodded = 1 magazine.caliber = "357" - desc = "[initial(desc)] The barrel and chamber assembly seems to have been modified." - to_chat(user, "You reinforce the barrel of [src]! Now it will fire .357 rounds.") + desc = "The barrel and chamber assembly seems to have been modified." + to_chat(user, "You reinforce the barrel of [src]. Now it will fire .357 rounds.") else - to_chat(user, "You begin to revert the modifications to [src].") + to_chat(user, "You begin to revert the modifications to [src]...") if(magazine.ammo_count()) afterattack(user, user) //and again - user.visible_message("[src] goes off!", "[src] goes off in your face!") + user.visible_message("[src] goes off!", "[src] goes off in your face!") return if(do_after(user, 30, target = src)) if(magazine.ammo_count()) - to_chat(user, "You can't modify it!") + to_chat(user, "You can't modify it!") return - ghettomodded = 0 magazine.caliber = "38" desc = initial(desc) - to_chat(user, "You remove the modifications on [src]! Now it will fire .38 rounds.") - - - + to_chat(user, "You remove the modifications on [src]. Now it will fire .38 rounds.") /obj/item/weapon/gun/projectile/revolver/mateba name = "\improper Unica 6 auto-revolver" @@ -181,6 +151,21 @@ icon_state = "mateba" origin_tech = "combat=2;materials=2" +/obj/item/weapon/gun/projectile/revolver/golden + name = "\improper Golden revolver" + desc = "This ain't no game, ain't never been no show, And I'll gladly gun down the oldest lady you know. Uses .357 ammo." + icon_state = "goldrevolver" + fire_sound = 'sound/weapons/resonator_blast.ogg' + recoil = 8 + +/obj/item/weapon/gun/projectile/revolver/nagant + name = "nagant revolver" + desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo." + icon_state = "nagant" + origin_tech = "combat=3" + can_suppress = 1 + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762 + // A gun to play Russian Roulette! // You can spin the chamber to randomize the position of the bullet. @@ -188,35 +173,239 @@ name = "\improper Russian Revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism that spins the chamber before each trigger pull." origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/rus357" + mag_type = /obj/item/ammo_box/magazine/internal/rus357 + var/spun = 0 /obj/item/weapon/gun/projectile/revolver/russian/New() ..() Spin() + update_icon() -/obj/item/weapon/gun/projectile/revolver/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj) +/obj/item/weapon/gun/projectile/revolver/russian/proc/Spin() + chambered = null + var/random = rand(1, magazine.max_ammo) + if(random <= get_ammo(0,0)) + chamber_round() + spun = 1 - if(!chambered && target == user) - user.visible_message("\red *click*", "\red *click*") - return +/obj/item/weapon/gun/projectile/revolver/russian/attackby(obj/item/A, mob/user, params) + var/num_loaded = ..() + if(num_loaded) + user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "You load a single bullet into the chamber and spin it.") + else + user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") + if(get_ammo() > 0) + Spin() + update_icon() + A.update_icon() + return - if(isliving(target) && isliving(user)) - if(target == user) - var/obj/item/organ/external/affecting = user.zone_sel.selecting - if(affecting == "head") - var/obj/item/ammo_casing/AC = chambered - if(!process_chambered()) - user.visible_message("\red *click*", "\red *click*") - return - if(!in_chamber) - return - var/obj/item/projectile/P = new AC.projectile_type - playsound(user, fire_sound, 50, 1) - user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - if(!P.nodamage) - user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead. +/obj/item/weapon/gun/projectile/revolver/russian/attack_self(mob/user) + if(!spun && can_shoot()) + user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") + Spin() + else + var/num_unloaded = 0 + while (get_ammo() > 0) + var/obj/item/ammo_casing/CB + CB = magazine.get_round() + chambered = null + CB.loc = get_turf(loc) + CB.update_icon() + num_unloaded++ + if (num_unloaded) + to_chat(user, "You unload [num_unloaded] shell\s from [src].") + else + to_chat(user, "[src] is empty.") + +/obj/item/weapon/gun/projectile/revolver/russian/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) + if(flag) + if(!(target in user.contents) && ismob(target)) + if(user.a_intent == "harm") // Flogging action return - ..() + if(isliving(user)) + if(!can_trigger_gun(user)) + return + if(target != user) + if(ismob(target)) + to_chat(user, "A mechanism prevents you from shooting anyone but yourself!") + return + if(ishuman(user)) + if(!spun) + to_chat(user, "You need to spin the revolver's chamber first!") + return + + spun = 0 + + if(chambered) + var/obj/item/ammo_casing/AC = chambered + if(AC.fire(user, user)) + playsound(user, fire_sound, 50, 1) + var/zone = check_zone(user.zone_sel.selecting) + if(zone == "head" || zone == "eyes" || zone == "mouth") + shoot_self(user, zone) + else + user.visible_message("[user.name] cowardly fires [src] at \his [zone]!", "You cowardly fire [src] at your [zone]!", "You hear a gunshot!") + return + + user.visible_message("*click*") + playsound(user, 'sound/weapons/empty.ogg', 100, 1) + +/obj/item/weapon/gun/projectile/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") + user.apply_damage(300, BRUTE, affecting) + user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a gunshot!") + +/obj/item/weapon/gun/projectile/revolver/capgun + name = "cap gun" + desc = "Looks almost like the real thing! Ages 8 and up." + origin_tech = "combat=1;materials=1" + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/cap + +///////////////////////////// +// DOUBLE BARRELED SHOTGUN // +///////////////////////////// + +/obj/item/weapon/gun/projectile/revolver/doublebarrel + name = "double-barreled shotgun" + desc = "A true classic." + icon_state = "dshotgun" + item_state = "shotgun" + w_class = 4 + force = 10 + flags = CONDUCT + slot_flags = SLOT_BACK + origin_tech = "combat=3;materials=1" + mag_type = /obj/item/ammo_box/magazine/internal/shot/dual + sawn_desc = "Omar's coming!" + unique_rename = 1 + unique_reskin = 1 + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/New() + ..() + options["Default"] = "dshotgun" + options["Dark Red Finish"] = "dshotgun-d" + options["Ash"] = "dshotgun-f" + options["Faded Grey"] = "dshotgun-g" + options["Maple"] = "dshotgun-l" + options["Rosewood"] = "dshotgun-p" + options["Cancel"] = null + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(obj/item/A, mob/user, params) + ..() + if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) + chamber_round() + if(istype(A, /obj/item/weapon/melee/energy)) + var/obj/item/weapon/melee/energy/W = A + if(W.active) + sawoff(user) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) + sawoff(user) + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user) + var/num_unloaded = 0 + while (get_ammo() > 0) + var/obj/item/ammo_casing/CB + CB = magazine.get_round(0) + chambered = null + CB.loc = get_turf(loc) + CB.update_icon() + num_unloaded++ + if (num_unloaded) + to_chat(user, "You break open \the [src] and unload [num_unloaded] shell\s.") + else + to_chat(user, "[src] is empty.") + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/isHandgun() //contrary to popular opinion, double barrels are not, shockingly, handguns + return 0 + +// IMPROVISED SHOTGUN // + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised + name = "improvised shotgun" + desc = "Essentially a tube that aims shotgun shells." + icon_state = "ishotgun" + item_state = "shotgun" + w_class = 4 + force = 10 + slot_flags = null + origin_tech = "combat=2;materials=2" + mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised + sawn_desc = "I'm just here for the gasoline." + unique_rename = 0 + unique_reskin = 0 + var/slung = 0 + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(obj/item/A, mob/user, params) + ..() + if(istype(A, /obj/item/stack/cable_coil) && !sawn_state) + var/obj/item/stack/cable_coil/C = A + if(C.use(10)) + slot_flags = SLOT_BACK + icon_state = "ishotgunsling" + to_chat(user, "You tie the lengths of cable to the shotgun, making a sling.") + slung = 1 + update_icon() + else + to_chat(user, "You need at least ten lengths of cable if you want to make a sling.") + return + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/update_icon() + ..() + if (slung && (slot_flags & SLOT_BELT) ) + slung = 0 + icon_state = "ishotgun-sawn" + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/sawoff(mob/user) + . = ..() + if(. && slung) //sawing off the gun removes the sling + new /obj/item/stack/cable_coil(get_turf(src), 10) + slung = 0 + update_icon() + +//caneshotgun + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane + name = "cane" + desc = "A cane used by a true gentleman. Or a clown." + icon = 'icons/obj/weapons.dmi' + lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items_righthand.dmi' + icon_state = "cane" + item_state = "stick" + sawn_state = SAWN_OFF + w_class = 2 + force = 10 + can_unsuppress = 0 + slot_flags = null + origin_tech = "" // NO GIVAWAYS + mag_type = /obj/item/ammo_box/magazine/internal/shot/improvised + sawn_desc = "I'm sorry, but why did you saw your cane in the first place?" + attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") + fire_sound = 'sound/weapons/Gunshot_silenced.ogg' + suppressed = 1 + needs_permit = 0 //its just a cane beepsky..... + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/update_icon() + return + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params) + ..() + if(istype(A, /obj/item/stack/cable_coil)) + return + +/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH + var/f_name = "\a [src]." + if(blood_DNA && !istype(src, /obj/effect/decal)) + if(gender == PLURAL) + f_name = "some " + else + f_name = "a " + f_name += "blood-stained [name]!" + + to_chat(user, "[bicon(src)] That's [f_name]") + + if(desc) + to_chat(user, desc) diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm deleted file mode 100644 index e667d9323ce..00000000000 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ /dev/null @@ -1,50 +0,0 @@ -/obj/item/weapon/gun/rocketlauncher - var/projectile - name = "rocket launcher" - desc = "Say hello to my little friend" - icon_state = "rocket" - item_state = "rocket" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - flags = CONDUCT - origin_tech = "combat=8;materials=5" - projectile = /obj/item/missile - var/missile_speed = 2 - var/missile_range = 30 - var/max_rockets = 1 - var/list/rockets = new/list() - -/obj/item/weapon/gun/rocketlauncher/examine(mob/user) - if(..(user, 2)) - to_chat(user, "\blue [rockets.len] / [max_rockets] rockets.") - -/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob, params) - if(istype(I, /obj/item/ammo_casing/rocket)) - if(rockets.len < max_rockets) - user.drop_item() - I.loc = src - rockets += I - to_chat(user, "\blue You put the rocket in [src].") - to_chat(user, "\blue [rockets.len] / [max_rockets] rockets.") - else - to_chat(usr, "\red [src] cannot hold more rockets.") - -/obj/item/weapon/gun/rocketlauncher/can_fire() - return rockets.len - -/obj/item/weapon/gun/rocketlauncher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(rockets.len) - var/obj/item/ammo_casing/rocket/I = rockets[1] - var/obj/item/missile/M = new projectile(user.loc) - playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) - M.primed = 1 - M.throw_at(target, missile_range, missile_speed,user) - message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]).") - log_game("[key_name_admin(user)] used a rocket launcher ([src.name]).") - rockets -= I - qdel(I) - return - else - to_chat(usr, "\red [src] is empty.") diff --git a/code/modules/projectiles/guns/projectile/saw.dm b/code/modules/projectiles/guns/projectile/saw.dm new file mode 100644 index 00000000000..097f5fb4a58 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/saw.dm @@ -0,0 +1,157 @@ +/obj/item/weapon/gun/projectile/automatic/l6_saw + name = "\improper L6 SAW" + desc = "A heavily modified 7.62 light machine gun, designated 'L6 SAW'. Has 'Aussec Armoury - 2531' engraved on the reciever below the designation." + icon_state = "l6closed100" + item_state = "l6closedmag" + w_class = 5 + slot_flags = 0 + origin_tech = "combat=5;materials=1;syndicate=2" + mag_type = /obj/item/ammo_box/magazine/mm556x45 + weapon_weight = WEAPON_MEDIUM + fire_sound = 'sound/weapons/Gunshot3.ogg' + var/cover_open = 0 + can_suppress = 0 + burst_size = 3 + fire_delay = 1 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user) + cover_open = !cover_open + to_chat(user, "You [cover_open ? "open" : "close"] [src]'s cover.") + update_icon() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() + icon_state = "l6[cover_open ? "open" : "closed"][magazine ? Ceiling(get_ammo(0)/12.5)*25 : "-empty"][suppressed ? "-suppressed" : ""]" + item_state = "l6[cover_open ? "openmag" : "closedmag"]" + +/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays + if(cover_open) + to_chat(user, "[src]'s cover is open! Close it before firing!") + else + ..() + update_icon() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user) + if(loc != user) + ..() + return //let them pick it up + if(!cover_open || (cover_open && !magazine)) + ..() + else if(cover_open && magazine) + //drop the mag + magazine.update_icon() + magazine.loc = get_turf(loc) + user.put_in_hands(magazine) + magazine = null + update_icon() + to_chat(user, "You remove the magazine from [src].") + + +/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + if(!cover_open) + to_chat(user, "[src]'s cover is closed! You can't insert a new mag.") + return + ..() + +//ammo// + +/obj/item/projectile/bullet/saw + damage = 45 + armour_penetration = 5 + +/obj/item/projectile/bullet/saw/bleeding + damage = 20 + armour_penetration = 0 + +/obj/item/projectile/bullet/saw/bleeding/on_hit(atom/target, blocked = 0, hit_zone) + . = ..() + if((blocked != 100) && istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + H.drip(350) + +/obj/item/projectile/bullet/saw/hollow + damage = 60 + armour_penetration = -10 + +/obj/item/projectile/bullet/saw/ap + damage = 40 + armour_penetration = 75 + +/obj/item/projectile/bullet/saw/incen + damage = 7 + armour_penetration = 0 + +obj/item/projectile/bullet/saw/incen/Move() + ..() + var/turf/location = get_turf(src) + if(location) + PoolOrNew(/obj/effect/hotspot, location) + location.hotspot_expose(700, 50, 1) + +/obj/item/projectile/bullet/saw/incen/on_hit(atom/target, blocked = 0) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(3) + M.IgniteMob() + +//magazines// + +/obj/item/ammo_box/magazine/mm556x45 + name = "box magazine (5.56x45mm)" + icon_state = "a762-50" + origin_tech = "combat=2" + ammo_type = /obj/item/ammo_casing/mm556x45 + caliber = "mm55645" + max_ammo = 50 + +/obj/item/ammo_box/magazine/mm556x45/bleeding + name = "box magazine (Bleeding 5.56x45mm)" + origin_tech = "combat=3" + ammo_type = /obj/item/ammo_casing/mm556x45/bleeding + +/obj/item/ammo_box/magazine/mm556x45/hollow + name = "box magazine (Hollow-Point 5.56x45mm)" + origin_tech = "combat=3" + ammo_type = /obj/item/ammo_casing/mm556x45/hollow + +/obj/item/ammo_box/magazine/mm556x45/ap + name = "box magazine (Armor Penetrating 5.56x45mm)" + origin_tech = "combat=4" + ammo_type = /obj/item/ammo_casing/mm556x45/ap + +/obj/item/ammo_box/magazine/mm556x45/incen + name = "box magazine (Incendiary 5.56x45mm)" + origin_tech = "combat=4" + ammo_type = /obj/item/ammo_casing/mm556x45/incen + +/obj/item/ammo_box/magazine/mm556x45/update_icon() + ..() + icon_state = "a762-[round(ammo_count(),10)]" + +//casings// + +/obj/item/ammo_casing/mm556x45 + desc = "A 556x45mm bullet casing." + icon_state = "762-casing" + caliber = "mm55645" + projectile_type = /obj/item/projectile/bullet/saw + +/obj/item/ammo_casing/mm556x45/bleeding + desc = "A 556x45mm bullet casing with specialized inner-casing, that when it makes contact with a target, release tiny shrapnel to induce internal bleeding." + icon_state = "762-casing" + projectile_type = /obj/item/projectile/bullet/saw/bleeding + +/obj/item/ammo_casing/mm556x45/hollow + desc = "A 556x45mm bullet casing designed to cause more damage to unarmored targets." + projectile_type = /obj/item/projectile/bullet/saw/hollow + +/obj/item/ammo_casing/mm556x45/ap + desc = "A 556x45mm bullet casing designed with a hardened-tipped core to help penetrate armored targets." + projectile_type = /obj/item/projectile/bullet/saw/ap + +/obj/item/ammo_casing/mm556x45/incen + desc = "A 556x45mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames. " + projectile_type = /obj/item/projectile/bullet/saw/incen diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 7ae951ad908..ddec7543009 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -8,40 +8,34 @@ flags = CONDUCT slot_flags = SLOT_BACK origin_tech = "combat=4;materials=2" + mag_type = /obj/item/ammo_box/magazine/internal/shot var/recentpump = 0 // to prevent spammage - mag_type = "/obj/item/ammo_box/magazine/internal/shot" -/obj/item/weapon/gun/projectile/shotgun/attackby(var/obj/item/A as obj, mob/user as mob, params) - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_box)) - var/obj/item/ammo_box/AM = A - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - var/didload = magazine.give_round(AC) - if(didload) - AM.stored_ammo -= AC - num_loaded++ - if(!didload || !magazine.multiload) - break - if(istype(A, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/AC = A - if(magazine && magazine.give_round(AC)) - user.drop_item() - AC.loc = src - num_loaded++ +/obj/item/weapon/gun/projectile/shotgun/attackby(obj/item/A, mob/user, params) + . = ..() + if(.) + return + var/num_loaded = magazine.attackby(A, user, params, 1) if(num_loaded) to_chat(user, "You load [num_loaded] shell\s into \the [src]!") A.update_icon() update_icon() -/obj/item/weapon/gun/projectile/shotgun/process_chambered() +/obj/item/weapon/gun/projectile/shotgun/process_chamber() return ..(0, 0) /obj/item/weapon/gun/projectile/shotgun/chamber_round() return -/obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user as mob) - if(recentpump) return +/obj/item/weapon/gun/projectile/shotgun/can_shoot() + if(!chambered) + return 0 + return (chambered.BB ? 1 : 0) + +/obj/item/weapon/gun/projectile/shotgun/attack_self(mob/living/user) + if(recentpump) + return pump(user) recentpump = 1 spawn(10) @@ -49,7 +43,7 @@ return -/obj/item/weapon/gun/projectile/shotgun/proc/pump(mob/M as mob) +/obj/item/weapon/gun/projectile/shotgun/proc/pump(mob/M) playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) pump_unload(M) pump_reload(M) @@ -61,36 +55,41 @@ chambered.loc = get_turf(src)//Eject casing chambered.SpinAnimation(5, 1) chambered = null - if(in_chamber) - in_chamber = null /obj/item/weapon/gun/projectile/shotgun/proc/pump_reload(mob/M) - if(!magazine.ammo_count()) return 0 + if(!magazine.ammo_count()) + return 0 var/obj/item/ammo_casing/AC = magazine.get_round() //load next casing. chambered = AC /obj/item/weapon/gun/projectile/shotgun/examine(mob/user) - ..(user) + ..() if (chambered) to_chat(user, "A [chambered.BB ? "live" : "spent"] one is in the chamber.") /obj/item/weapon/gun/projectile/shotgun/isHandgun() //You cannot, in fact, holster a shotgun. return 0 +/obj/item/weapon/gun/projectile/shotgun/lethal + mag_type = /obj/item/ammo_box/magazine/internal/shot/lethal + // RIOT SHOTGUN // /obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory name = "riot shotgun" desc = "A sturdy shotgun with a longer magazine and a fixed tactical stock designed for non-lethal riot control." icon_state = "riotshotgun" - mag_type = "/obj/item/ammo_box/magazine/internal/shotriot" + mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." -/obj/item/weapon/gun/projectile/shotgun/riot/attackby(var/obj/item/A as obj, mob/user as mob, params) +/obj/item/weapon/gun/projectile/shotgun/riot/attackby(obj/item/A, mob/user, params) ..() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) sawoff(user) - + if(istype(A, /obj/item/weapon/melee/energy)) + var/obj/item/weapon/melee/energy/W = A + if(W.active) + sawoff(user) /////////////////////// // BOLT ACTION RIFLE // @@ -102,7 +101,7 @@ icon_state = "moistnugget" item_state = "moistnugget" slot_flags = 0 //no SLOT_BACK sprite, alas - mag_type = "/obj/item/ammo_box/magazine/internal/boltaction" + mag_type = /obj/item/ammo_box/magazine/internal/boltaction var/bolt_open = 0 /obj/item/weapon/gun/projectile/shotgun/boltaction/pump(mob/M) @@ -115,21 +114,27 @@ update_icon() //I.E. fix the desc return 1 -/obj/item/weapon/gun/projectile/shotgun/boltaction/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/shotgun/blow_up(mob/user) + . = 0 + if(chambered && chambered.BB) + process_fire(user, user,0) + . = 1 + +/obj/item/weapon/gun/projectile/shotgun/boltaction/attackby(obj/item/A, mob/user, params) if(!bolt_open) to_chat(user, "The bolt is closed!") return . = ..() /obj/item/weapon/gun/projectile/shotgun/boltaction/examine(mob/user) - ..(user) + ..() to_chat(user, "The bolt is [bolt_open ? "open" : "closed"].") /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted name = "enchanted bolt action rifle" desc = "Careful not to lose your head." var/guns_left = 30 - mag_type = "/obj/item/ammo_box/magazine/internal/boltaction/enchanted" + mag_type = /obj/item/ammo_box/magazine/internal/boltaction/enchanted /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/New() ..() @@ -137,13 +142,14 @@ pump() /obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/dropped() + ..() guns_left = 0 -/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/Fire(atom/target as mob|obj|turf|area, mob/living/carbon/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) ..() if(guns_left) var/obj/item/weapon/gun/projectile/shotgun/boltaction/enchanted/GUN = new - GUN.guns_left = src.guns_left - 1 + GUN.guns_left = guns_left - 1 user.drop_item() user.swap_hand() user.put_in_hands(GUN) @@ -153,205 +159,59 @@ throw_at(pick(oview(7,get_turf(user))),1,1) user.visible_message("[user] tosses aside the spent rifle!") +// Automatic Shotguns// -/obj/item/ammo_box/magazine/internal/boltaction/enchanted - max_ammo =1 +/obj/item/weapon/gun/projectile/shotgun/automatic -///////////////////////////// -// DOUBLE BARRELED SHOTGUN // -///////////////////////////// - -/obj/item/weapon/gun/projectile/revolver/doublebarrel - name = "double-barreled shotgun" - desc = "A true classic." - icon_state = "dshotgun" - item_state = "shotgun" - w_class = 4.0 - force = 10 - flags = CONDUCT - slot_flags = SLOT_BACK - origin_tech = "combat=3;materials=1" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/dualshot" - sawn_desc = "Omar's coming!" - -/obj/item/weapon/gun/projectile/revolver/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob, params) - ..() - if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing)) - chamber_round() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/gun/energy/plasmacutter)) - sawoff(user) - -/obj/item/weapon/gun/projectile/revolver/doublebarrel/attack_self(mob/living/user as mob) - var/num_unloaded = 0 - while (get_ammo() > 0) - var/obj/item/ammo_casing/CB - CB = magazine.get_round(0) - chambered = null - CB.loc = get_turf(src.loc) - CB.update_icon() - num_unloaded++ - if (num_unloaded) - to_chat(user, "You break open \the [src] and unload [num_unloaded] shell\s.") - else - to_chat(user, "[src] is empty.") - -/obj/item/weapon/gun/projectile/revolver/doublebarrel/isHandgun() //contrary to popular opinion, double barrels are not, shockingly, handguns - return 0 - -// IMPROVISED SHOTGUN // - -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised - name = "improvised shotgun" - desc = "Essentially a tube that aims shotgun shells." - icon_state = "ishotgun" - item_state = "shotgun" - w_class = 4.0 - force = 10 - slot_flags = null - origin_tech = "combat=2;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/improvised" - sawn_desc = "I'm just here for the gasoline." - -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/attackby(var/obj/item/A as obj, mob/user as mob, params) - ..() - if(istype(A, /obj/item/stack/cable_coil) && !sawn_state) - var/obj/item/stack/cable_coil/C = A - if(C.use(10)) - slot_flags = SLOT_BACK - icon_state = "ishotgunsling" - to_chat(user, "You tie the lengths of cable to the shotgun, making a sling.") - update_icon() - else - to_chat(user, "You need at least ten lengths of cable if you want to make a sling.") - return - -// Sawing guns related procs // - -/obj/item/weapon/gun/projectile/proc/blow_up(mob/user as mob) - if(get_ammo()) - afterattack(user, user) - playsound(user, fire_sound, 50, 1) - user.visible_message("The [src] goes off!", "The [src] goes off in your face!") - return - -/obj/item/weapon/gun/projectile/proc/sawoff(mob/user as mob) - if(sawn_state == SAWN_OFF) - to_chat(user, "\The [src] is already shortened.") - return - - if(sawn_state == SAWN_SAWING) - return - - user.visible_message("[user] begins to shorten \the [src].", "You begin to shorten \the [src].") - - //if there's any live ammo inside the gun, makes it go off - if(blow_up(user)) - user.visible_message("\The [src] goes off!", "\The [src] goes off in your face!") - return - - sawn_state = SAWN_SAWING - - if(do_after(user, 30, target = src)) - user.visible_message("[user] shortens \the [src]!", "You shorten \the [src]!") - name = "sawn-off [src.name]" - desc = sawn_desc - icon_state = "[icon_state]-sawn" - w_class = 3.0 - item_state = "gun" - 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 - update_icon() - return - else - sawn_state = SAWN_INTACT - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog - name = "\improper 'Bulldog' Shotgun" - desc = "A compact, mag-fed semi-automatic shotgun for combat in narrow corridors, nicknamed 'Bulldog' by boarding parties. Compatible only with specialized 8-round drum magazines." - icon_state = "bulldog" - item_state = "bulldog" - w_class = 3.0 - origin_tech = "combat=5;materials=4;syndicate=6" - mag_type = "/obj/item/ammo_box/magazine/m12g" - fire_sound = 'sound/weapons/Gunshot4.ogg' - can_suppress = 0 - burst_size = 1 - fire_delay = 0 - action_button_name = null - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/New() - ..() - update_icon() - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/proc/update_magazine() - if(magazine) - overlays.Cut() - overlays += "[magazine.icon_state]" - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/update_icon() - overlays.Cut() - update_magazine() - icon_state = "bulldog[chambered ? "" : "-e"]" - return - -/obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - empty_alarm() - return - -/obj/item/weapon/gun/projectile/shotgun/automatic/Fire(mob/living/user as mob|obj) +/obj/item/weapon/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj) ..() pump(user) -// COMBAT SHOTGUN // - /obj/item/weapon/gun/projectile/shotgun/automatic/combat name = "combat shotgun" desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath." icon_state = "cshotgun" origin_tech = "combat=5;materials=2" - mag_type = "/obj/item/ammo_box/magazine/internal/shotcom" + mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = 5 -//caneshotgun +//Dual Feed Shotgun -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane - name = "cane" - desc = "A cane used by a true gentlemen. Or a clown." - icon = 'icons/obj/weapons.dmi' - icon_state = "cane" - item_state = "stick" - sawn_state = SAWN_OFF - w_class = 2 - force = 10 - can_unsuppress = 0 - slot_flags = null - origin_tech = "" // NO GIVAWAYS - mag_type = "/obj/item/ammo_box/magazine/internal/cylinder/improvised" - sawn_desc = "I'm sorry, but why did you saw your cane in the first place?" - attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") - fire_sound = 'sound/weapons/Gunshot_silenced.ogg' - silenced = 1 - needs_permit = 0 //its just a cane beepsky..... +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube + name = "cycler shotgun" + desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types." + icon_state = "cycler" + origin_tech = "combat=4;materials=2" + mag_type = /obj/item/ammo_box/magazine/internal/shot/tube + w_class = 5 + var/toggled = 0 + var/obj/item/ammo_box/magazine/internal/shot/alternate_magazine -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/attackby(obj/item/A, mob/user, params) +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/New() ..() - if(istype(A, /obj/item/stack/cable_coil)) + if (!alternate_magazine) + alternate_magazine = new mag_type(src) + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/attack_self(mob/living/user) + if(!chambered && magazine.contents.len) + pump() + else + toggle_tube(user) + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/proc/toggle_tube(mob/living/user) + var/current_mag = magazine + var/alt_mag = alternate_magazine + magazine = alt_mag + alternate_magazine = current_mag + toggled = !toggled + if(toggled) + to_chat(user, "You switch to tube B.") + else + to_chat(user, "You switch to tube A.") + +/obj/item/weapon/gun/projectile/shotgun/automatic/dual_tube/AltClick(mob/living/user) + if(user.incapacitated() || !Adjacent(user) || !istype(user)) return + pump() -/obj/item/weapon/gun/projectile/revolver/doublebarrel/improvised/cane/examine(mob/user) // HAD TO REPEAT EXAMINE CODE BECAUSE GUN CODE DOESNT STEALTH - var/f_name = "\a [src]." - if(src.blood_DNA && !istype(src, /obj/effect/decal)) - if(gender == PLURAL) - f_name = "some " - else - f_name = "a " - f_name += "blood-stained [name]!" - - to_chat(user, "\icon[src] That's [f_name]") - - if(desc) - to_chat(user, desc) \ No newline at end of file +// DOUBLE BARRELED SHOTGUN, IMPROVISED SHOTGUN, and CANE SHOTGUN are in revolver.dm diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index ee70bb3f80b..59bd7fb649b 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -4,8 +4,8 @@ icon_state = "sniper" item_state = "sniper" recoil = 2 - heavy_weapon = 1 - mag_type = "/obj/item/ammo_box/magazine/sniper_rounds" + weapon_weight = WEAPON_MEDIUM + mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 40 origin_tech = "combat=8" can_unsuppress = 1 @@ -35,18 +35,18 @@ max_ammo = 6 caliber = ".50" -/obj/item/ammo_casing/point50 - desc = "A .50 bullet casing." - caliber = ".50" - projectile_type = /obj/item/projectile/bullet/sniper - icon_state = ".50" - /obj/item/ammo_box/magazine/sniper_rounds/update_icon() if(ammo_count()) icon_state = "[initial(icon_state)]-ammo" else icon_state = "[initial(icon_state)]" +/obj/item/ammo_casing/point50 + desc = "A .50 bullet casing." + caliber = ".50" + projectile_type = /obj/item/projectile/bullet/sniper + icon_state = ".50" + /obj/item/projectile/bullet/sniper damage = 70 stun = 5 @@ -69,8 +69,6 @@ origin_tech = "combat=6;syndicate=3" ammo_type = /obj/item/ammo_casing/soporific max_ammo = 3 - caliber = ".50" - icon_state = ".50" /obj/item/ammo_casing/soporific desc = "A .50 bullet casing, specialised in sending the target to sleep, instead of hell." @@ -79,10 +77,10 @@ icon_state = ".50" /obj/item/projectile/bullet/sniper/soporific + armour_penetration = 0 nodamage = 1 stun = 0 weaken = 0 - armour_penetration = 0 breakthings = FALSE /obj/item/projectile/bullet/sniper/soporific/on_hit(atom/target, blocked = 0, hit_zone) @@ -102,8 +100,6 @@ origin_tech = "combat=7;syndicate=5" ammo_type = /obj/item/ammo_casing/haemorrhage max_ammo = 5 - caliber = ".50" - icon_state = ".50" /obj/item/ammo_casing/haemorrhage desc = "A .50 bullet casing, specialised in causing massive bloodloss" @@ -112,11 +108,11 @@ icon_state = ".50" /obj/item/projectile/bullet/sniper/haemorrhage + armour_penetration = 15 damage = 15 stun = 0 weaken = 0 breakthings = FALSE - armour_penetration = 15 /obj/item/projectile/bullet/sniper/haemorrhage/on_hit(atom/target, blocked = 0, hit_zone) if((blocked != 100) && istype(target, /mob/living/carbon/human)) @@ -145,4 +141,4 @@ forcedodge = 1 stun = 0 weaken = 0 - breakthings = FALSE \ No newline at end of file + breakthings = FALSE diff --git a/code/modules/projectiles/guns/projectile/toy.dm b/code/modules/projectiles/guns/projectile/toy.dm index 7bb290f4f46..c0465a83beb 100644 --- a/code/modules/projectiles/guns/projectile/toy.dm +++ b/code/modules/projectiles/guns/projectile/toy.dm @@ -1,10 +1,11 @@ /obj/item/weapon/gun/projectile/automatic/toy name = "foam force SMG" desc = "A prototype three-round burst toy submachine gun. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' + icon = 'icons/obj/guns/toy.dmi' icon_state = "saber" item_state = "gun" - mag_type = "/obj/item/ammo_box/magazine/toy/smg" + mag_type = /obj/item/ammo_box/magazine/toy/smg + fire_sound = 'sound/weapons/Gunshot_smg.ogg' force = 0 throwforce = 0 burst_size = 3 @@ -12,15 +13,15 @@ clumsy_check = 0 needs_permit = 0 -/obj/item/weapon/gun/projectile/automatic/toy/process_chambered() - return ..(0, 1) +/obj/item/weapon/gun/projectile/automatic/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() /obj/item/weapon/gun/projectile/automatic/toy/pistol name = "foam force pistol" desc = "A small, easily concealable toy handgun. Ages 8 and up." icon_state = "pistol" w_class = 2 - mag_type = "/obj/item/ammo_box/magazine/toy/pistol" + mag_type = /obj/item/ammo_box/magazine/toy/pistol fire_sound = 'sound/weapons/Gunshot.ogg' can_suppress = 0 burst_size = 1 @@ -34,67 +35,65 @@ /obj/item/weapon/gun/projectile/automatic/toy/pistol/riot name = "foam force riot pistol" desc = "RIOT! Ages 8 and up." + mag_type = /obj/item/ammo_box/magazine/toy/pistol/riot /obj/item/weapon/gun/projectile/automatic/toy/pistol/riot/New() magazine = new /obj/item/ammo_box/magazine/toy/pistol/riot(src) ..() -/obj/item/weapon/gun/projectile/automatic/c20r/toy - name = "donksoft SMG" - desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' - can_suppress = 0 - needs_permit = 0 - mag_type = "/obj/item/ammo_box/magazine/toy/smgm45" - -/obj/item/weapon/gun/projectile/automatic/c20r/toy/process_chambered() - return ..(0, 1) - -/obj/item/weapon/gun/projectile/automatic/l6_saw/toy - name = "donksoft LMG" - desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' - can_suppress = 0 - needs_permit = 0 - mag_type = "/obj/item/ammo_box/magazine/toy/m762" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/toy/process_chambered() - return ..(0, 1) - - - /obj/item/weapon/gun/projectile/shotgun/toy name = "foam force shotgun" desc = "A toy shotgun with wood furniture and a four-shell capacity underneath. Ages 8 and up." - icon = 'icons/obj/toyguns.dmi' + icon = 'icons/obj/guns/toy.dmi' force = 0 throwforce = 0 origin_tech = null - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy clumsy_check = 0 needs_permit = 0 -/obj/item/weapon/gun/projectile/shotgun/toy/pump_unload() - if(chambered)//We have a shell in the chamber - chambered = null - if(in_chamber) - in_chamber = null +/obj/item/weapon/gun/projectile/shotgun/toy/process_chamber() + ..() + if(chambered && !chambered.BB) + qdel(chambered) /obj/item/weapon/gun/projectile/shotgun/toy/crossbow name = "foam force crossbow" desc = "A weapon favored by many overactive children. Ages 8 and up." icon_state = "crossbow" item_state = "crossbow" - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy/crossbow" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/crossbow fire_sound = 'sound/items/syringeproj.ogg' slot_flags = SLOT_BELT w_class = 2 +/obj/item/weapon/gun/projectile/automatic/c20r/toy + name = "donksoft SMG" + desc = "A bullpup two-round burst toy SMG, designated 'C-20r'. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/smgm45 + +/obj/item/weapon/gun/projectile/automatic/c20r/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy + name = "donksoft LMG" + desc = "A heavily modified toy light machine gun, designated 'L6 SAW'. Ages 8 and up." + icon = 'icons/obj/guns/toy.dmi' + can_suppress = 0 + needs_permit = 0 + mag_type = /obj/item/ammo_box/magazine/toy/m762 + +/obj/item/weapon/gun/projectile/automatic/l6_saw/toy/process_chamber(eject_casing = 0, empty_chamber = 1) + ..() + /obj/item/weapon/gun/projectile/shotgun/toy/tommygun name = "tommy gun" desc = "Looks almost like the real thing! Great for practicing Drive-bys. Ages 8 and up." - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/projectile.dmi' icon_state = "tommy" item_state = "shotgun" - mag_type = "/obj/item/ammo_box/magazine/internal/shot/toy/tommygun" + mag_type = /obj/item/ammo_box/magazine/internal/shot/toy/tommygun w_class = 2 diff --git a/code/modules/projectiles/guns/rocket.dm b/code/modules/projectiles/guns/rocket.dm new file mode 100644 index 00000000000..72ab89bf40e --- /dev/null +++ b/code/modules/projectiles/guns/rocket.dm @@ -0,0 +1,58 @@ +/obj/item/weapon/gun/rocketlauncher + var/projectile + name = "rocket launcher" + desc = "Say hello to my little friend" + icon_state = "rocket" + item_state = "rocket" + w_class = 4.0 + throw_speed = 2 + throw_range = 10 + force = 5.0 + flags = CONDUCT + origin_tech = "combat=8;materials=5" + var/missile_speed = 2 + var/missile_range = 30 + var/max_rockets = 1 + var/list/rockets = new/list() + +/obj/item/weapon/gun/rocketlauncher/examine(mob/user) + ..() + to_chat(user, "[rockets.len] / [max_rockets] rockets.") + +/obj/item/weapon/gun/rocketlauncher/Destroy() + for(var/datum/D in rockets) + qdel(D) + rockets = null + + return ..() + +/obj/item/weapon/gun/rocketlauncher/update_icon() + return + +/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/ammo_casing/rocket)) + if(rockets.len < max_rockets) + user.drop_item() + I.loc = src + rockets += I + to_chat(user, "You put the rocket in [src].") + to_chat(user, "[rockets.len] / [max_rockets] rockets.") + else + to_chat(usr, "[src] cannot hold more rockets.") + +/obj/item/weapon/gun/rocketlauncher/can_shoot() + return rockets.len + +/obj/item/weapon/gun/rocketlauncher/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override = "") + if(rockets.len) + var/obj/item/ammo_casing/rocket/I = rockets[1] + var/obj/item/missile/M = new /obj/item/missile(user.loc) + playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) + M.primed = 1 + M.throw_at(target, missile_range, missile_speed, user, 1) + message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([name]).") + log_game("[key_name_admin(user)] used a rocket launcher ([name]).") + rockets -= I + qdel(I) + else + to_chat(usr, "[src] is empty.") diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 0e43d550c85..332d279376b 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -13,25 +13,41 @@ var/list/syringes = list() var/max_syringes = 1 -/obj/item/weapon/gun/syringe/process_chambered() - if(!syringes.len) return 0 +/obj/item/weapon/gun/syringe/New() + ..() + chambered = new /obj/item/ammo_casing/syringegun(src) + +/obj/item/weapon/gun/syringe/newshot() + if(!syringes.len) + return var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - if(!S) return 0 + if(!S) + return - in_chamber = new /obj/item/projectile/bullet/dart/syringe(src) - S.reagents.trans_to(in_chamber, S.reagents.total_volume) - in_chamber.name = S.name + chambered.BB = new S.projectile_type (src) + + S.reagents.trans_to(chambered.BB, S.reagents.total_volume) + chambered.BB.name = S.name syringes.Remove(S) qdel(S) - return 1 + return + +/obj/item/weapon/gun/syringe/process_chamber() + return + +/obj/item/weapon/gun/syringe/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, params) + if(target == loc) + return + newshot() + ..() /obj/item/weapon/gun/syringe/examine(mob/user) - ..(user) + ..() to_chat(user, "Can hold [max_syringes] syringe\s. Has [syringes.len] syringe\s remaining.") - + /obj/item/weapon/gun/syringe/attack_self(mob/living/user as mob) if(!syringes.len) to_chat(user, "[src] is empty.") @@ -39,24 +55,26 @@ var/obj/item/weapon/reagent_containers/syringe/S = syringes[syringes.len] - if(!S) return 0 - S.forceMove(user.loc) + if(!S) + return 0 + S.loc = user.loc syringes.Remove(S) to_chat(user, "You unload [S] from \the [src]!") return 1 -/obj/item/weapon/gun/syringe/attackby(var/obj/item/A as obj, mob/user as mob, var/show_msg = 1, params) +/obj/item/weapon/gun/syringe/attackby(obj/item/A, mob/user, params, show_msg = 1) if(istype(A, /obj/item/weapon/reagent_containers/syringe)) if(syringes.len < max_syringes) - user.drop_item() + if(!user.unEquip(A)) + return to_chat(user, "You load [A] into \the [src]!") syringes.Add(A) - A.forceMove(src) + A.loc = src return 1 else - to_chat(usr, "[src] cannot hold more syringes.") + to_chat(user, "[src] cannot hold more syringes.") return 0 /obj/item/weapon/gun/syringe/rapidsyringe @@ -64,7 +82,7 @@ desc = "A modification of the syringe gun design, using a rotating cylinder to store up to six syringes." icon_state = "rapidsyringegun" max_syringes = 6 - + /obj/item/weapon/gun/syringe/syndicate name = "dart pistol" desc = "A small spring-loaded sidearm that functions identically to a syringe gun." @@ -73,5 +91,5 @@ w_class = 2 origin_tech = "combat=2;syndicate=2" force = 2 //Also very weak because it's smaller - silenced = 1 //Softer fire sound + suppressed = 1 //Softer fire sound can_unsuppress = 0 //Permanently silenced diff --git a/code/modules/projectiles/guns/throw.dm b/code/modules/projectiles/guns/throw.dm new file mode 100644 index 00000000000..d1bcda59067 --- /dev/null +++ b/code/modules/projectiles/guns/throw.dm @@ -0,0 +1,93 @@ +/obj/item/weapon/gun/throw + name = "abstract item thrower" + desc = "This shouldn't be here, yell at a coder." + fire_sound = 'sound/weapons/punchmiss.ogg' + fire_sound_text = "thwock" + + var/obj/item/to_launch + var/list/valid_projectile_type + var/max_capacity = 1 + var/list/loaded_projectiles = list() + + var/projectile_speed = 1 + var/projectile_range = 1 + +/obj/item/weapon/gun/throw/proc/notify_ammo_count(mob/user) + return + +/obj/item/weapon/gun/throw/proc/get_throwrange() + return projectile_speed + +/obj/item/weapon/gun/throw/proc/get_throwspeed() + return projectile_range + +/obj/item/weapon/gun/throw/proc/modify_projectile(obj/item/I, on_chamber = 0) + return + +/obj/item/weapon/gun/throw/proc/get_ammocount(include_loaded = 1) + var/count = loaded_projectiles.len + if(include_loaded && to_launch) + count++ + return count + +/obj/item/weapon/gun/throw/examine(mob/user) + ..() + to_chat(user, "It is [to_launch ? "loaded with \a [to_launch]" : "not loaded"].") + notify_ammo_count(user) + +/obj/item/weapon/gun/throw/Destroy() + qdel(to_launch) + to_launch = null + for(var/atom/A in loaded_projectiles) + qdel(A) + loaded_projectiles = null + + return ..() + +/obj/item/weapon/gun/throw/update_icon() + return + +/obj/item/weapon/gun/throw/attackby(obj/item/I, mob/user, params) + if(istype(I, valid_projectile_type) && !(I.flags & NODROP)) + if(get_ammocount() < max_capacity) + user.drop_item() + I.forceMove(src) + loaded_projectiles += I + to_chat(user, "You load [I] into [src].") + if(!to_launch) + process_chamber() + notify_ammo_count(user) + else + to_chat(user, "[src] cannot hold any more projectiles.") + else + to_chat(user, "You cannot load [I] into [src]!") + +/obj/item/weapon/gun/throw/process_chamber() + if(!to_launch && loaded_projectiles.len) + to_launch = loaded_projectiles[1] + loaded_projectiles -= to_launch + return + +/obj/item/weapon/gun/throw/can_shoot() + if(to_launch) + return 1 + return 0 + +/obj/item/weapon/gun/throw/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) + add_fingerprint(user) + if(semicd) + return + + var/obj/item/I = to_launch + I.forceMove(get_turf(src)) + to_launch = null + modify_projectile(I) + playsound(user, fire_sound, 50, 1) + I.throw_at(target, get_throwrange(), get_throwspeed(), user, 1) + message_admins("[key_name_admin(user)] fired \a [I] from a [src].") + log_game("[key_name_admin(user)] used \a [src].") + process_chamber() + + semicd = 1 + spawn(fire_delay) + semicd = 0 diff --git a/code/modules/projectiles/guns/throw/crossbow.dm b/code/modules/projectiles/guns/throw/crossbow.dm new file mode 100644 index 00000000000..55e76bec6b7 --- /dev/null +++ b/code/modules/projectiles/guns/throw/crossbow.dm @@ -0,0 +1,181 @@ +#define XBOW_TENSION_20 "20%" +#define XBOW_TENSION_40 "40%" +#define XBOW_TENSION_60 "60%" +#define XBOW_TENSION_80 "80%" +#define XBOW_TENSION_FULL "100%" + +/obj/item/weapon/gun/throw/crossbow + name = "powered crossbow" + desc = "A modern twist on an old classic. Pick up that can." + icon_state = "crossbow" + item_state = "crossbow-solid" + fire_sound_text = "a solid thunk" + fire_delay = 25 + + valid_projectile_type = /obj/item/weapon/arrow + + var/tension = 0 + var/drawtension = 5 + var/maxtension = 5 + var/speed_multiplier = 5 + var/range_multiplier = 3 + var/obj/item/weapon/stock_parts/cell/cell = null // Used for firing superheated rods. + var/list/possible_tensions = list(XBOW_TENSION_20, XBOW_TENSION_40, XBOW_TENSION_60, XBOW_TENSION_80, XBOW_TENSION_FULL) + +/obj/item/weapon/gun/throw/crossbow/emp_act(severity) + if(cell && severity) + emp_act(severity) + +/obj/item/weapon/gun/throw/crossbow/update_icon() + if(!tension) + if(!to_launch) + icon_state = "[initial(icon_state)]" + else + icon_state = "[initial(icon_state)]-nocked" + else + icon_state = "[initial(icon_state)]-drawn" + +/obj/item/weapon/gun/throw/crossbow/examine(mob/user) + ..() + if(cell) + to_chat(user, "\A [cell] is mounted onto [src]. Battery cell charge: [cell.charge]/[cell.maxcharge]") + else + to_chat(user, "It has an empty mount for a battery cell.") + +/obj/item/weapon/gun/throw/crossbow/modify_projectile(obj/item/I, on_chamber = 0) + if(cell && on_chamber && istype(I, /obj/item/weapon/arrow/rod)) + var/obj/item/weapon/arrow/rod/R = I + visible_message("[R] plinks and crackles as it begins to glow red-hot.") + R.throwforce = 15 + R.superheated = 1 + cell.use(500) + +/obj/item/weapon/gun/throw/crossbow/get_throwspeed() + return tension * speed_multiplier + +/obj/item/weapon/gun/throw/crossbow/get_throwrange() + return tension * range_multiplier + +/obj/item/weapon/gun/throw/crossbow/process_chamber() + ..() + if(to_launch) + modify_projectile(to_launch, 1) + update_icon() + +/obj/item/weapon/gun/throw/crossbow/attack_self(mob/living/user) + if(tension) + if(to_launch) + user.visible_message("[user] relaxes the tension on [src]'s string and removes [to_launch].","You relax the tension on [src]'s string and remove [to_launch].") + to_launch.forceMove(get_turf(src)) + var/obj/item/weapon/arrow/A = to_launch + to_launch = null + A.removed() + process_chamber() + else + user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.") + tension = 0 + update_icon() + else + draw(user) + +/obj/item/weapon/gun/throw/crossbow/proc/draw(mob/living/user) + if(user.incapacitated()) + return + if(!to_launch) + to_chat(user, "You can't draw [src] without a bolt nocked.") + return + + user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") + if(do_after(user, 25 * drawtension, target = user)) + tension = drawtension + user.visible_message("[usr] draws back the string of [src]!","[src] clunks as you draw the string to its maximum tension!!") + update_icon() + +/obj/item/weapon/gun/throw/crossbow/attackby(obj/item/W as obj, mob/user as mob, params) + if(istype(W, /obj/item/weapon/stock_parts/cell)) + if(!cell) + user.drop_item() + W.loc = src + cell = W + to_chat(user, "You jam [cell] into [src] and wire it to the firing coil.") + process_chamber() + else + to_chat(user, "[src] already has a cell installed.") + else if(istype(W, /obj/item/weapon/screwdriver)) + if(cell) + cell.loc = get_turf(src) + to_chat(user, "You jimmy [cell] out of [src] with [W].") + cell = null + else + to_chat(user, "[src] doesn't have a cell installed.") + else + ..() + +/obj/item/weapon/gun/throw/crossbow/verb/set_tension() + set name = "Adjust Tension" + set category = "Object" + set src in range(0) + + var/mob/user = usr + if(user.incapacitated()) + return + var/choice = input("Select tension to draw to:", "[src]", XBOW_TENSION_FULL) as null|anything in possible_tensions + if(!choice) + return + + switch(choice) + if(XBOW_TENSION_20) + drawtension = Ceiling(0.2 * maxtension) + if(XBOW_TENSION_40) + drawtension = Ceiling(0.4 * maxtension) + if(XBOW_TENSION_60) + drawtension = Ceiling(0.6 * maxtension) + if(XBOW_TENSION_80) + drawtension = Ceiling(0.8 * maxtension) + if(XBOW_TENSION_FULL) + drawtension = maxtension + +/obj/item/weapon/gun/throw/crossbow/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override) + ..() + tension = 0 + update_icon() +/obj/item/weapon/gun/throw/crossbow/french + name = "french powered crossbow" + icon_state = "fcrossbow" + valid_projectile_type = /obj/item/weapon/reagent_containers/food/snacks/baguette + +/obj/item/weapon/gun/throw/crossbow/french/modify_projectile(obj/item/I, on_chamber = 0) + return + +/obj/item/weapon/arrow + name = "bolt" + desc = "It's got a tip for you - get the point?" + icon_state = "bolt" + item_state = "bolt" + throwforce = 20 + w_class = 3.0 + sharp = 1 + edge = 0 + +/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart. + return + +/obj/item/weapon/arrow/rod + name = "makeshift bolt" + desc = "A sharpened metal rod that can be fired out of a crossbow." + icon_state = "metal-rod" + throwforce = 8 + var/superheated = 0 + +/obj/item/weapon/arrow/rod/removed() + if(superheated) // The rod has been superheated - we don't want it to be useable when removed from the bow. + visible_message("[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow.") + var/obj/item/weapon/shard/shrapnel/S = new /obj/item/weapon/shard/shrapnel + S.loc = get_turf(src) + qdel(src) + +#undef XBOW_TENSION_20 +#undef XBOW_TENSION_40 +#undef XBOW_TENSION_60 +#undef XBOW_TENSION_80 +#undef XBOW_TENSION_FULL diff --git a/code/modules/projectiles/guns/throw/pielauncher.dm b/code/modules/projectiles/guns/throw/pielauncher.dm new file mode 100644 index 00000000000..f6405f47194 --- /dev/null +++ b/code/modules/projectiles/guns/throw/pielauncher.dm @@ -0,0 +1,36 @@ +/obj/item/weapon/gun/throw/piecannon + name = "pie cannon" + desc = "A projectile weapon that fires pies." + icon_state = "piecannon" + w_class = 5 + throw_speed = 2 + throw_range = 3 + force = 5 + + clumsy_check = 0 + valid_projectile_type = /obj/item/weapon/reagent_containers/food/snacks/pie + max_capacity = 5 + projectile_speed = 2 + projectile_range = 30 + + +/obj/item/weapon/gun/throw/piecannon/New() + ..() + for(var/i in 1 to max_capacity) + var/obj/item/weapon/reagent_containers/food/snacks/pie/P = new /obj/item/weapon/reagent_containers/food/snacks/pie(src) + loaded_projectiles += P + process_chamber() + +/obj/item/weapon/gun/throw/piecannon/notify_ammo_count(mob/user) + to_chat(user, "[src] has [get_ammocount()] of [max_capacity] pies left.") + +/obj/item/weapon/gun/throw/piecannon/update_icon() + if(to_launch) + icon_state = "piecannon1" + else + icon_state = "piecannon0" + item_state = icon_state + +/obj/item/weapon/gun/throw/piecannon/process_chamber() + ..() + update_icon() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 5a028a1084a..5a8fa77e268 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1,353 +1,223 @@ -/* -#define BRUTE "brute" -#define BURN "burn" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" - -#define ADD "add" -#define SET "set" -*/ - /obj/item/projectile name = "projectile" icon = 'icons/obj/projectiles.dmi' icon_state = "bullet" - density = 1 + density = 0 unacidable = 1 anchored = 1 //There's a reason this is here, Mport. God fucking damn it -Agouri. Find&Fix by Pete. The reason this is here is to stop the curving of emitter shots. + flags = ABSTRACT pass_flags = PASSTABLE mouse_opacity = 0 hitsound = 'sound/weapons/pierce.ogg' - animate_movement = 0 - var/bumped = 0 //Prevents it from hitting more than one guy at once + var/hitsound_wall = "" + pressure_resistance = INFINITY var/def_zone = "" //Aiming at var/mob/firer = null//Who shot it - var/silenced = 0 //Attack message + var/obj/item/ammo_casing/ammo_casing = null + var/suppressed = 0 //Attack message var/yo = null var/xo = null var/current = null - var/obj/shot_from = null // the object which shot us var/atom/original = null // the original target clicked var/turf/starting = null // the projectile's starting turf var/list/permutated = list() // we've passed through these atoms, don't try to hit them again var/paused = FALSE //for suspending the projectile midair - var/p_x = 16 var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center + var/speed = 1 //Amount of deciseconds it takes for projectile to travel + var/Angle = 0 + var/spread = 0 //amount (in degrees) of projectile spread + var/legacy = 0 //legacy projectile system + animate_movement = 0 var/damage = 10 var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid var/projectile_type = "/obj/item/projectile" - var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile. - //Effects + var/range = 50 //This will de-increment every step. When 0, it will delete the projectile. + //Effects var/stun = 0 var/weaken = 0 var/paralyze = 0 var/irradiate = 0 - var/slur = 0 var/stutter = 0 + var/slur = 0 var/eyeblur = 0 var/drowsy = 0 var/stamina = 0 var/jitter = 0 var/embed = 0 // whether or not the projectile can embed itself in the mob - var/forcedodge = 0 + var/forcedodge = 0 //to pass through everything - var/range = 0 - var/proj_hit = 0 +/obj/item/projectile/New() + permutated = list() + return ..() - var/chatlog_attacks = 1 +/obj/item/projectile/proc/Range() + range-- + if(range <= 0 && loc) + on_range() - var/speed = 1 //Amount of deciseconds it takes for projectile to travel. Animation is adjusted accordingly. - var/Angle = 0 //For new projectiles - var/spread = 0 //Amount of degrees by which the projectiles will be spread DURING MOVEMENT. It exists for chaotic types of projectiles, like bees or something. - var/legacy = 0 //Use the legacy projectile system or new pixel movement? +/obj/item/projectile/proc/on_range() //if we want there to be effects when they reach the end of their range + qdel(src) - proc/delete() - // Garbage collect the projectiles - loc = null - - proc/Range() - if(range) - range-- - if(range <= 0) - on_range() - else - return - - proc/on_range() //if we want there to be effects when they reach the end of their range - proj_hit = 1 - del(src) - - proc/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) - if(!isliving(target)) return 0 - if(isanimal(target)) return 0 - var/mob/living/L = target - return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) - - proc/OnFired() //if assigned, allows for code when the projectile gets fired - return 1 - - proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - if(!istype(target) || !istype(user)) - return 0 - var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... - in_chamber.target = target - in_chamber.flags = flags //Set the flags... - in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile... - in_chamber.firer = user - var/output = in_chamber.process() //Test it! - del(in_chamber) //No need for it anymore - return output //Send it back to the gun! - - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return 0 //cannot shoot yourself - - if(bumped) - return 1 - bumped = 1 - if(firer && istype(A, /mob)) - var/mob/M = A - if(!istype(A, /mob/living)) - loc = A.loc - return 0// nope.avi - - var/reagent_note - if(reagents && reagents.reagent_list) - reagent_note = " REAGENTS:" - for(var/datum/reagent/R in reagents.reagent_list) - reagent_note += R.id + " (" - reagent_note += num2text(R.volume) + ") " - //Lower accurancy/longer range tradeoff. Distance matters a lot here, so at - // close distance, actually RAISE the chance to hit. - var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. - def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. - /* - if(!def_zone) - visible_message("\blue \The [src] misses [M] narrowly!") - forcedodge = -1 - else - */ - if(ishuman(A)) - var/mob/living/carbon/human/H = A - var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone)) - if(isnull(organ)) - return - if(silenced) - playsound(loc, hitsound, 5, 1, -1) - to_chat(M, "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!") - else - playsound(loc, hitsound, 20, 1, -1) - visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter - if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [key_name(firer)] shot [M]/[M.ckey] with a [src.type][reagent_note]" - firer.attack_log += "\[[time_stamp()]\] [key_name(firer)] shot [M]/[M.ckey] with a [src.type][reagent_note]" - if(M.ckey && chatlog_attacks) - msg_admin_attack("[key_name_admin(firer)] shot [key_name_admin(M)] with a [src][reagent_note]") //BS12 EDIT ALG - if(!iscarbon(firer)) - M.LAssailant = null - else - M.LAssailant = firer - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [key_name(M)] with a [src][reagent_note]" - if(M.ckey && chatlog_attacks) - msg_admin_attack("UNKNOWN shot [key_name_admin(M)] with a [src][reagent_note] (JMP)") //BS12 EDIT ALG - - spawn(0) - if(A) - var/turf/new_loc = get_turf(A) - var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null - if(permutation == -1 || forcedodge)// the bullet passes through a dense object! - spawn(1) - bumped = 0 // reset bumped variable... after a delay. We don't want the projectile to hit AGAIN. Fixes deflecting projectiles. - loc = new_loc - permutated.Add(A) - return 0 - if(istype(A,/turf)) - for(var/obj/O in A) - O.bullet_act(src) - for(var/mob/M in A) - M.bullet_act(src, def_zone) - if(!istype(src, /obj/item/projectile/beam/lightning)) - density = 0 - invisibility = 101 - del(src) - return 1 - - - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - - if(istype(mover, /obj/item/projectile)) - return prob(95) - else - return 1 - - - Process_Spacemove(var/movement_dir = 0) - return 1 //Bullets don't drift in space - - - - process(var/setAngle) - if(setAngle) Angle = setAngle - if(!legacy) - spawn() //New projectile system - while(loc) - if(kill_count < 1) - del(src) - return - if(!paused) - kill_count-- - if((!( current ) || loc == current)) - current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - - if(!Angle) - Angle=round(Get_Angle(src,current)) -// to_chat(world, "[Angle] angle") - //overlays.Cut() - //var/icon/I=new(initial(icon),icon_state) //using initial(icon) makes sure that the angle for that is reset as well - //I.Turn(Angle) - //I.DrawBox(rgb(255,0,0,50),1,1,32,32) - //icon = I - if(spread) //Chaotic spread - Angle += (rand() - 0.5) * spread - var/matrix/M = new//matrix(transform) - M.Turn(Angle) - transform = M - - var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2) - var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2) - var/pixel_x_offset = pixel_x + Pixel_x - var/pixel_y_offset = pixel_y + Pixel_y - var/new_x = x - var/new_y = y - //Not sure if using whiles for this is good - while(pixel_x_offset > 16) -// to_chat(world, "Pre-adjust coords (x++): xy [pixel_x] xy offset [pixel_x_offset]") - pixel_x_offset -= 32 - pixel_x -= 32 - new_x++// x++ - while(pixel_x_offset < -16) -// to_chat(world, "Pre-adjust coords (x--): xy [pixel_x] xy offset [pixel_x_offset]") - pixel_x_offset += 32 - pixel_x += 32 - new_x-- - - while(pixel_y_offset > 16) -// to_chat(world, "Pre-adjust coords (y++): py [pixel_y] py offset [pixel_y_offset]") - pixel_y_offset -= 32 - pixel_y -= 32 - new_y++ - while(pixel_y_offset < -16) -// to_chat(world, "Pre-adjust coords (y--): py [pixel_y] py offset [pixel_y_offset]") - pixel_y_offset += 32 - pixel_y += 32 - new_y-- - - speed = round(speed) //Just in case. - step_towards(src, locate(new_x, new_y, z)) //Original projectiles stepped towards 'current' - if(speed <= 1) //We should really only animate at speed 2 - pixel_x = pixel_x_offset - pixel_y = pixel_y_offset - else - animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed))) - - /* - var/turf/T = get_turf(src) - if(T) - T.color = "#6666FF" - spawn(10) - T.color = initial(T.color) - */ - - if(!bumped && ((original && original.layer>=2.75) || ismob(original))) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - Range() - sleep(max(1, speed)) - else - spawn() //Old projectile system - while(loc) - if(kill_count < 1) - del(src) - return - if(!paused) - kill_count-- - if((!( current ) || loc == current)) - current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - if(!Angle) - Angle=round(Get_Angle(src,current)) - var/matrix/M = new//matrix(transform) - M.Turn(Angle) - transform = M //So there's no need to give icons directions again - step_towards(src, current) - if(!bumped && ((original && original.layer>=2.75) || ismob(original))) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - Range() - sleep(1) - - proc/dumbfire(var/dir) - current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. - process() - -/obj/item/projectile/test //Used to see if you can hit them. - invisibility = 101 //Nope! Can't see me! - yo = null - xo = null - var/target = null - var/result = 0 //To pass the message back to the gun. - - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return //cannot shoot yourself - if(istype(A, /obj/item/projectile)) - return - if(istype(A, /mob/living) || istype(A, /obj/mecha) || istype(A, /obj/spacepod) || istype(A, /obj/vehicle)) - result = 2 //We hit someone, return 1! - return - result = 1 - return - - process() - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) - return 0 - yo = targloc.y - curloc.y - xo = targloc.x - curloc.x - target = targloc - while(src) //Loop on through! - if(result) - return (result - 1) - if((!( target ) || loc == target)) - target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge - step_towards(src, target) - var/mob/living/M = locate() in get_turf(src) - if(istype(M)) //If there is someting living... - return 1 //Return 1 - else - M = locate() in get_step(src,target) - if(istype(M)) - return 1 - -/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) //Checks if you can hit them or not. - if(!istype(target) || !istype(firer)) +/obj/item/projectile/proc/on_hit(atom/target, blocked = 0, hit_zone) + if(!isliving(target)) return 0 - var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_turf(firer)) //Making the test.... - trace.target = target - if(!isnull(flags)) - trace.flags = flags //Set the flags... - trace.pass_flags = pass_flags //And the pass flags to that of the real projectile... - var/output = trace.process() //Test it! - qdel(trace) //No need for it anymore - return output //Send it back to the gun! + var/mob/living/L = target + if(blocked < 100) // not completely blocked + var/organ_hit_text = "" + if(L.has_limbs) + organ_hit_text = " in \the [parse_zone(def_zone)]" + if(suppressed) + playsound(loc, hitsound, 5, 1, -1) + to_chat(L, "You're shot by \a [src][organ_hit_text]!") + else + if(hitsound) + var/volume = vol_by_damage() + playsound(loc, hitsound, volume, 1, -1) + L.visible_message("[L] is hit by \a [src][organ_hit_text]!", \ + "[L] is hit by \a [src][organ_hit_text]!") //X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter + + var/reagent_note + if(reagents && reagents.reagent_list) + reagent_note = " REAGENTS:" + for(var/datum/reagent/R in reagents.reagent_list) + reagent_note += R.id + " (" + reagent_note += num2text(R.volume) + ") " + add_logs(L, firer, "shot", src, reagent_note) + return L.apply_effects(stun, weaken, paralyze, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter) + +/obj/item/projectile/proc/vol_by_damage() + if(damage) + return Clamp((damage) * 0.67, 30, 100)// Multiply projectile damage by 0.67, then clamp the value between 30 and 100 + else + return 50 //if the projectile doesn't do damage, play its hitsound at 50% volume + +/obj/item/projectile/Bump(atom/A, yes) + if(!yes) //prevents double bumps. + return + if(firer) + if(A == firer || (A == firer.loc && istype(A, /obj/mecha))) //cannot shoot yourself or your mech + loc = A.loc + return 0 + + var/distance = get_dist(get_turf(A), starting) // Get the distance between the turf shot from and the mob we hit and use that for the calculations. + def_zone = ran_zone(def_zone, max(100-(7*distance), 5)) //Lower accurancy/longer range tradeoff. 7 is a balanced number to use. + + if(isturf(A) && hitsound_wall) + var/volume = Clamp(vol_by_damage() + 20, 0, 100) + if(suppressed) + volume = 5 + playsound(loc, hitsound_wall, volume, 1, -1) + else if(ishuman(A)) + var/mob/living/carbon/human/H = A + var/obj/item/organ/external/organ = H.get_organ(check_zone(def_zone)) + if(isnull(organ)) + return + + var/turf/target_turf = get_turf(A) + + var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null + if(permutation == -1 || forcedodge)// the bullet passes through a dense object! + loc = target_turf + if(A) + permutated.Add(A) + return 0 + else + if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile. + var/list/mobs_list = list() + for(var/mob/living/L in target_turf) + mobs_list += L + if(mobs_list.len) + var/mob/living/picked_mob = pick(mobs_list) + picked_mob.bullet_act(src, def_zone) + qdel(src) + +/obj/item/projectile/Process_Spacemove(var/movement_dir = 0) + return 1 //Bullets don't drift in space + +/obj/item/projectile/proc/fire(var/setAngle) + if(setAngle) + Angle = setAngle + if(!legacy) //new projectiles + set waitfor = 0 + while(loc) + if(!paused) + if((!( current ) || loc == current)) + current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) + + if(!Angle) + Angle=round(Get_Angle(src,current)) + if(spread) + Angle += (rand() - 0.5) * spread + var/matrix/M = new + M.Turn(Angle) + transform = M + + var/Pixel_x=round(sin(Angle)+16*sin(Angle)*2) + var/Pixel_y=round(cos(Angle)+16*cos(Angle)*2) + var/pixel_x_offset = pixel_x + Pixel_x + var/pixel_y_offset = pixel_y + Pixel_y + var/new_x = x + var/new_y = y + + while(pixel_x_offset > 16) + pixel_x_offset -= 32 + pixel_x -= 32 + new_x++// x++ + while(pixel_x_offset < -16) + pixel_x_offset += 32 + pixel_x += 32 + new_x-- + + while(pixel_y_offset > 16) + pixel_y_offset -= 32 + pixel_y -= 32 + new_y++ + while(pixel_y_offset < -16) + pixel_y_offset += 32 + pixel_y += 32 + new_y-- + + speed = round(speed) + step_towards(src, locate(new_x, new_y, z)) + if(speed <= 1) + pixel_x = pixel_x_offset + pixel_y = pixel_y_offset + else + animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (speed <= 3 ? speed - 1 : speed))) + + if(original && (original.layer>=2.75) || ismob(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original, 1) + Range() + sleep(max(1, speed)) + else //old projectile system + set waitfor = 0 + while(loc) + if(!paused) + if((!( current ) || loc == current)) + current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) + step_towards(src, current) + if(original && (original.layer>=2.75) || ismob(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original, 1) + Range() + sleep(1) + +obj/item/projectile/Crossed(atom/movable/AM) //A mob moving on a tile with a projectile is hit by it. + ..() + if(isliving(AM) && AM.density && !checkpass(PASSMOB)) + Bump(AM, 1) + +/obj/item/projectile/Destroy() + ammo_casing = null + return ..() + +/obj/item/projectile/proc/dumbfire(var/dir) + current = get_ranged_target_turf(src, dir, world.maxx) //world.maxx is the range. Not sure how to handle this better. + fire() diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index e86d8e7a739..d9cf8360d2a 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -5,56 +5,34 @@ damage = 20 damage_type = BURN hitsound = 'sound/weapons/sear.ogg' + hitsound_wall = 'sound/weapons/effects/searwall.ogg' flag = "laser" eyeblur = 2 -/obj/item/projectile/practice - name = "laser" - icon_state = "laser" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE +/obj/item/projectile/beam/laser + +/obj/item/projectile/beam/laser/heavylaser + name = "heavy laser" + icon_state = "heavylaser" + damage = 40 + +/obj/item/projectile/beam/practice + name = "practice laser" damage = 0 - hitsound = null - damage_type = BURN - flag = "laser" - eyeblur = 2 - chatlog_attacks = 0 + nodamage = 1 /obj/item/projectile/beam/scatter name = "laser pellet" icon_state = "scatterlaser" damage = 5 - -/obj/item/projectile/beam/heavylaser - name = "heavy laser" - icon_state = "heavylaser" - damage = 40 - -/obj/item/projectile/beam/sniper - name = "sniper beam" - icon_state = "sniperlaser" - damage = 60 - stun = 5 - weaken = 5 - stutter = 5 - - -/obj/item/projectile/beam/immolator - name = "immolation beam" - -/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0) - . = ..() - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target - M.adjust_fire_stacks(1) - M.IgniteMob() - /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" damage = 15 irradiate = 30 forcedodge = 1 + range = 15 /obj/item/projectile/beam/disabler name = "disabler beam" @@ -82,204 +60,75 @@ name = "emitter beam" icon_state = "emitter" damage = 30 + legacy = 1 + animate_movement = SLIDE_STEPS /obj/item/projectile/beam/emitter/singularity_pull() return //don't want the emitters to miss -/obj/item/projectile/lasertag +/obj/item/projectile/beam/lasertag name = "laser tag beam" icon_state = "omnilaser" hitsound = null damage = 0 damage_type = STAMINA flag = "laser" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) - chatlog_attacks = 0 -/obj/item/projectile/lasertag/on_hit(var/atom/target, var/blocked = 0) - if(istype(target, /mob/living/carbon/human)) +/obj/item/projectile/beam/lasertag/on_hit(atom/target, blocked = 0) + . = ..() + if(ishuman(target)) var/mob/living/carbon/human/M = target if(istype(M.wear_suit)) if(M.wear_suit.type in suit_types) M.adjustStaminaLoss(34) return 1 -/obj/item/projectile/lasertag/omni +/obj/item/projectile/beam/lasertag/omni name = "laser tag beam" icon_state = "omnilaser" -/obj/item/projectile/lasertag/red +/obj/item/projectile/beam/lasertag/redtag icon_state = "laser" suit_types = list(/obj/item/clothing/suit/bluetag) -/obj/item/projectile/lasertag/blue +/obj/item/projectile/beam/lasertag/bluetag icon_state = "bluelaser" suit_types = list(/obj/item/clothing/suit/redtag) -/obj/item/projectile/beam/lightning - invisibility = 101 - name = "lightning" - damage = 0 - icon = 'icons/obj/lightning.dmi' - icon_state = "lightning" - stun = 10 - weaken = 10 - stutter = 50 - eyeblur = 50 - var/tang = 0 - layer = 3 - var/turf/last = null - kill_count = 6 - var/bullet_acted = 0 +/obj/item/projectile/beam/sniper + name = "sniper beam" + icon_state = "sniperlaser" + damage = 60 + stun = 5 + weaken = 5 + stutter = 5 - Bump(var/atom/A) - if((A != firer) && !bullet_acted) - A.bullet_act(src) - bullet_acted = 1 +/obj/item/projectile/beam/immolator + name = "immolation beam" - proc/adjustAngle(angle) - angle = round(angle) + 45 - if(angle > 180) - angle -= 180 - else - angle += 180 - if(!angle) - angle = 1 - /*if(angle < 0) - //angle = (round(abs(get_angle(A, user))) + 45) - 90 - angle = round(angle) + 45 + 180 - else - angle = round(angle) + 45*/ - return angle +/obj/item/projectile/beam/immolator/on_hit(var/atom/target, var/blocked = 0) + . = ..() + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(1) + M.IgniteMob() - process() - var/first = 1 //So we don't make the overlay in the same tile as the firer - var/broke = 0 - var/broken - var/atom/curr = current - var/Angle=round(Get_Angle(firer,curr)) - var/icon/I=new('icons/obj/zap.dmi',"lightning") - I.Turn(Angle) - var/DX=(32*curr.x+curr.pixel_x)-(32*firer.x+firer.pixel_x) - var/DY=(32*curr.y+curr.pixel_y)-(32*firer.y+firer.pixel_y) - var/N=0 - var/length=round(sqrt((DX)**2+(DY)**2)) - var/count = 0 - for(N,N= kill_count) - break - count++ - var/obj/effect/overlay/beam/X=new(loc) - X.BeamSource=src - if(N+32>length) - var/icon/II=new(icon,icon_state) - II.DrawBox(null,1,(length-N),32,32) - II.Turn(Angle) - X.icon=II - else X.icon=I - var/Pixel_x=round(sin(Angle)+32*sin(Angle)*(N+16)/32) - var/Pixel_y=round(cos(Angle)+32*cos(Angle)*(N+16)/32) - if(DX==0) Pixel_x=0 - if(DY==0) Pixel_y=0 - if(Pixel_x>32) - for(var/a=0, a<=Pixel_x,a+=32) - X.x++ - Pixel_x-=32 - if(Pixel_x<-32) - for(var/a=0, a>=Pixel_x,a-=32) - X.x-- - Pixel_x+=32 - if(Pixel_y>32) - for(var/a=0, a<=Pixel_y,a+=32) - X.y++ - Pixel_y-=32 - if(Pixel_y<-32) - for(var/a=0, a>=Pixel_y,a-=32) - X.y-- - Pixel_y+=32 - X.pixel_x=Pixel_x - X.pixel_y=Pixel_y - var/turf/TT = get_turf(X.loc) - if(TT == firer.loc) - continue - if(TT.density) - qdel(X) - break - for(var/atom/O in TT) - if(istype(O,/mob/living)) - if(O.density) - qdel(X) - broke = 1 - break - if(!O.CanPass(src)) - qdel(X) - broke = 1 - break - if(broke) - if(X) - qdel(X) - break - spawn - while(src) //Move until we hit something - if(first) - icon = midicon - if((!( current ) || loc == current)) //If we pass our target - broken = 1 - icon = endicon - tang = adjustAngle(get_angle(original,current)) - if(tang > 180) - tang -= 180 - else - tang += 180 - icon_state = "[tang]" - var/turf/simulated/floor/f = current - if(f && istype(f)) - if(!bullet_acted) - f.break_tile() - f.hotspot_expose(1000,CELL_VOLUME) - if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) -// to_chat(world, "deleting") - //qdel(src) //Delete if it passes the world edge - broken = 1 - return - if(kill_count < 1) -// to_chat(world, "deleting") - //qdel(src) - broken = 1 - kill_count-- -// to_chat(world, "[x] [y]") - if(!bumped && !isturf(original)) - if(loc == get_turf(original)) - if(!(original in permutated)) - icon = endicon - if(!broken) - tang = adjustAngle(get_angle(original,current)) - if(tang > 180) - tang -= 180 - else - tang += 180 - icon_state = "[tang]" - Bump(original) - first = 0 - if(broken) -// to_chat(world, "breaking") - break - else - last = get_turf(src.loc) - step_towards(src, current) //Move~ - if(src.loc != current) - tang = adjustAngle(get_angle(src.loc,current)) - icon_state = "[tang]" - qdel(src) - return - /*cleanup(reference) //Waits .3 seconds then removes the overlay. -// to_chat(world, "setting invisibility") - sleep(50) - src.invisibility = 101 - return*/ - on_hit(atom/target, blocked = 0) - if(istype(target, /mob/living)) - var/mob/living/M = target - M.playsound_local(src, "explosion", 50, 1) - ..() \ No newline at end of file +/obj/item/projectile/beam/instakill + name = "instagib laser" + icon_state = "purple_laser" + damage = 200 + damage_type = BURN + +/obj/item/projectile/beam/instakill/blue + icon_state = "blue_laser" + +/obj/item/projectile/beam/instakill/red + icon_state = "red_laser" + +/obj/item/projectile/beam/instakill/on_hit(atom/target) + . = ..() + if(iscarbon(target)) + var/mob/living/carbon/M = target + M.visible_message("[M] explodes into a shower of gibs!") + M.gib() diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 879bbf7fad0..8f8809c504f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -3,21 +3,10 @@ icon_state = "bullet" damage = 60 damage_type = BRUTE - nodamage = 0 flag = "bullet" embed = 1 sharp = 1 - -/obj/item/projectile/bullet/cap - name = "cap" - damage = 0 - nodamage = 1 - embed = 0 - sharp = 0 - -/obj/item/projectile/bullet/cap/process() - loc = null - del(src) + hitsound_wall = "ricochet" /obj/item/projectile/bullet/weakbullet //beanbag, heavy stamina damage damage = 5 @@ -27,6 +16,26 @@ embed = 0 sharp = 0 +/obj/item/projectile/bullet/weakbullet/booze + embed = 0 + +/obj/item/projectile/bullet/weakbullet/booze/on_hit(atom/target, blocked = 0) + if(..(target, blocked)) + var/mob/living/M = target + M.dizziness += 20 + M.slurring += 20 + M.confused += 20 + M.eye_blurry += 20 + M.drowsyness += 20 + for(var/datum/reagent/ethanol/A in M.reagents.reagent_list) + M.AdjustParalysis(2) + M.dizziness += 10 + M.slurring += 10 + M.confused += 10 + M.eye_blurry += 10 + M.drowsyness += 10 + A.volume += 5 //Because we can + /obj/item/projectile/bullet/weakbullet2 //detective revolver instastuns, but multiple shots are better for keeping punks down damage = 5 weaken = 3 @@ -44,6 +53,15 @@ damage = 15 damage_type = TOX +/obj/item/projectile/bullet/incendiary + +/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) + ..() + if(istype(target, /mob/living/carbon)) + var/mob/living/carbon/M = target + M.adjust_fire_stacks(1) + M.IgniteMob() + /obj/item/projectile/bullet/incendiary/firebullet damage = 10 @@ -55,15 +73,34 @@ name = "pellet" damage = 15 -/obj/item/projectile/bullet/blank - name = "blankshot" - nodamage = 1 - /obj/item/projectile/bullet/pellet/weak + damage = 6 + +/obj/item/projectile/bullet/pellet/weak/New() + range = rand(8) + +/obj/item/projectile/bullet/pellet/weak/on_range() + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread + sparks.set_up(1, 1, src) + sparks.start() + ..() + +/obj/item/projectile/bullet/pellet/overload damage = 3 -/obj/item/projectile/bullet/pellet/random/New() - damage = rand(10) +/obj/item/projectile/bullet/pellet/overload/New() + range = rand(10) + +/obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0) + ..() + explosion(target, 0, 0, 2) + +/obj/item/projectile/bullet/pellet/overload/on_range() + explosion(src, 0, 0, 2) + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread + sparks.set_up(3, 3, src) + sparks.start() + ..() /obj/item/projectile/bullet/midbullet damage = 20 @@ -89,39 +126,11 @@ weaken = 5 stutter = 5 jitter = 20 - icon_state = "spark" range = 7 embed = 0 sharp = 0 - - -/obj/item/projectile/bullet/weakbullet/booze - embed = 0 - on_hit(var/atom/target, var/blocked = 0) - if(..(target, blocked)) - var/mob/living/M = target - M.dizziness += 20 - M.slurring += 20 - M.confused += 20 - M.eye_blurry += 20 - M.drowsyness += 20 - for(var/datum/reagent/ethanol/A in M.reagents.reagent_list) - M.AdjustParalysis(2) - M.dizziness += 10 - M.slurring += 10 - M.confused += 10 - M.eye_blurry += 10 - M.drowsyness += 10 - A.volume += 5 //Because we can - -/obj/item/projectile/bullet/incendiary - -/obj/item/projectile/bullet/incendiary/on_hit(var/atom/target, var/blocked = 0) - ..() - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target - M.adjust_fire_stacks(1) - M.IgniteMob() + icon_state = "spark" + color = "#FFFF00" /obj/item/projectile/bullet/incendiary/shell name = "incendiary slug" @@ -130,8 +139,9 @@ /obj/item/projectile/bullet/incendiary/shell/Move() ..() var/turf/location = get_turf(src) - new /obj/effect/hotspot(location) - location.hotspot_expose(700, 50, 1) + if(location) + new /obj/effect/hotspot(location) + location.hotspot_expose(700, 50, 1) /obj/item/projectile/bullet/incendiary/shell/dragonsbreath name = "dragonsbreath round" @@ -157,7 +167,26 @@ ..() SpinAnimation() +/obj/item/projectile/bullet/meteorshot/weak + damage = 10 + weaken = 4 + stun = 4 +/obj/item/projectile/bullet/honker + damage = 0 + weaken = 5 + stun = 5 + forcedodge = 1 + nodamage = 1 + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + hitsound = 'sound/items/bikehorn.ogg' + icon = 'icons/obj/harvest.dmi' + icon_state = "banana" + range = 200 + +/obj/item/projectile/bullet/honker/New() + ..() + SpinAnimation() /obj/item/projectile/bullet/mime damage = 0 @@ -168,7 +197,7 @@ /obj/item/projectile/bullet/mime/on_hit(var/atom/target, var/blocked = 0) ..(target, blocked) - if(istype(target, /mob/living/carbon)) + if(iscarbon(target)) var/mob/living/carbon/M = target M.silent = max(M.silent, 10) else if(istype(target, /obj/mecha/combat/honker)) @@ -184,32 +213,38 @@ damage = 6 embed = 0 sharp = 0 + var/piercing = 0 - New() - ..() - flags |= NOREACT - create_reagents(50) +/obj/item/projectile/bullet/dart/New() + ..() + flags |= NOREACT + create_reagents(50) - on_hit(var/atom/target, var/blocked = 0, var/hit_zone) - if(istype(target, /mob/living/carbon)) - var/mob/living/carbon/M = target +/obj/item/projectile/bullet/dart/on_hit(var/atom/target, var/blocked = 0, var/hit_zone) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) if(M.can_inject(null,0,hit_zone)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..() reagents.reaction(M, INGEST) reagents.trans_to(M, reagents.total_volume) return 1 else + blocked = 100 target.visible_message("The [name] was deflected!", \ - "You were protected against the [name]!") - flags &= ~NOREACT - reagents.handle_reactions() - return 1 + "You were protected against the [name]!") + ..(target, blocked, hit_zone) + flags &= ~NOREACT + reagents.handle_reactions() + return 1 /obj/item/projectile/bullet/dart/metalfoam - New() - ..() - reagents.add_reagent("aluminum", 15) - reagents.add_reagent("fluorosurfactant", 5) - reagents.add_reagent("sacid", 5) + +/obj/item/projectile/bullet/dart/metalfoam/New() + ..() + reagents.add_reagent("aluminum", 15) + reagents.add_reagent("fluorosurfactant", 5) + reagents.add_reagent("sacid", 5) //This one is for future syringe guns update /obj/item/projectile/bullet/dart/syringe @@ -218,9 +253,9 @@ icon_state = "syringeproj" /obj/item/projectile/bullet/dart/syringe/tranquilizer - New() - ..() - reagents.add_reagent("haloperidol", 15) +/obj/item/projectile/bullet/dart/syringe/tranquilizer/New() + ..() + reagents.add_reagent("haloperidol", 15) /obj/item/projectile/bullet/neurotoxin name = "neurotoxin spit" @@ -231,5 +266,17 @@ /obj/item/projectile/bullet/neurotoxin/on_hit(var/atom/target, var/blocked = 0) if(isalien(target)) - return 0 - ..() // Execute the rest of the code. + weaken = 0 + nodamage = 1 + . = ..() // Execute the rest of the code. + +/obj/item/projectile/bullet/cap + name = "cap" + damage = 0 + nodamage = 1 + embed = 0 + sharp = 0 + +/obj/item/projectile/bullet/cap/fire() + loc = null + qdel(src) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index b5665a6af1c..79ffc1d0898 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -5,7 +5,6 @@ damage_type = BURN flag = "energy" - /obj/item/projectile/energy/electrode name = "electrode" icon_state = "spark" @@ -20,26 +19,23 @@ //Damage will be handled on the MOB side, to prevent window shattering. /obj/item/projectile/energy/electrode/on_hit(var/atom/target, var/blocked = 0) - if(!proj_hit) - if(!ismob(target) || blocked >= 2) //Fully blocked by mob or collided with dense object - burst into sparks! - var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread - sparks.set_up(1, 1, src) - sparks.start() - proj_hit = 1 - else if(iscarbon(target)) - var/mob/living/carbon/C = target - if(HULK in C.mutations) - C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - else if(C.status_flags & CANWEAKEN) - C.do_jitter_animation(jitter) - ..() - -/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet - if(!proj_hit) + . = ..() + if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks! var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread sparks.set_up(1, 1, src) sparks.start() - proj_hit = 1 + else if(iscarbon(target)) + var/mob/living/carbon/C = target + if(HULK in C.mutations) + C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + else if(C.status_flags & CANWEAKEN) + spawn(5) + C.do_jitter_animation(jitter) + +/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet + var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread + sparks.set_up(1, 1, src) + sparks.start() ..() /obj/item/projectile/energy/declone @@ -49,7 +45,6 @@ damage_type = CLONE irradiate = 10 - /obj/item/projectile/energy/dart name = "dart" icon_state = "toxin" @@ -63,7 +58,6 @@ icon_state = "toxin" damage = 10 damage_type = TOX - nodamage = 0 weaken = 5 stutter = 5 @@ -77,12 +71,28 @@ stutter = 5 /obj/item/projectile/energy/bolt/large - name = "largebolt" damage = 20 -/obj/item/projectile/energy/plasma +/obj/item/projectile/energy/shock_revolver + name = "shock bolt" + icon_state = "purple_laser" + var/chain + +/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/projectile/energy/shock_revolver/P = BB + spawn(1) + P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30) + +/obj/item/projectile/energy/shock_revolver/on_hit(atom/target) + . = ..() + if(isliving(target)) + tesla_zap(src, 3, 10000) + qdel(chain) + +/obj/item/projectile/energy/toxplasma name = "plasma bolt" icon_state = "energy" damage = 20 damage_type = TOX - irradiate = 20 \ No newline at end of file + irradiate = 20 diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm index 2fab1a4da18..4e5c6d27700 100644 --- a/code/modules/projectiles/projectile/force.dm +++ b/code/modules/projectiles/projectile/force.dm @@ -10,21 +10,8 @@ name = "force bolt" /obj/item/projectile/forcebolt/on_hit(var/atom/target, var/blocked = 0) - - var/obj/T = target - var/throwdir = get_dir(firer,target) - T.throw_at(get_edge_target_turf(target, throwdir),10,10) - return 1 - -/* -/obj/item/projectile/forcebolt/strong/on_hit(var/atom/target, var/blocked = 0) - - // NONE OF THIS WORKS. DO NOT USE. - var/throwdir = null - - for(var/mob/M in hearers(2, src)) - if(M.loc != src.loc) - throwdir = get_dir(src,target) - M.throw_at(get_edge_target_turf(M, throwdir),15,1) - return ..() -*/ \ No newline at end of file + . = ..() + if(blocked < 100) + var/obj/T = target + var/throwdir = get_dir(firer,target) + T.throw_at(get_edge_target_turf(target, throwdir),10,10) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index ecbbfb530f8..d91fd3898f7 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -4,15 +4,15 @@ damage = 0 damage_type = OXY nodamage = 1 + armour_penetration = 100 flag = "magic" /obj/item/projectile/magic/death name = "bolt of death" icon_state = "pulse1_bl" - damage = 9001 - damage_type = OXY + damage_type = BURN //OXY does not kill IPCs + damage = 50000 nodamage = 0 - flag = "magic" /obj/item/projectile/magic/fireball name = "bolt of fireball" @@ -20,9 +20,22 @@ damage = 10 damage_type = BRUTE nodamage = 0 - flag = "magic" + +/obj/item/projectile/magic/fireball/Range() + var/turf/T1 = get_step(src,turn(dir, -45)) + var/turf/T2 = get_step(src,turn(dir, 45)) + var/mob/living/L = locate(/mob/living) in T1 //if there's a mob alive in our front right diagonal, we hit it. + if(L && L.stat != DEAD) + Bump(L) //Magic Bullet #teachthecontroversy + return + L = locate(/mob/living) in T2 + if(L && L.stat != DEAD) + Bump(L) + return + ..() /obj/item/projectile/magic/fireball/on_hit(var/target) + . = ..() var/turf/T = get_turf(target) explosion(T, -1, 0, 2, 3, 0, flame_range = 2) if(ismob(target)) //multiple flavors of pain @@ -32,35 +45,13 @@ /obj/item/projectile/magic/resurrection name = "bolt of resurrection" icon_state = "ion" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/resurrection/on_hit(var/mob/living/carbon/target) - - if(istype(target,/mob)) + . = ..() + if(ismob(target)) var/old_stat = target.stat - if(isanimal(target) && target.stat == DEAD) - var/mob/living/simple_animal/O = target - var/mob/living/simple_animal/A = new O.type(O.loc) - A.real_name = O.real_name - A.name = O.name - if(iscorgi(O)) - var/mob/living/simple_animal/pet/corgi/C = O - if(C.inventory_head) - C.inventory_head.loc = C.loc - if(C.inventory_back) - C.inventory_back.loc = C.loc - if(O.mind) - O.mind.transfer_to(A) - else - A.key = O.key - qdel(O) - target = A - else - target.revive() - target.suiciding = 0 + target.suiciding = 0 + target.revive() if(!target.ckey) for(var/mob/dead/observer/ghost in player_list) if(target.real_name == ghost.real_name) @@ -74,14 +65,11 @@ /obj/item/projectile/magic/teleport name = "bolt of teleportation" icon_state = "bluespace" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" var/inner_tele_radius = 0 var/outer_tele_radius = 6 /obj/item/projectile/magic/teleport/on_hit(var/mob/target) + . = ..() var/teleammount = 0 var/teleloc = target if(!isturf(target)) @@ -97,37 +85,46 @@ /obj/item/projectile/magic/door name = "bolt of door creation" icon_state = "energy" - damage = 0 - damage_type = OXY - nodamage = 1 - flag = "magic" + var/list/door_types = list(/obj/structure/mineral_door/wood,/obj/structure/mineral_door/iron,/obj/structure/mineral_door/silver,\ + /obj/structure/mineral_door/gold,/obj/structure/mineral_door/uranium,/obj/structure/mineral_door/sandstone,/obj/structure/mineral_door/transparent/plasma,\ + /obj/structure/mineral_door/transparent/diamond) /obj/item/projectile/magic/door/on_hit(var/atom/target) + . = ..() var/atom/T = target.loc - if(isturf(target)) - if(target.density) - new /obj/structure/mineral_door/wood(target) - target:ChangeTurf(/turf/simulated/floor/plating) - else if (isturf(T)) - if(T.density) - new /obj/structure/mineral_door/wood(T) - T:ChangeTurf(/turf/simulated/floor/plating) + if(isturf(target) && target.density) + CreateDoor(target) + else if (isturf(T) && T.density) + CreateDoor(T) + else if(istype(target, /obj/machinery/door)) + OpenDoor(target) + +/obj/item/projectile/magic/door/proc/CreateDoor(turf/T) + var/door_type = pick(door_types) + var/obj/structure/mineral_door/D = new door_type(T) + T.ChangeTurf(/turf/simulated/floor/plasteel) + D.Open() + +/obj/item/projectile/magic/door/proc/OpenDoor(var/obj/machinery/door/D) + if(istype(D,/obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/A = D + A.locked = 0 + D.open() /obj/item/projectile/magic/change name = "bolt of change" icon_state = "ice_1" - damage = 0 damage_type = BURN - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/change/on_hit(var/atom/change) + . = ..() wabbajack(change) proc/wabbajack(mob/living/M) if(istype(M)) if(istype(M, /mob/living) && M.stat != DEAD) - if(M.notransform) return + if(M.notransform) + return M.notransform = 1 M.canmove = 0 M.icon = null @@ -136,7 +133,9 @@ proc/wabbajack(mob/living/M) if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) qdel(Robot.mmi) + if(Robot.mmi) + qdel(Robot.mmi) + Robot.notify_ai(1) else if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -146,7 +145,8 @@ proc/wabbajack(mob/living/M) for(var/i in H.internal_organs) qdel(i) for(var/obj/item/W in M) - M.unEquip(W) + M.unEquip(W, 1) + qdel(W) var/mob/living/new_mob @@ -166,8 +166,6 @@ proc/wabbajack(mob/living/M) Robot.mmi.transfer_identity(M) //Does not transfer key/client. if("slime") new_mob = new /mob/living/carbon/slime(M.loc) -/* if(prob(50)) - new_mob.is_adult = 1*/ new_mob.universal_speak = 1 if("xeno") if(prob(50)) @@ -175,14 +173,6 @@ proc/wabbajack(mob/living/M) else new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) new_mob.universal_speak = 1 - - /*var/alien_caste = pick("Hunter","Sentinel","Drone","Larva") - switch(alien_caste) - if("Hunter") new_mob = new /mob/living/carbon/alien/humanoid/hunter(M.loc) - if("Sentinel") new_mob = new /mob/living/carbon/alien/humanoid/sentinel(M.loc) - if("Drone") new_mob = new /mob/living/carbon/alien/humanoid/drone(M.loc) - else new_mob = new /mob/living/carbon/alien/larva(M.loc) - new_mob.universal_speak = 1*/ if("animal") if(prob(50)) var/beast = pick("carp","bear","mushroom","statue", "bat", "goat", "tomato") @@ -225,7 +215,6 @@ proc/wabbajack(mob/living/M) randomize = picked_species var/datum/preferences/A = new() //Randomize appearance for the human A.copy_to(new_mob) - else return @@ -246,13 +235,10 @@ proc/wabbajack(mob/living/M) /obj/item/projectile/magic/animate name = "bolt of animation" icon_state = "red_1" - damage = 0 damage_type = BURN - nodamage = 1 - flag = "magic" /obj/item/projectile/magic/animate/Bump(var/atom/change) - . = ..() + ..() if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects)) if(istype(change, /obj/structure/closet/statue)) for(var/mob/living/carbon/human/H in change.contents) @@ -269,8 +255,11 @@ proc/wabbajack(mob/living/M) qdel(src) else var/obj/O = change - new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer) + if(istype(O, /obj/item/weapon/gun)) + new /mob/living/simple_animal/hostile/mimic/copy/ranged(O.loc, O, firer) + else + new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, firer) else if(istype(change, /mob/living/simple_animal/hostile/mimic/copy)) // Change our allegiance! var/mob/living/simple_animal/hostile/mimic/copy/C = change - C.ChangeOwner(firer) \ No newline at end of file + C.ChangeOwner(firer) diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 81defd55743..12e7b30c759 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -1,42 +1,63 @@ /obj/item/projectile/bullet/reusable name = "reusable bullet" desc = "How do you even reuse a bullet?" - var/obj/item/ammo_casing/caseless/ammo_type = /obj/item/ammo_casing/caseless/ - var/hit = 0 + var/ammo_type = /obj/item/ammo_casing/caseless/ + var/dropped = 0 -/obj/item/projectile/bullet/reusable/on_hit(var/atom/target, var/blocked = 0) - if(!proj_hit) - proj_hit = 1 - if (src.contents.len) - var/obj/content - for(content in src.contents) - content.loc = src.loc - else - new ammo_type(src.loc) - ..() +/obj/item/projectile/bullet/reusable/on_hit(atom/target, blocked = 0) + . = ..() + handle_drop() /obj/item/projectile/bullet/reusable/on_range() - if(!proj_hit) - if (src.contents.len) - var/obj/content - for(content in src.contents) - content.loc = src.loc - else - new ammo_type(src.loc) + handle_drop() ..() +/obj/item/projectile/bullet/reusable/proc/handle_drop() + if(!dropped) + new ammo_type(loc) + dropped = 1 + +/obj/item/projectile/bullet/reusable/magspear + name = "magnetic spear" + desc = "WHITE WHALE, HOLY GRAIL" + damage = 30 //takes 3 spears to kill a mega carp, one to kill a normal carp + icon_state = "magspear" + ammo_type = /obj/item/ammo_casing/caseless/magspear + /obj/item/projectile/bullet/reusable/foam_dart name = "foam dart" desc = "I hope you're wearing eye protection." damage = 0 // It's a damn toy. damage_type = OXY nodamage = 1 - edge = 0 - embed = 0 - icon = 'icons/obj/toyguns.dmi' + icon = 'icons/obj/guns/toy.dmi' icon_state = "foamdart" ammo_type = /obj/item/ammo_casing/caseless/foam_dart - range = 10 + range = 10 + var/obj/item/weapon/pen/pen = null + edge = 0 + embed = 0 + +/obj/item/projectile/bullet/reusable/foam_dart/handle_drop() + if(dropped) + return + dropped = 1 + var/obj/item/ammo_casing/caseless/foam_dart/newdart = new ammo_type(loc) + var/obj/item/ammo_casing/caseless/foam_dart/old_dart = ammo_casing + newdart.modified = old_dart.modified + if(pen) + var/obj/item/projectile/bullet/reusable/foam_dart/newdart_FD = newdart.BB + newdart_FD.pen = pen + pen.loc = newdart_FD + pen = null + newdart.BB.damage = damage + newdart.BB.nodamage = nodamage + newdart.BB.damage_type = damage_type + newdart.update_icon() + +/obj/item/projectile/bullet/reusable/foam_dart/Destroy() + pen = null + return ..() /obj/item/projectile/bullet/reusable/foam_dart/riot name = "riot foam dart" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index ed64d73df4e..53527ef326e 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -6,15 +6,15 @@ nodamage = 1 flag = "energy" - - on_hit(var/atom/target, var/blocked = 0) - empulse(target, 1, 1) - return 1 - +/obj/item/projectile/ion/on_hit(var/atom/target, var/blocked = 0) + ..() + empulse(target, 1, 1) + return 1 /obj/item/projectile/ion/weak /obj/item/projectile/ion/weak/on_hit(atom/target, blocked = 0) + ..() empulse(target, 0, 0) return 1 @@ -26,9 +26,10 @@ sharp = 1 edge = 1 - on_hit(var/atom/target, var/blocked = 0) - explosion(target, -1, 0, 2) - return 1 +/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0) + ..() + explosion(target, -1, 0, 2) + return 1 /obj/item/projectile/bullet/a40mm name ="40mm grenade" @@ -43,90 +44,84 @@ return 1 /obj/item/projectile/temp - name = "freeze beam" + name = "temperature beam" icon_state = "temp_4" damage = 0 damage_type = BURN nodamage = 1 flag = "energy" var/temperature = 300 - var/obj/item/weapon/gun/energy/temperature/T = null + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - OnFired() - T = shot_from - temperature = T.temperature - switch(temperature) - if(501 to INFINITY) - name = "searing beam" //if emagged - icon_state = "temp_8" - if(400 to 500) - name = "burning beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_2 - icon_state = "temp_7" - if(360 to 400) - name = "hot beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_1 - icon_state = "temp_6" - if(335 to 360) - name = "warm beam" //temp at which players get notified of their high body temp - icon_state = "temp_5" - if(295 to 335) - name = "ambient beam" - icon_state = "temp_4" - if(260 to 295) - name = "cool beam" //temp at which players get notified of their low body temp - icon_state = "temp_3" - if(200 to 260) - name = "cold beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_1 - icon_state = "temp_2" - if(120 to 260) - name = "ice beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_2 - icon_state = "temp_1" - if(-INFINITY to 120) - name = "freeze beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_3 - icon_state = "temp_0" - else - name = "temperature beam"//failsafe - icon_state = "temp_4" +/obj/item/projectile/temp/New(loc, shot_temp) + ..(loc) + if(shot_temp) + temperature = shot_temp + switch(temperature) + if(501 to INFINITY) + name = "searing beam" //if emagged + icon_state = "temp_8" + if(400 to 500) + name = "burning beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_2 + icon_state = "temp_7" + if(360 to 400) + name = "hot beam" //temp at which mobs start taking HEAT_DAMAGE_LEVEL_1 + icon_state = "temp_6" + if(335 to 360) + name = "warm beam" //temp at which players get notified of their high body temp + icon_state = "temp_5" + if(295 to 335) + name = "ambient beam" + icon_state = "temp_4" + if(260 to 295) + name = "cool beam" //temp at which players get notified of their low body temp + icon_state = "temp_3" + if(200 to 260) + name = "cold beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_1 + icon_state = "temp_2" + if(120 to 260) + name = "ice beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_2 + icon_state = "temp_1" + if(-INFINITY to 120) + name = "freeze beam" //temp at which mobs start taking COLD_DAMAGE_LEVEL_3 + icon_state = "temp_0" + else + name = "temperature beam"//failsafe + icon_state = "temp_4" + ..() - on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob - if(istype(target, /mob/living)) - var/mob/living/M = target - M.bodytemperature = temperature - if(temperature > 500)//emagged - M.adjust_fire_stacks(0.5) - M.IgniteMob() - playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0) - return 1 +/obj/item/projectile/temp/on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob + ..() + if(isliving(target)) + var/mob/living/M = target + M.bodytemperature = temperature + if(temperature > 500)//emagged + M.adjust_fire_stacks(0.5) + M.IgniteMob() + playsound(M.loc, 'sound/effects/bamf.ogg', 50, 0) + return 1 /obj/item/projectile/meteor name = "meteor" icon = 'icons/obj/meteor.dmi' - icon_state = "smallf" + icon_state = "small" damage = 0 damage_type = BRUTE nodamage = 1 flag = "bullet" - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return - - sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits - - if(src)//Do not add to this if() statement, otherwise the meteor won't delete them - if(A) - - A.ex_act(2) - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) - - for(var/mob/M in range(10, src)) - if(!M.stat && !istype(M, /mob/living/silicon/ai))\ - shake_camera(M, 3, 1) - qdel(src) - return 1 - else - return 0 +/obj/item/projectile/meteor/Bump(atom/A, yes) + if(yes) + return + if(A == firer) + loc = A.loc + return + playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1) + for(var/mob/M in urange(10, src)) + if(!M.stat) + shake_camera(M, 3, 1) + qdel(src) /obj/item/projectile/energy/floramut name = "alpha somatoray" @@ -136,36 +131,31 @@ nodamage = 1 flag = "energy" - on_hit(var/atom/target, var/blocked = 0) - var/mob/living/M = target - if(ishuman(target)) - var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) - if(prob(15)) - M.apply_effect((rand(30,80)),IRRADIATE) - M.Weaken(5) - for (var/mob/V in viewers(src)) - V.show_message("\red [M] writhes in pain as \his vacuoles boil.", 3, "\red You hear the crunching of leaves.", 2) - if(prob(35)) - // for (var/mob/V in viewers(src)) //Public messages commented out to prevent possible metaish genetics experimentation and stuff. - Cheridan - // V.show_message("\red [M] is mutated by the radiation beam.", 3, "\red You hear the snapping of twigs.", 2) - if(prob(80)) - randmutb(M) - domutcheck(M,null) - else - randmutg(M) - domutcheck(M,null) +/obj/item/projectile/energy/floramut/on_hit(var/atom/target, var/blocked = 0) + ..() + var/mob/living/M = target + if(ishuman(target)) + var/mob/living/carbon/human/H = M + if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) + if(prob(15)) + M.apply_effect((rand(30,80)),IRRADIATE) + M.Weaken(5) + for (var/mob/V in viewers(src)) + V.show_message("[M] writhes in pain as \his vacuoles boil.", 3, "You hear the crunching of leaves.", 2) + if(prob(35)) + if(prob(80)) + randmutb(M) + domutcheck(M,null) else - M.adjustFireLoss(rand(5,15)) - M.show_message("\red The radiation beam singes you!") - // for (var/mob/V in viewers(src)) - // V.show_message("\red [M] is singed by the radiation beam.", 3, "\red You hear the crackle of burning leaves.", 2) - else if(istype(target, /mob/living/carbon/)) - // for (var/mob/V in viewers(src)) - // V.show_message("The radiation beam dissipates harmlessly through [M]", 3) - M.show_message("\blue The radiation beam dissipates harmlessly through your body.") - else - return 1 + randmutg(M) + domutcheck(M,null) + else + M.adjustFireLoss(rand(5,15)) + M.show_message("The radiation beam singes you!") + else if(istype(target, /mob/living/carbon/)) + M.show_message("The radiation beam dissipates harmlessly through your body.") + else + return 1 /obj/item/projectile/energy/florayield name = "beta somatoray" @@ -175,40 +165,42 @@ nodamage = 1 flag = "energy" - on_hit(var/atom/target, var/blocked = 0) - var/mob/M = target - if(ishuman(target)) //These rays make plantmen fat. - var/mob/living/carbon/human/H = M - if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) - M.nutrition += 30 - else if (istype(target, /mob/living/carbon/)) - M.show_message("\blue The radiation beam dissipates harmlessly through your body.") - else - return 1 +/obj/item/projectile/energy/florayield/on_hit(var/atom/target, var/blocked = 0) + ..() + var/mob/M = target + if(ishuman(target)) //These rays make plantmen fat. + var/mob/living/carbon/human/H = M + if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) + M.nutrition += 30 + else if (istype(target, /mob/living/carbon/)) + M.show_message("The radiation beam dissipates harmlessly through your body.") + else + return 1 /obj/item/projectile/beam/mindflayer name = "flayer ray" - on_hit(var/atom/target, var/blocked = 0) - if(ishuman(target)) - var/mob/living/carbon/human/M = target - M.adjustBrainLoss(20) - M.hallucination += 20 +/obj/item/projectile/beam/mindflayer/on_hit(var/atom/target, var/blocked = 0) + . = ..() + if(ishuman(target)) + var/mob/living/carbon/human/M = target + M.adjustBrainLoss(20) + M.hallucination += 20 /obj/item/projectile/clown name = "snap-pop" icon = 'icons/obj/toy.dmi' icon_state = "snappop" - Bump(atom/A as mob|obj|turf|area) - 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/ash(src.loc) - src.visible_message("\red The [src.name] explodes!","\red You hear a snap!") - playsound(src, 'sound/effects/snap.ogg', 50, 1) - qdel(src) +/obj/item/projectile/clown/Bump(atom/A as mob|obj|turf|area) + 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/ash(loc) + visible_message("The [name] explodes!","You hear a snap!") + playsound(src, 'sound/effects/snap.ogg', 50, 1) + qdel(src) /obj/item/projectile/kinetic name = "kinetic force" @@ -239,11 +231,9 @@ obj/item/projectile/kinetic/New() damage *= 4 ..() -/obj/item/projectile/kinetic/Range() - range-- - if(range <= 0) - new /obj/item/effect/kinetic_blast(src.loc) - qdel(src) +/obj/item/projectile/kinetic/on_range() + new /obj/effect/kinetic_blast(loc) + ..() /obj/item/projectile/kinetic/on_hit(atom/target) . = ..() @@ -251,23 +241,57 @@ obj/item/projectile/kinetic/New() if(istype(target_turf, /turf/simulated/mineral)) var/turf/simulated/mineral/M = target_turf M.gets_drilled(firer) - new /obj/item/effect/kinetic_blast(target_turf) - if(src.splash) + new /obj/effect/kinetic_blast(target_turf) + if(splash) for(var/turf/T in range(splash, target_turf)) if(istype(T, /turf/simulated/mineral)) var/turf/simulated/mineral/M = T M.gets_drilled(firer) -/obj/item/effect/kinetic_blast +/obj/effect/kinetic_blast name = "kinetic explosion" icon = 'icons/obj/projectiles.dmi' icon_state = "kinetic_blast" layer = 4.1 -/obj/item/effect/kinetic_blast/New() +/obj/effect/kinetic_blast/New() spawn(4) qdel(src) +/obj/item/projectile/beam/wormhole + name = "bluespace beam" + icon_state = "spark" + hitsound = "sparks" + damage = 3 + var/obj/item/weapon/gun/energy/wormhole_projector/gun + color = "#33CCFF" + +/obj/item/projectile/beam/wormhole/orange + name = "orange bluespace beam" + color = "#FF6600" + +/obj/item/projectile/beam/wormhole/New(var/obj/item/ammo_casing/energy/wormhole/casing) + if(casing) + gun = casing.gun + +/obj/item/projectile/beam/wormhole/on_hit(atom/target) + if(ismob(target)) + var/turf/portal_destination = pick(orange(6, src)) + do_teleport(target, portal_destination) + return ..() + if(!gun) + qdel(src) + gun.create_portal(src) + +/obj/item/projectile/beam/wormhole/on_hit(atom/target) + if(ismob(target)) + var/turf/portal_destination = pick(orange(6, src)) + do_teleport(target, portal_destination) + return ..() + if(!gun) + qdel(src) + gun.create_portal(src) + /obj/item/projectile/bullet/frag12 name ="explosive slug" damage = 25 @@ -278,25 +302,6 @@ obj/item/projectile/kinetic/New() explosion(target, -1, 0, 1) return 1 -/obj/item/projectile/energy/teleport - name = "teleportation burst" - icon_state = "bluespace" - damage = 0 - nodamage = 1 - var/obj/item/weapon/gun/energy/telegun/T = null - var/teleport_target = null - - OnFired() - T = shot_from - teleport_target = T.teleport_target - -/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0) - if(isliving(target)) - if(teleport_target) - do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon - else - do_teleport(target, target, 15) //Otherwise it just warps you off somewhere. - /obj/item/projectile/plasma name = "plasma blast" icon_state = "plasmacutter" @@ -321,8 +326,9 @@ obj/item/projectile/kinetic/New() if(istype(target, /turf/simulated/mineral)) var/turf/simulated/mineral/M = target M.gets_drilled(firer) - range = max(range - 1, 1) - return -1 + Range() + if(range > 0) + return -1 /obj/item/projectile/plasma/adv range = 5 @@ -331,29 +337,24 @@ obj/item/projectile/kinetic/New() damage = 10 range = 6 -/obj/item/projectile/beam/wormhole - name = "bluespace beam" - icon_state = "spark" - hitsound = "sparks" - damage = 3 - var/obj/item/weapon/gun/energy/wormhole_projector/gun = null - color = "#33CCFF" +/obj/item/projectile/energy/teleport + name = "teleportation burst" + icon_state = "bluespace" + damage = 0 + nodamage = 1 + var/teleport_target = null -/obj/item/projectile/beam/wormhole/orange - name = "orange bluespace beam" - color = "#FF6600" +/obj/item/projectile/energy/teleport/New(loc, tele_target) + ..(loc) + if(tele_target) + teleport_target = tele_target -/obj/item/projectile/beam/wormhole/OnFired() - gun = shot_from - -/obj/item/projectile/beam/wormhole/on_hit(atom/target) - if(ismob(target)) - var/turf/portal_destination = pick(orange(6, src)) - do_teleport(target, portal_destination) - return ..() - if(!gun) - qdel(src) - gun.create_portal(src) +/obj/item/projectile/energy/teleport/on_hit(var/atom/target, var/blocked = 0) + if(isliving(target)) + if(teleport_target) + do_teleport(target, teleport_target, 0)//teleport what's in the tile to the beacon + else + do_teleport(target, target, 15) //Otherwise it just warps you off somewhere. /obj/item/projectile/snowball name = "snowball" @@ -363,6 +364,7 @@ obj/item/projectile/kinetic/New() damage_type = BURN /obj/item/projectile/snowball/on_hit(atom/target) //chilling + . = ..() if(istype(target, /mob/living)) var/mob/living/M = target M.bodytemperature = max(0, M.bodytemperature - 50) //each hit will drop your body temp, so don't get surrounded! @@ -380,9 +382,38 @@ obj/item/projectile/kinetic/New() ..() /obj/item/projectile/ornament/on_hit(atom/target) //knockback + ..() if(istype(target, /turf)) return 0 var/obj/T = target var/throwdir = get_dir(firer,target) T.throw_at(get_edge_target_turf(target, throwdir),10,10) - return 1 \ No newline at end of file + return 1 + +/obj/item/projectile/mimic + name = "googly-eyed gun" + hitsound = 'sound/weapons/genhit1.ogg' + damage = 0 + nodamage = 1 + damage_type = BURN + flag = "melee" + var/obj/item/weapon/gun/stored_gun + +/obj/item/projectile/mimic/New(loc, mimic_type) + ..(loc) + if(mimic_type) + stored_gun = new mimic_type(src) + icon = stored_gun.icon + icon_state = stored_gun.icon_state + overlays = stored_gun.overlays + SpinAnimation(20, -1) + +/obj/item/projectile/mimic/on_hit(atom/target) + ..() + var/turf/T = get_turf(src) + var/obj/item/weapon/gun/G = stored_gun + stored_gun = null + G.forceMove(T) + var/mob/living/simple_animal/hostile/mimic/copy/ranged/R = new /mob/living/simple_animal/hostile/mimic/copy/ranged(T, G, firer) + if(ismob(target)) + R.target = target diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 9be9ea9c124..2db8c339935 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -302,14 +302,14 @@ var/const/INGEST = 2 var/list/seen = viewers(4, get_turf(my_atom)) for(var/mob/M in seen) if(!C.no_message) - to_chat(M, "\blue \icon[my_atom] [C.mix_message]") + to_chat(M, "\blue [bicon(my_atom)] [C.mix_message]") if(istype(my_atom, /obj/item/slime_extract)) var/obj/item/slime_extract/ME2 = my_atom ME2.Uses-- if(ME2.Uses <= 0) // give the notification that the slime core is dead for(var/mob/M in seen) - to_chat(M, "\blue \icon[my_atom] The [my_atom]'s power is consumed in the reaction.") + to_chat(M, "\blue [bicon(my_atom)] The [my_atom]'s power is consumed in the reaction.") ME2.name = "used slime extract" ME2.desc = "This extract has been used up." diff --git a/code/modules/reagents/grenade_launcher.dm b/code/modules/reagents/grenade_launcher.dm deleted file mode 100644 index 9b9484ba60e..00000000000 --- a/code/modules/reagents/grenade_launcher.dm +++ /dev/null @@ -1,111 +0,0 @@ - - -/obj/item/weapon/gun/grenadelauncher - name = "grenade launcher" - icon = 'icons/obj/gun.dmi' - icon_state = "riotgun" - item_state = "riotgun" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - var/list/grenades = new/list() - var/max_grenades = 3 - var/ammo_name = "grenade" - var/ammo_type = /obj/item/weapon/grenade - var/unloaded - - materials = list(MAT_METAL=2000) - -/obj/item/weapon/gun/grenadelauncher/examine(mob/user) - if(..(user, 2)) - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/attackby(obj/item/I as obj, mob/user as mob, params) - - if((istype(I, ammo_type))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - to_chat(user, "\blue You put the [ammo_name] in the [name].") - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - else - to_chat(usr, "\red The grenade launcher cannot hold more [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/afterattack(obj/target, mob/user , flag) - - if (istype(target, /obj/item/weapon/storage/backpack )) - return - - else if (locate (/obj/structure/table, src.loc)) - return - - else if(target == user) - return - - if(grenades.len) - spawn(0) fire_grenade(target,user) - else - to_chat(usr, "\red The [name] is empty.") - -/obj/item/weapon/gun/grenadelauncher/proc/fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a [ammo_name]!", user), 1) - to_chat(user, "\red You fire the [name]!") - var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! - grenades -= F - F.loc = user.loc - F.throw_at(target, 30, 2, user) - message_admins("[key_name_admin(user)] fired a [ammo_name] ([F.name]) from a launcher ([name]).") - log_game("[key_name_admin(user)] used a [ammo_name] ([name]).") - F.active = 1 - F.icon_state = initial(icon_state) + "_active" - playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(15) - F.prime() - - -/obj/item/weapon/gun/grenadelauncher/piecannon - name = "pie cannon" - icon = 'icons/obj/gun.dmi' - icon_state = "piecannon1" - item_state = "piecannon1" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - clumsy_check = 0 - grenades = new/list() - max_grenades = 5 - ammo_name = "cream pie" - ammo_type = /obj/item/weapon/reagent_containers/food/snacks/pie - -/obj/item/weapon/gun/grenadelauncher/piecannon/New() - ..() - for(var/i=0, i < max_grenades, i++) - var/obj/item/weapon/reagent_containers/food/snacks/pie/P = new /obj/item/weapon/reagent_containers/food/snacks/pie(src) - grenades += P - -/obj/item/weapon/gun/grenadelauncher/piecannon/attackby(obj/item/I as obj, mob/user as mob, params) - if((istype(I, ammo_type))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - to_chat(user, "\blue You put the [ammo_name] in the [name].") - to_chat(user, "\blue [grenades.len] / [max_grenades] [ammo_name]s.") - icon_state = "piecannon1" - else - to_chat(usr, "\red The grenade launcher cannot hold more [ammo_name]s.") - -/obj/item/weapon/gun/grenadelauncher/piecannon/fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a [ammo_name]!", user), 1) - to_chat(user, "\red You fire the [name]!") - var/obj/item/weapon/reagent_containers/food/snacks/pie/P = grenades[1] //Now with less copypasta! - grenades -= P - P.loc = user.loc - P.throw_at(target, 30, 2, user) - if(!grenades.len) - icon_state = "piecannon0" diff --git a/code/modules/reagents/newchem/drinks.dm b/code/modules/reagents/newchem/drinks.dm index c09b1a06fba..a9912f8722b 100644 --- a/code/modules/reagents/newchem/drinks.dm +++ b/code/modules/reagents/newchem/drinks.dm @@ -36,9 +36,6 @@ id = "applejack" description = "A highly concentrated alcoholic beverage made by repeatedly freezing cider and removing the ice." color = "#997A00" - slur_start = 30 - brawl_start = 40 - confused_start = 100 alcohol_perc = 0.4 /datum/chemical_reaction/applejack @@ -120,14 +117,7 @@ color = "#1BB1FF" process_flags = ORGANIC | SYNTHETIC metabolization_rate = 0.4 - vomit_start = INFINITY // - blur_start = INFINITY // - pass_out = INFINITY //INFINITY, so that IPCs don't puke and stuff - var/spark_start = 50 //amount absorbed after which mob starts sparking - var/collapse_start = 80 //amount absorbed after wich mob starts sparking and collapsing (DOUBLE THE SPARKS, DOUBLE THE FUN) - var/braindamage_start = 250 //amount absorbed after which mob starts taking a small amount of brain damage - - + alcohol_perc = 0.5 /datum/chemical_reaction/synthanol name = "Synthanol" @@ -139,26 +129,7 @@ mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' /datum/reagent/ethanol/synthanol/on_mob_life(var/mob/living/M as mob, var/alien) - - var/d = 0 - // make all the beverages work together - for(var/datum/reagent/ethanol/synthanol/A in holder.reagent_list) - if(isnum(A.current_cycle)) d += A.current_cycle * A.alcohol_perc - - if(M.isSynthetic()) //works normally on synthetics - if(d >= spark_start && prob(25)) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, M) - s.start() - if(d >= collapse_start && prob(10)) - M.emote("collapse") - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(3, 1, M) - s.start() - if(d >= braindamage_start && prob(10)) - M.adjustBrainLoss(1) - - else + if(!M.isSynthetic()) holder.remove_reagent(id, 3.6) //gets removed from organics very fast if(prob(25)) holder.remove_reagent(id, 15) @@ -179,7 +150,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "An oily substance that an IPC could technically consider a 'drink'." reagent_state = LIQUID color = "#363636" - alcohol_perc = 0.5 + alcohol_perc = 0.25 /datum/chemical_reaction/synthanol/robottears name = "Robot Tears" @@ -195,7 +166,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "A fruit drink meant only for synthetics, however that works." reagent_state = LIQUID color = "#adb21f" - alcohol_perc = 0.3 + alcohol_perc = 0.2 /datum/chemical_reaction/synthanol/trinary name = "Trinary" @@ -211,7 +182,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "A drink containing some organic ingredients, but meant only for synthetics." reagent_state = LIQUID color = "#5b3210" - alcohol_perc = 0.5 + alcohol_perc = 0.25 /datum/chemical_reaction/synthanol/servo name = "Servo" @@ -227,7 +198,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "A potent mix of alcohol and synthanol. Will only work on synthetics." reagent_state = LIQUID color = "#e7ae04" - alcohol_perc = 0.2 + alcohol_perc = 0.15 /datum/chemical_reaction/synthanol/uplink name = "Uplink" @@ -242,7 +213,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "The classic drink adjusted for a robot's tastes." reagent_state = LIQUID color = "#7204e7" - alcohol_perc = 0.5 + alcohol_perc = 0.25 /datum/chemical_reaction/synthanol/synthnsoda name = "Synth 'n Soda" @@ -257,7 +228,7 @@ datum/reagent/ethanol/synthanol/reaction_mob(var/mob/M, var/method=TOUCH, var/vo description = "Someone mixed wine and alcohol for robots. Hope you're proud of yourself." reagent_state = LIQUID color = "#d004e7" - alcohol_perc = 0.5 + alcohol_perc = 0.25 /datum/chemical_reaction/synthanol/synthignon name = "Synthignon" diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/newchem/medicine.dm index 33f04d5e6a8..a1e990ec51e 100644 --- a/code/modules/reagents/newchem/medicine.dm +++ b/code/modules/reagents/newchem/medicine.dm @@ -774,6 +774,7 @@ datum/reagent/antihol datum/reagent/antihol/on_mob_life(var/mob/living/M as mob) M.slurring = 0 + M.AdjustDrunk(-4) M.reagents.remove_all_type(/datum/reagent/ethanol, 8, 0, 1) if(M.toxloss <= 25) M.adjustToxLoss(-2.0) @@ -1059,4 +1060,4 @@ datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/M) M.adjustBrainLoss(-15*REM) M.adjustCloneLoss(-3*REM) ..() - return \ No newline at end of file + return diff --git a/code/modules/reagents/newchem/patch.dm b/code/modules/reagents/newchem/patch.dm index a7aae47d8de..793b6f8ae6f 100644 --- a/code/modules/reagents/newchem/patch.dm +++ b/code/modules/reagents/newchem/patch.dm @@ -10,37 +10,42 @@ apply_method = "apply" transfer_efficiency = 0.5 //patches aren't as effective at getting chemicals into the bloodstream. -/obj/item/weapon/reagent_containers/food/pill/patch/New() - ..() - icon_state = "bandaid" - /obj/item/weapon/reagent_containers/food/pill/patch/afterattack(obj/target, mob/user , proximity) return // thanks inheritance again /obj/item/weapon/reagent_containers/food/pill/patch/styptic name = "healing patch" desc = "Helps with brute injuries." - New() - ..() - reagents.add_reagent("styptic_powder", 40) + icon_state = "bandaid_brute" + instant_application = 1 + +/obj/item/weapon/reagent_containers/food/pill/patch/styptic/New() + ..() + reagents.add_reagent("styptic_powder", 40) /obj/item/weapon/reagent_containers/food/pill/patch/silver_sulf name = "burn patch" desc = "Helps with burn injuries." - New() - ..() - reagents.add_reagent("silver_sulfadiazine", 40) + icon_state = "bandaid_burn" + instant_application = 1 + +/obj/item/weapon/reagent_containers/food/pill/patch/silver_sulf/New() + ..() + reagents.add_reagent("silver_sulfadiazine", 40) /obj/item/weapon/reagent_containers/food/pill/patch/synthflesh name = "syntheflesh patch" desc = "Helps with burn injuries." - New() - ..() - reagents.add_reagent("synthflesh", 20) + instant_application = 1 + +/obj/item/weapon/reagent_containers/food/pill/patch/synthflesh/New() + ..() + reagents.add_reagent("synthflesh", 20) /obj/item/weapon/reagent_containers/food/pill/patch/nicotine name = "nicotine patch" desc = "Helps temporarily curb the cravings of nicotine dependency." - New() - ..() - reagents.add_reagent("nicotine", 20) \ No newline at end of file + +/obj/item/weapon/reagent_containers/food/pill/patch/nicotine/New() + ..() + reagents.add_reagent("nicotine", 20) \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm index 4479d24aa7c..10b5ff13344 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm @@ -156,8 +156,8 @@ name = "Cuba Libre" id = "cubalibre" result = "cubalibre" - required_reagents = list("rum" = 2, "cola" = 1) - result_amount = 3 + required_reagents = list("rum" = 2, "cola" = 2, "limejuice" = 1) + result_amount = 5 mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' /datum/chemical_reaction/mojito @@ -509,6 +509,14 @@ result_amount = 2 mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' +/datum/chemical_reaction/cafe_mocha + name = "Cafe Mocha" + id = "cafe_mocha" + result = "cafe_mocha" + required_reagents = list("cafe_latte" = 1, "chocolate" = 1) + result_amount = 2 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + /datum/chemical_reaction/acidspit name = "Acid Spit" id = "acidspit" @@ -667,4 +675,4 @@ result = "rewriter" required_reagents = list("spacemountainwind" = 1, "coffee" = 1) result_amount = 2 - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' \ No newline at end of file + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm index a466af1752d..5f96f794b34 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm +++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm @@ -109,16 +109,17 @@ max_temp = 273 mix_message = "Ice forms as the water freezes." mix_sound = null + /datum/chemical_reaction/water name = "Water" id = "water" result = "water" required_reagents = list("ice" = 1) result_amount = 1 - min_temp = 274 + min_temp = 301 // In Space.....ice melts at 82F...don't ask mix_message = "Water pools as the ice melts." mix_sound = null - + /datum/chemical_reaction/dough name = "Dough" id = "dough" diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm index 82d46d60519..a40345ffaac 100644 --- a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm +++ b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm @@ -7,64 +7,13 @@ nutriment_factor = 0 //So alcohol can fill you up! If they want to. color = "#404030" // rgb: 64, 64, 48 can_grow_in_plants = 0 //Alcoholic drinks won't be grown in plants (would "water down" random seed chems too much) - var/datum/martial_art/drunk_brawling/F = new var/dizzy_adj = 3 - var/slurr_adj = 3 - var/confused_adj = 2 - var/slur_start = 20 //amount absorbed after which mob starts slurring - var/brawl_start = 25 //amount absorbed after which mob switches to drunken brawling as a fighting style - var/confused_start = 30 //amount absorbed after which mob starts confusing directions - var/vomit_start = 45 //amount absorbed after which mob starts vomitting - var/blur_start = 70 //amount absorbed after which mob starts getting blurred vision - var/pass_out = 90 //amount absorbed after which mob starts passing out var/alcohol_perc = 1 //percentage of ethanol in a beverage 0.0 - 1.0 /datum/reagent/ethanol/on_mob_life(var/mob/living/M as mob, var/alien) - // Sobering multiplier. - // Sober block makes it more difficult to get drunk - var/sober_str=!(SOBER in M.mutations)?1:2 M.nutrition += nutriment_factor - - var/d = 0 - // make all the beverages work together - for(var/datum/reagent/ethanol/A in holder.reagent_list) - if(isnum(A.current_cycle)) d += A.current_cycle * A.alcohol_perc - - d/=sober_str - - var/obj/item/organ/internal/liver/L - if(ishuman(M) && !M.isSynthetic()) - var/mob/living/carbon/human/H = M - L = H.get_int_organ(/obj/item/organ/internal/liver) - d *= L ? L.alcohol_intensity : 5 - - M.dizziness += dizzy_adj. - if(d >= slur_start && d < pass_out) - if (!M.slurring) M.slurring = 1 - M.slurring += slurr_adj/sober_str - if(d >= brawl_start && ishuman(M)) - var/mob/living/carbon/human/H = M - F.teach(H,1) - if(src.volume < 3) - if(H.martial_art == F) - F.remove(H) - if(d >= confused_start && prob(33)) - if (!M.confused) M.confused = 1 - M.confused = max(M.confused+(confused_adj/sober_str),0) - if(d >= blur_start) - M.eye_blurry = max(M.eye_blurry, 10/sober_str) - M.drowsyness = max(M.drowsyness, 0) - if(d >= vomit_start) - if(prob(8)) - M.fakevomit() - if(d >= pass_out) - M.Paralyse(20 / sober_str) - M.drowsyness = max(M.drowsyness, 30/sober_str) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if (L) - L.take_damage(0.1, 1) - H.adjustToxLoss(0.1) + M.AdjustDrunk(alcohol_perc) + M.dizziness += dizzy_adj ..() return @@ -97,7 +46,7 @@ description = "An alcoholic beverage made from malted grains, hops, yeast, and water." nutriment_factor = 2 * FOOD_METABOLISM color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/beer/on_mob_life(var/mob/living/M as mob) ..() @@ -109,7 +58,7 @@ id = "cider" description = "An alcoholic beverage derived from apples." color = "#174116" - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/whiskey name = "Whiskey" @@ -174,7 +123,7 @@ id = "mojito" description = "If it's good enough for Spesscuba, it's good enough for you." color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/vodka name = "Vodka" @@ -226,8 +175,6 @@ description = "An unbelievably strong and potent variety of Cider." color = "#CF3811" dizzy_adj = 20 - slurr_adj = 20 - confused_adj = 3 alcohol_perc = 1 //because that's a thing it's supposed to do, I guess /datum/reagent/ethanol/ale @@ -265,7 +212,7 @@ description = "This appears to be beer mixed with milk. Disgusting." reagent_state = LIQUID color = "#895C4C" // rgb: 137, 92, 76 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/atomicbomb name = "Atomic Bomb" @@ -429,7 +376,7 @@ description = "Beer and Ale, brought together in a delicious mix. Intended for true men only." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/longislandicedtea name = "Long Island Iced Tea" @@ -517,7 +464,7 @@ description = "Barefoot and pregnant" reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/snowwhite name = "Snow White" @@ -525,7 +472,7 @@ description = "A cold refreshment" reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/demonsblood name = "Demons Blood" @@ -534,7 +481,6 @@ reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 dizzy_adj = 10 - slurr_adj = 10 alcohol_perc = 0.4 /datum/reagent/ethanol/vodkatonic @@ -544,7 +490,6 @@ reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 dizzy_adj = 4 - slurr_adj = 3 alcohol_perc = 0.3 /datum/reagent/ethanol/ginfizz @@ -554,7 +499,6 @@ reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 dizzy_adj = 4 - slurr_adj = 3 alcohol_perc = 0.4 /datum/reagent/ethanol/bahama_mama @@ -563,7 +507,7 @@ description = "Tropic cocktail." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/singulo name = "Singulo" @@ -572,7 +516,6 @@ reagent_state = LIQUID color = "#2E6671" // rgb: 46, 102, 113 dizzy_adj = 15 - slurr_adj = 15 alcohol_perc = 0.7 /datum/reagent/ethanol/sbiten @@ -603,7 +546,7 @@ description = "The true Viking drink! Even though it has a strange red color." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/mead name = "Mead" @@ -611,7 +554,7 @@ description = "A Vikings drink, though a cheap one." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/iced_beer name = "Iced Beer" @@ -619,7 +562,7 @@ description = "A beer which is so cold the air around it freezes." reagent_state = LIQUID color = "#664300" // rgb: 102, 67, 0 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/iced_beer/on_mob_life(var/mob/living/M as mob) ..() @@ -685,16 +628,10 @@ /datum/reagent/ethanol/neurotoxin/on_mob_life(var/mob/living/M as mob) M.weakened = max(M.weakened, 3) - M.dizziness +=6 - if(current_cycle >= 15 && current_cycle <45) - if (!M.slurring) - M.slurring = 1 - M.slurring += 3 - else if(current_cycle >= 45 && prob(50) && current_cycle <55) - M.confused = max(M.confused+3,0) - else if(current_cycle >=55) + dizzy_adj = 6 + if(current_cycle >=55) M.druggy = max(M.druggy, 55) - else if(current_cycle >=200) + if(current_cycle >=200) M.adjustToxLoss(2) ..() return @@ -739,7 +676,7 @@ description = "The surprise is, it's green!" reagent_state = LIQUID color = "#2E6671" // rgb: 46, 102, 113 - alcohol_perc = 0.1 + alcohol_perc = 0.2 /datum/reagent/ethanol/driestmartini name = "Driest Martini" @@ -754,8 +691,6 @@ if(current_cycle >= 55 && current_cycle <115) if (!M.stuttering) M.stuttering = 1 M.stuttering += 10 - else if(current_cycle >= 115 && prob(33)) - M.confused = max(M.confused+15,15) ..() return diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm b/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm index 45e0e2e8ac2..d52743c6ae6 100644 --- a/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm +++ b/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm @@ -241,6 +241,12 @@ M.adjustBruteLoss(-1) return +/datum/reagent/drink/coffee/cafe_latte/cafe_mocha + name = "Cafe Mocha" + id = "cafe_mocha" + description = "The perfect blend of coffe, milk, and chocolate." + color = "#673629" + /datum/reagent/drink/tea name = "Tea" id = "tea" diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/oldchem/reagents/reagents_water.dm index df9e0b29b64..11a5759fa5b 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_water.dm +++ b/code/modules/reagents/oldchem/reagents/reagents_water.dm @@ -297,6 +297,13 @@ if(data >= 75 && prob(33)) // 30 units, 150 seconds if (!M.confused) M.confused = 1 M.confused += 3 + if(isvampirethrall(M)) + ticker.mode.remove_vampire_mind(M.mind) + holder.remove_reagent(src.id, src.volume) + M.jitteriness = 0 + M.stuttering = 0 + M.confused = 0 + return if(iscultist(M)) ticker.mode.remove_cultist(M.mind) holder.remove_reagent(src.id, src.volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 13f4904369c..f75959544ef 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -87,7 +87,7 @@ if(reagents.has_reagent(bad_reagent)) badshit += reagents_to_log[bad_reagent] if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" + var/hl = "([english_list(badshit)])" message_admins("[key_name_admin(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl]") log_game("[key_name(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].") diff --git a/code/modules/reagents/reagent_containers/drugs.dm b/code/modules/reagents/reagent_containers/drugs.dm index db162b6f7cc..54c14f714ee 100644 --- a/code/modules/reagents/reagent_containers/drugs.dm +++ b/code/modules/reagents/reagent_containers/drugs.dm @@ -55,7 +55,7 @@ if(reagents.has_reagent(bad_reagent)) badshit += reagents_to_log[bad_reagent] if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" + var/hl = "([english_list(badshit)])" message_admins("[key_name_admin(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl]") log_game("[key_name(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].") diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index 8caaa5ff653..50a3ecd1a1d 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -10,6 +10,7 @@ var/apply_type = INGEST var/apply_method = "swallow" var/transfer_efficiency = 1.0 + var/instant_application = 0 //if we want to bypass the forcedfeed delay /obj/item/weapon/reagent_containers/food/New() ..() diff --git a/code/modules/reagents/reagent_containers/food/condiment.dm b/code/modules/reagents/reagent_containers/food/condiment.dm index e1fb06f1be7..2b53bfb2e6d 100644 --- a/code/modules/reagents/reagent_containers/food/condiment.dm +++ b/code/modules/reagents/reagent_containers/food/condiment.dm @@ -183,6 +183,15 @@ ..() reagents.add_reagent("sodiumchloride", 20) +/obj/item/weapon/reagent_containers/food/condiment/saltshaker/suicide_act(mob/user) + user.visible_message("[user] begins to swap forms with the salt shaker! It looks like \he's trying to commit suicide.") + var/newname = "[name]" + name = "[user.name]" + user.name = newname + user.real_name = newname + desc = "Salt. From dead crew, presumably." + return TOXLOSS + /obj/item/weapon/reagent_containers/food/condiment/peppermill name = "pepper mill" desc = "Often used to flavor food or make people sneeze." diff --git a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm index c7351d1c3fd..981bb7148a2 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm @@ -459,6 +459,10 @@ icon_state = "cafe_latte" name = "Cafe Latte" desc = "A nice, strong and refreshing beverage while you are reading." + if("cafe_mocha") + icon_state = "cafe_latte" + name = "Cafe Mocha" + desc = "The perfect blend of coffe, milk, and chocolate." if("acidspit") icon_state = "acidspitglass" name = "Acid Spit" diff --git a/code/modules/reagents/reagent_containers/food/snacks/candy.dm b/code/modules/reagents/reagent_containers/food/snacks/candy.dm index 1370eff0093..d13eb7ec145 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/candy.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/candy.dm @@ -139,13 +139,13 @@ reagents.add_reagent("sugar", 3) bitesize = 5 -/obj/item/weapon/reagent_containers/food/snacks/candy_corn +/obj/item/weapon/reagent_containers/food/snacks/candy/candy_corn name = "candy corn" desc = "It's a handful of candy corn. Cannot be stored in a detective's hat, alas." - icon_state = "candy_corn" + icon_state = "candycorn" filling_color = "#FFFCB0" -/obj/item/weapon/reagent_containers/food/snacks/candy_corn/New() +/obj/item/weapon/reagent_containers/food/snacks/candy/candy_corn/New() ..() reagents.add_reagent("nutriment", 4) reagents.add_reagent("sugar", 2) diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm index 457f473c8bb..31b1b2030e5 100644 --- a/code/modules/reagents/reagent_containers/glass_containers.dm +++ b/code/modules/reagents/reagent_containers/glass_containers.dm @@ -121,7 +121,7 @@ if(reagents.has_reagent(bad_reagent)) badshit += reagents_to_log[bad_reagent] if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" + var/hl = "([english_list(badshit)])" message_admins("[key_name_admin(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl]") log_game("[key_name(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].") diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 4af5ab79bc7..37c73ca760f 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -43,7 +43,7 @@ if(reagents.has_reagent(bad_reagent)) badshit += reagents_to_log[bad_reagent] if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" + var/hl = "([english_list(badshit)])" message_admins("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl] (JMP)") log_game("[user.name] ([user.ckey]) added [reagents.get_reagent_ids(1)] to \a [target] with [src].") diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 32a0e752913..efc6a48b1f9 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -155,7 +155,7 @@ /obj/item/weapon/reagent_containers/spray/chemsprayer name = "chem sprayer" desc = "A utility used to spray large amounts of reagents in a given area." - icon = 'icons/obj/gun.dmi' + icon = 'icons/obj/guns/projectile.dmi' icon_state = "chemsprayer" item_state = "chemsprayer" throwforce = 0 @@ -234,4 +234,4 @@ if (istype(A, /obj/effect/blob)) // blob damage in blob code return - ..() \ No newline at end of file + ..() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index bd8a22cd06f..91f12f8c00e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -17,6 +17,7 @@ w_class = 1 sharp = 1 var/mode = SYRINGE_DRAW + var/projectile_type = /obj/item/projectile/bullet/dart/syringe /obj/item/weapon/reagent_containers/syringe/on_reagent_change() update_icon() @@ -218,7 +219,7 @@ if(reagents.has_reagent(bad_reagent)) badshit += reagents_to_log[bad_reagent] if(badshit.len) - var/hl="\red ([english_list(badshit)]) \black" + var/hl = "([english_list(badshit)])" message_admins("[key_name_admin(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].[hl] ") log_game("[key_name(user)] added [reagents.get_reagent_ids(1)] to \a [target] with [src].") @@ -247,6 +248,12 @@ else trans = src.reagents.trans_to(target, amount_per_transfer_from_this) to_chat(user, "\blue You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units.") + if(istype(target, /obj/item/weapon/reagent_containers/food/pill/patch)) + var/obj/item/weapon/reagent_containers/food/pill/patch/P = target + if(P.instant_application) + to_chat(user, "You break the medical seal on the [P]!") + P.instant_application = 0 + if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT) mode = SYRINGE_DRAW update_icon() @@ -533,4 +540,4 @@ reagents.add_reagent("capulettium_plus", 5) reagents.add_reagent("sodium_thiopental", 5) mode = SYRINGE_INJECT - update_icon() \ No newline at end of file + update_icon() diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 89a73e31715..06dbba8d62e 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -49,6 +49,7 @@ other types of metals and chemistry for reagents). var/category = null //Primarily used for Mech Fabricators, but can be used for anything var/list/reagents = list() //List of reagents. Format: "id" = amount. var/maxstack = 1 + var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe //A proc to calculate the reliability of a design based on tech levels and innate modifiers. //Input: A list of /datum/tech; Output: The new reliabilty. diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 00530d2a8a3..7bcc42e4979 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -280,6 +280,17 @@ build_path = /obj/item/organ/internal/cyberimp/brain/anti_stun category = list("Misc", "Medical") +/datum/design/cyberimp_clownvoice + name = "Comical implant" + desc = "Uh oh." + id = "ci-clownvoice" + req_tech = list("materials" = 2, "biotech" = 2) + build_type = PROTOLATHE | MECHFAB + construction_time = 60 + materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_BANANIUM = 200) + build_path = /obj/item/organ/internal/cyberimp/brain/clown_voice + category = list("Misc", "Medical") + /datum/design/cyberimp_nutriment name = "Nutriment pump implant" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." diff --git a/code/modules/research/designs/stock_parts_designs.dm b/code/modules/research/designs/stock_parts_designs.dm index 81182661384..a1be7ffcf7a 100644 --- a/code/modules/research/designs/stock_parts_designs.dm +++ b/code/modules/research/designs/stock_parts_designs.dm @@ -11,6 +11,7 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/weapon/stock_parts/capacitor category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/basic_sensor name = "Basic Scanning Module" @@ -21,6 +22,7 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 20) build_path = /obj/item/weapon/stock_parts/scanning_module category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/micro_mani name = "Micro Manipulator" @@ -31,6 +33,7 @@ materials = list(MAT_METAL = 30) build_path = /obj/item/weapon/stock_parts/manipulator category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/basic_micro_laser name = "Basic Micro-Laser" @@ -41,6 +44,7 @@ materials = list(MAT_METAL = 10, MAT_GLASS = 20) build_path = /obj/item/weapon/stock_parts/micro_laser category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/basic_matter_bin name = "Basic Matter Bin" @@ -51,6 +55,7 @@ materials = list(MAT_METAL = 80) build_path = /obj/item/weapon/stock_parts/matter_bin category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/adv_capacitor name = "Advanced Capacitor" @@ -61,6 +66,7 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/weapon/stock_parts/capacitor/adv category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/adv_sensor name = "Advanced Scanning Module" @@ -71,6 +77,7 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 20) build_path = /obj/item/weapon/stock_parts/scanning_module/adv category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/nano_mani name = "Nano Manipulator" @@ -81,6 +88,7 @@ materials = list(MAT_METAL = 30) build_path = /obj/item/weapon/stock_parts/manipulator/nano category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/high_micro_laser name = "High-Power Micro-Laser" @@ -91,6 +99,7 @@ materials = list(MAT_METAL = 10, MAT_GLASS = 20) build_path = /obj/item/weapon/stock_parts/micro_laser/high category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/adv_matter_bin name = "Advanced Matter Bin" @@ -101,6 +110,7 @@ materials = list(MAT_METAL = 80) build_path = /obj/item/weapon/stock_parts/matter_bin/adv category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/super_capacitor name = "Super Capacitor" @@ -112,6 +122,7 @@ materials = list(MAT_METAL = 50, MAT_GLASS = 50, MAT_GOLD = 20) build_path = /obj/item/weapon/stock_parts/capacitor/super category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/phasic_sensor name = "Phasic Scanning Module" @@ -123,6 +134,7 @@ reliability = 72 build_path = /obj/item/weapon/stock_parts/scanning_module/phasic category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/pico_mani name = "Pico Manipulator" @@ -134,6 +146,7 @@ reliability = 73 build_path = /obj/item/weapon/stock_parts/manipulator/pico category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/ultra_micro_laser name = "Ultra-High-Power Micro-Laser" @@ -145,6 +158,7 @@ reliability = 70 build_path = /obj/item/weapon/stock_parts/micro_laser/ultra category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/super_matter_bin name = "Super Matter Bin" @@ -156,6 +170,7 @@ reliability = 75 build_path = /obj/item/weapon/stock_parts/matter_bin/super category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/quadratic_capacitor name = "Quadratic Capacitor" @@ -167,6 +182,7 @@ materials = list(MAT_METAL = 100, MAT_GLASS = 100, MAT_DIAMOND = 40) build_path = /obj/item/weapon/stock_parts/capacitor/quadratic category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/triphasic_scanning name = "Triphasic Scanning Module" @@ -178,6 +194,7 @@ reliability = 72 build_path = /obj/item/weapon/stock_parts/scanning_module/triphasic category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/femto_mani name = "Femto Manipulator" @@ -189,6 +206,7 @@ reliability = 73 build_path = /obj/item/weapon/stock_parts/manipulator/femto category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/quadultra_micro_laser name = "Quad-Ultra Micro-Laser" @@ -200,6 +218,7 @@ reliability = 70 build_path = /obj/item/weapon/stock_parts/micro_laser/quadultra category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/bluespace_matter_bin name = "Bluespace Matter Bin" @@ -211,6 +230,7 @@ reliability = 75 build_path = /obj/item/weapon/stock_parts/matter_bin/bluespace category = list("Stock Parts") + lathe_time_factor = 5 /datum/design/RPED name = "Rapid Part Exchange Device" @@ -240,4 +260,5 @@ build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) build_path = /obj/item/stack/sheet/mineral/abductor - category = list("Stock Parts") \ No newline at end of file + category = list("Stock Parts") + lathe_time_factor = 5 \ No newline at end of file diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 64ad0c962fc..f44e96ae78b 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -128,7 +128,7 @@ //WT550 Mags /datum/design/mag_oldsmg - name = "WT-550 Auto Gun Magazine (4.6×30mm)" + name = "WT-550 Auto Gun Magazine (4.6x30mm)" desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg" req_tech = list("combat" = 1, "materials" = 1) @@ -138,21 +138,21 @@ category = list("Weapons") /datum/design/mag_oldsmg/ap_mag - name = "WT-550 Auto Gun Armour Piercing Magazine (4.6×30mm AP)" + name = "WT-550 Auto Gun Armour Piercing Magazine (4.6x30mm AP)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ap" materials = list(MAT_METAL = 6000, MAT_SILVER = 600) build_path = /obj/item/ammo_box/magazine/wt550m9/wtap /datum/design/mag_oldsmg/ic_mag - name = "WT-550 Auto Gun Incendiary Magazine (4.6×30mm IC)" + name = "WT-550 Auto Gun Incendiary Magazine (4.6x30mm IC)" desc = "A 20 round armour piercing magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_ic" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic /datum/design/mag_oldsmg/tx_mag - name = "WT-550 Auto Gun Urnaium Magazine (4.6×30mm TX)" + name = "WT-550 Auto Gun Urnaium Magazine (4.6x30mm TX)" desc = "A 20 round urnaium tipped magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg_tx" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 38004bd49fa..c9ed686645a 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -219,6 +219,7 @@ --cloneCount if(cloneCount == 0) cloneMode = FALSE + return var/turf/dropturf = get_turf(pick(view(1,src))) if(!dropturf) //Failsafe to prevent the object being lost in the void forever. dropturf = get_turf(src) @@ -373,8 +374,7 @@ FB.current = start FB.yo = MT.y - start.y FB.xo = MT.x - start.x - spawn(1) - FB.process() + FB.fire() if(prob(EFFECT_PROB_LOW-badThingCoeff)) visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!") explosion(src.loc, -1, 0, 0, 0, 0, flame_range = 2) @@ -406,7 +406,7 @@ visible_message("[src] lowers [exp_on]'s temperature.") if(prob(EFFECT_PROB_LOW) && criticalReaction) visible_message("[src]'s emergency coolant system gives off a small ding!") - var/obj/machinery/vending/coffee/C = new /obj/machinery/vending/coffee(get_turf(pick(oview(1,src)))) + var/obj/item/weapon/reagent_containers/food/drinks/coffee/C = new /obj/item/weapon/reagent_containers/food/drinks/coffee(get_turf(pick(oview(1,src)))) playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) //Ding! Your death coffee is ready! chosenchem = pick("uranium","frostoil","ephedrine") C.reagents.remove_any(25) @@ -492,7 +492,7 @@ ejectItem() //Global reactions - + if(prob(EFFECT_PROB_VERYLOW) && prob(13)) visible_message("[src] improves [exp_on], drawing the life essence of those nearby!") for(var/mob/living/m in view(4,src)) @@ -504,7 +504,7 @@ reqs[T] = reqs[T] + 1 exp_on.origin_tech = list2params(reqs) investigate_log("Experimentor has set the origin tech of [exp_on] to [exp_on.origin_tech]", "experimentor") - + if(prob(EFFECT_PROB_VERYLOW-badThingCoeff) && prob(87)) var/globalMalf = rand(1,87) if(globalMalf < 15) diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index a528c643809..555fa7b22c1 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -103,12 +103,12 @@ var/global/list/obj/machinery/message_server/message_servers = list() if(2) if(!Console.silent) playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1) - Console.audible_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5) + Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'PRIORITY Alert in [sender]'"),,5) Console.message_log += "High Priority message from [sender]
[authmsg]" else if(!Console.silent) playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1) - Console.audible_message(text("\icon[Console] *The Requests Console beeps: 'Message from [sender]'"),,4) + Console.audible_message(text("[bicon(Console)] *The Requests Console beeps: 'Message from [sender]'"),,4) Console.message_log += "Message from [sender]
[authmsg]" Console.set_light(2) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 3c8b89ea2a0..cff54b3bd32 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -41,7 +41,7 @@ Note: Must be placed west/left of and R&D console to function. component_parts += new /obj/item/weapon/stock_parts/manipulator(null) component_parts += new /obj/item/weapon/reagent_containers/glass/beaker/large(null) component_parts += new /obj/item/weapon/reagent_containers/glass/beaker/large(null) - materials = new(src, list(MAT_METAL=1, MAT_GLASS=1, MAT_SILVER=1, MAT_GOLD=1, MAT_DIAMOND=1, MAT_PLASMA=1, MAT_URANIUM=1, MAT_BANANIUM=1)) + materials = new(src, list(MAT_METAL=1, MAT_GLASS=1, MAT_SILVER=1, MAT_GOLD=1, MAT_DIAMOND=1, MAT_PLASMA=1, MAT_URANIUM=1, MAT_BANANIUM=1, MAT_TRANQUILLITE=1)) RefreshParts() reagents.my_atom = src diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 9e8b29f94c1..2fdb61a706f 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -46,6 +46,11 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter var/screen = 1.0 //Which screen is currently showing. + + var/menu = 0 // Current menu. + var/submenu = 0 + var/wait_message = 0 + var/id = 0 //ID of the computer (for server restrictions). var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console @@ -173,7 +178,7 @@ proc/CallMaterialName(ID) to_chat(user, "You add the disk to the machine!") else if(!(linked_destroy && linked_destroy.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy)) ..() - src.updateUsrDialog() + nanomanager.update_uis(src) return /obj/machinery/computer/rdconsole/emag_act(user as mob) @@ -195,17 +200,36 @@ proc/CallMaterialName(ID) usr.set_machine(src) if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. var/temp_screen = text2num(href_list["menu"]) - screen = temp_screen + menu = temp_screen + if(href_list["submenu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. + var/temp_screen = text2num(href_list["submenu"]) + submenu = temp_screen if(href_list["category"]) - selected_category = href_list["category"] + var/compare + + matching_designs.Cut() + + if(menu == 4) + compare = PROTOLATHE + else + compare = IMPRINTER + + for(var/datum/design/D in files.known_designs) + if(!(D.build_type & compare)) + continue + if(href_list["category"] in D.category) + matching_designs.Add(D) + submenu = 1 + + selected_category = "Viewing Category [href_list["category"]]" else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk. - screen = 0.0 + wait_message = "Updating Database...." spawn(50) - screen = 1.2 + wait_message = 0 files.AddTech2Known(t_disk.stored) - updateUsrDialog() + nanomanager.update_uis(src) griefProtection() //Update centcom too else if(href_list["clear_tech"]) //Erase data on the technology disk. @@ -216,21 +240,23 @@ proc/CallMaterialName(ID) if(t_disk) t_disk.loc = src.loc t_disk = null - screen = 1.0 + menu = 0 + submenu = 0 else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. for(var/datum/tech/T in files.known_tech) if(href_list["copy_tech_ID"] == T.id) t_disk.stored = T break - screen = 1.2 + menu = 2 + submenu = 0 else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk. - screen = 0.0 + wait_message = "Updating Database...." spawn(50) - screen = 1.4 + wait_message = 0 files.AddDesign2Known(d_disk.blueprint) - updateUsrDialog() + nanomanager.update_uis(src) griefProtection() //Update centcom too else if(href_list["clear_design"]) //Erases data on the design disk. @@ -241,7 +267,8 @@ proc/CallMaterialName(ID) if(d_disk) d_disk.loc = src.loc d_disk = null - screen = 1.0 + menu = 0 + submenu = 0 else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk. for(var/datum/design/D in files.known_designs) @@ -259,7 +286,8 @@ proc/CallMaterialName(ID) D.category |= "Imported" d_disk.blueprint = D break - screen = 1.4 + menu = 2 + submenu = 0 else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer. if(linked_destroy) @@ -270,20 +298,20 @@ proc/CallMaterialName(ID) linked_destroy.loaded_item.loc = linked_destroy.loc linked_destroy.loaded_item = null linked_destroy.icon_state = "d_analyzer" - screen = 2.1 + menu = 3 else if(href_list["maxresearch"]) //Eject the item inside the destructive analyzer. if(!check_rights(R_ADMIN)) return - screen = 0.0 + wait_message = "Updating Database...." if(alert("Are you sure you want to maximize research levels?","Confirmation","Yes","No")=="No") return log_admin("[key_name(usr)] has maximized the research levels.") message_admins("[key_name_admin(usr)] has maximized the research levels.") spawn(30) Maximize() - screen = 1.0 - updateUsrDialog() + wait_message = "" + nanomanager.update_uis(src) griefProtection() //Update centcomm too else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. @@ -294,8 +322,8 @@ proc/CallMaterialName(ID) var/choice = input("Proceeding will destroy loaded item.") in list("Proceed", "Cancel") if(choice == "Cancel" || !linked_destroy) return linked_destroy.busy = 1 - screen = 0.1 - updateUsrDialog() + wait_message = "Processing and Updating Database..." + nanomanager.update_uis(src) flick("d_analyzer_process", linked_destroy) spawn(24) if(linked_destroy) @@ -303,7 +331,9 @@ proc/CallMaterialName(ID) if(!linked_destroy.hacked) if(!linked_destroy.loaded_item) to_chat(usr, "The destructive analyzer appears to be empty.") - screen = 1.0 + wait_message = 0 + menu = 0 + submenu = 0 return if((linked_destroy.loaded_item.reliability >= 99 - (linked_destroy.decon_mod * 3)) || linked_destroy.loaded_item.crit_fail) var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) @@ -311,15 +341,21 @@ proc/CallMaterialName(ID) if(prob(linked_destroy.loaded_item.reliability)) //If deconstructed item is not reliable enough its just being wasted, else it is pocessed files.UpdateTech(T, temp_tech[T]) //Check if deconstructed item has research levels higher/same/one less than current ones files.UpdateDesigns(linked_destroy.loaded_item, temp_tech, src) //If if such reseach type found all the known designs are checked for having this research type in them - screen = 1.0 //If design have it it gains some reliability + wait_message = 0 //If design have it it gains some reliability + menu = 0 + submenu = 0 else //Same design always gain quality - screen = 2.3 //Crit fail gives the same design a lot of reliability, like really a lot + wait_message = 0 //Crit fail gives the same design a lot of reliability, like really a lot + menu = 2 + submenu = 0 if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. for(var/material in linked_destroy.loaded_item.materials) linked_lathe.materials.insert_amount(min((linked_lathe.materials.max_amount - linked_lathe.materials.total_amount), (linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10))), material) linked_destroy.loaded_item = null else - screen = 1.0 + wait_message = 0 + menu = 0 + submenu = 0 for(var/obj/I in linked_destroy.contents) for(var/mob/M in I.contents) M.death() @@ -336,10 +372,10 @@ proc/CallMaterialName(ID) qdel(I) linked_destroy.icon_state = "d_analyzer" use_power(250) - updateUsrDialog() + nanomanager.update_uis(src) else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected. - screen = 0.0 + wait_message = "Updating Database...." if(!sync) to_chat(usr, "You must connect to the network first!") else @@ -366,8 +402,8 @@ proc/CallMaterialName(ID) server_processed = 1 if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed) S.produce_heat(100) - screen = 1.6 - updateUsrDialog() + wait_message = 0 + nanomanager.update_uis(src) else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data. sync = !sync @@ -388,12 +424,11 @@ proc/CallMaterialName(ID) if(being_built) var/power = 2000 var/amount=text2num(href_list["amount"]) - var/old_screen = screen amount = max(1, min(10, amount)) for(var/M in being_built.materials) power += round(being_built.materials[M] * amount / 5) power = max(2000, power) - screen = 0.3 + wait_message = "Constructing Prototype. Please Wait..." if(linked_lathe.busy) g2g = 0 var/key = usr.key //so we don't lose the info during the spawn delay @@ -431,6 +466,9 @@ proc/CallMaterialName(ID) var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. var/O = being_built.locked + + coeff *= being_built.lathe_time_factor + spawn(32*amount/coeff) if(g2g) //And if we only fail the material requirements, we still spend time and power for(var/i = 0, iAccess denied.
") return 1 - interact(user) - -/obj/machinery/computer/rdconsole/interact(mob/user) + ui_interact(user) +/obj/machinery/computer/rdconsole/ui_interact(mob/user, ui_key="main", var/datum/nanoui/ui = null, var/force_open = 1) user.set_machine(src) - var/dat = "" + var/data = list() + files.RefreshResearch() - switch(screen) //A quick check to make sure you get the right screen when a device is disconnected. - if(2 to 2.9) - if(screen == 2.3) - ; - else if(linked_destroy == null) - screen = 2.0 - else if(linked_destroy.loaded_item == null) - screen = 2.1 - else - screen = 2.2 - if(3 to 3.9) - if(linked_lathe == null) - screen = 3.0 - if(4 to 4.9) - if(linked_imprinter == null) - screen = 4.0 - - switch(screen) - - //////////////////////R&D CONSOLE SCREENS////////////////// - if(0.0) dat += "
Updating Database....
" - - if(0.1) dat += "
Processing and Updating Database...
" - - if(0.3) - dat += "
Constructing Prototype. Please Wait...
" - - if(0.4) - dat += "
Imprinting Circuit. Please Wait...
" - - if(1.0) //Main Menu - dat += "
" - dat += "

Main Menu:


" - dat += "Current Research Levels
" - if(t_disk) - dat += "Disk Operations
" - else if(d_disk) - dat += "Disk Operations
" - else - dat += "Disk Operations
" - if(linked_destroy) - dat += "Destructive Analyzer Menu
" - else - dat += "Destructive Analyzer Menu
" - if(linked_lathe) - dat += "Protolathe Construction Menu
" - else - dat += "Protolathe Construction Menu
" - if(linked_imprinter) - dat += "Circuit Construction Menu
" - else - dat += "Circuit Construction Menu
" - dat += "Settings" - dat += "
" - - if(1.1) //Research viewer - dat += "Main Menu" - dat += "

Current Research Levels:


" + + data["menu"] = menu + data["submenu"] = submenu + data["wait_message"] = wait_message + data["src_ref"] = "\ref[src]" + + data["linked_destroy"] = linked_destroy ? 1 : 0 + data["linked_lathe"] = linked_lathe ? 1 : 0 + data["linked_imprinter"] = linked_imprinter ? 1 : 0 + data["sync"] = sync + data["admin"] = check_rights(R_ADMIN,0) + data["disk_type"] = d_disk ? 2 : (t_disk ? 1 : 0) + data["category"] = selected_category + + if(menu == 1) + var/list/tech_levels = list() + data["tech_levels"] = tech_levels + for(var/datum/tech/T in files.known_tech) + if(T.level <= 0) + continue + var/list/this_tech_list = list() + this_tech_list["name"] = T.name + this_tech_list["level"] = T.level + this_tech_list["desc"] = T.desc + tech_levels[++tech_levels.len] = this_tech_list + + if(menu == 2) + + if(t_disk != null && t_disk.stored != null && submenu == 0) //Technology Disk Menu + var/list/disk_data = list() + data["disk_data"] = disk_data + disk_data["name"] = t_disk.stored.name + disk_data["level"] = t_disk.stored.level + disk_data["desc"] = t_disk.stored.desc + + if(t_disk != null && submenu == 1) + var/list/to_copy = list() + data["to_copy"] = to_copy for(var/datum/tech/T in files.known_tech) + var/list/item = list() + to_copy[++to_copy.len] = item if(T.level <= 0) continue - dat += "[T.name]
" - dat += "* Level: [T.level]
" - dat += "* Summary: [T.desc]
" - dat += "
" - - if(1.2) //Technology Disk Menu - - dat += "Main Menu
" - dat += "
Technology Data Disk Contents:

" - if(t_disk.stored == null) - dat += "The disk has no data stored on it.
" - dat += "Operations: " - dat += "Load Tech to Disk" - else - dat += "Name: [t_disk.stored.name]
" - dat += "Level: [t_disk.stored.level]
" - dat += "Description: [t_disk.stored.desc]" - dat += "Operations: " - dat += "Upload to Database" - dat += "Clear Disk" - dat += "Eject Disk" - - if(1.3) //Technology Disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
" - dat += "

Load Technology to Disk:


" - for(var/datum/tech/T in files.known_tech) - if(T.level <= 0) - continue - dat += "[T.name] " - dat += "Copy to Disk
" - dat += "
" - - if(1.4) //Design Disk menu. - dat += "Main Menu
" - if(d_disk.blueprint == null) - dat += "The disk has no data stored on it.
" - dat += "Operations: " - dat += "Load Design to Disk" - else - dat += "Name: [d_disk.blueprint.name]
" - dat += "Level: [d_disk.blueprint.reliability]
" - var/b_type = d_disk.blueprint.build_type - if(b_type) - dat += "Lathe Types:
" - if(b_type & IMPRINTER) dat += "Circuit Imprinter
" - if(b_type & PROTOLATHE) dat += "Proto-lathe
" - if(b_type & AUTOLATHE) dat += "Auto-lathe
" - if(b_type & MECHFAB) dat += "Mech Fabricator
" - dat += "Required Materials:
" - for(var/M in d_disk.blueprint.materials) - if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]
" - else dat += "* [M] x [d_disk.blueprint.materials[M]]
" - dat += "Operations: " - dat += "Upload to Database" - dat += "Clear Disk" - dat += "Eject Disk" - - if(1.5) //Technology disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
" - dat += "

Load Design to Disk:


" + item["name"] = T.name + item["id"] = T.id + + if(d_disk != null && d_disk.blueprint != null && submenu == 0) + var/list/disk_data = list() + data["disk_data"] = disk_data + disk_data["name"] = d_disk.blueprint.name + disk_data["reliability"] = d_disk.blueprint.reliability + var/b_type = d_disk.blueprint.build_type + var/list/lathe_types = list() + disk_data["lathe_types"] = lathe_types + if(b_type) + if(b_type & IMPRINTER) lathe_types += "Circuit Imprinter" + if(b_type & PROTOLATHE) lathe_types += "Protolathe" + if(b_type & AUTOLATHE) lathe_types += "Autolathe" + if(b_type & MECHFAB) lathe_types += "Mech Fabricator" + if(b_type & PODFAB) lathe_types += "Spacepod Fabricator" + var/list/materials = list() + disk_data["materials"] = materials + for(var/M in d_disk.blueprint.materials) + var/list/material = list() + materials[++materials.len] = material + material["name"] = CallMaterialName(M) + material["amount"] = d_disk.blueprint.materials[M] + + if(d_disk != null && submenu == 1) + var/list/to_copy = list() + data["to_copy"] = to_copy for(var/datum/design/D in files.known_designs) - dat += "[D.name] " - dat += "Copy to Disk
" - dat += "
" - - if(1.6) //R&D console settings - dat += "Main Menu
" - dat += "

R&D Console Setting:


" - if(sync) - dat += "Sync Database with Network
" - dat += "Connect to Research Network
" - dat += "Disconnect from Research Network
" - else - dat += "Sync Database with Network
" - dat += "Connect to Research Network
" - dat += "Disconnect from Research Network
" - dat += "Device Linkage Menu
" - if(check_rights(R_ADMIN,0)) - dat += "\[ADMIN\] Maximize Research Levels
" - dat += "Reset R&D Database
" - - if(1.7) //R&D device linkage - dat += "Main Menu" - dat += "Settings Menu
" - dat += "

R&D Console Device Linkage Menu:


" - dat += "Re-sync with Nearby Devices

" - dat += "

Linked Devices:


" - if(linked_destroy) - dat += "* Destructive Analyzer Disconnect
" - else - dat += "* No Destructive Analyzer Linked
" - if(linked_lathe) - dat += "* Protolathe Disconnect
" - else - dat += "* No Protolathe Linked
" - if(linked_imprinter) - dat += "* Circuit Imprinter Disconnect
" - else - dat += "* No Circuit Imprinter Linked
" - dat += "
" - - ////////////////////DESTRUCTIVE ANALYZER SCREENS//////////////////////////// - if(2.0) - dat += "Main Menu" - dat += "
NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE
" - - if(2.1) - dat += "Main Menu" - dat += "
No Item Loaded. Standing-by...
" - - if(2.2) - dat += "Main Menu
" - dat += "

Deconstruction Menu


" - dat += "Name: [linked_destroy.loaded_item.name]
" - dat += "Reliability: [linked_destroy.loaded_item.reliability]
" - dat += "Origin Tech:
" - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - for(var/T in temp_tech) - dat += "* [CallTechName(T)] [temp_tech[T]]" - for(var/datum/tech/F in files.known_tech) - if(F.name == CallTechName(T)) - dat += " (Current: [F.level])" - break - dat += "
" - dat += "
Options: " - dat += "Deconstruct Item" - dat += "Eject Item" - if(2.3) - dat += "Main Menu" - dat += "
Item is neither reliable enough or broken enough to learn from.
" - - /////////////////////PROTOLATHE SCREENS///////////////////////// - if(3.0) - dat += "Main Menu
" - dat += "
NO PROTOLATHE LINKED TO CONSOLE
" - - if(3.1) - dat += "Main Menu " - dat += "Material Storage" - dat += "Chemical Storage
" - dat += "

Protolathe Menu:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" - - dat += "
\ - \ - \ - \ - \ - \ -

" - - dat += list_categories(linked_lathe.categories, 3.15) - - //Grouping designs by categories, to improve readability - if(3.15) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" - - for(var/datum/design/D in files.known_designs) - if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) - continue - var/temp_material - var/c = 50 - var/t - for(var/M in D.materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[D.materials[M]] [CallMaterialName(M)]" - else - temp_material += " [D.materials[M]] [CallMaterialName(M)]" - c = min(c,t) - - - for(var/R in D.reagents) - t = linked_lathe.check_mat(D, R) - temp_material += " | " - if (t < 1) - temp_material += "[D.reagents[R]] [CallMaterialName(R)]" - else - temp_material += " [D.reagents[R]] [CallMaterialName(R)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - if(D.locked) - dat += " | LOCKED" - dat += "
" - dat += "
" - - if(3.17) //Display search result - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

Search results:


" - dat += "Material Amount: [linked_lathe.materials.total_amount] / [linked_lathe.materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" + var/list/item = list() + to_copy[++to_copy.len] = item + item["name"] = D.name + item["id"] = D.id + if(menu == 3 && linked_destroy && linked_destroy.loaded_item) + var/list/loaded_item_list = list() + data["loaded_item"] = loaded_item_list + loaded_item_list["name"] = linked_destroy.loaded_item.name + loaded_item_list["reliability"] = linked_destroy.loaded_item.reliability + var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) + var/list/tech_list = list() + loaded_item_list["origin_tech"] = tech_list + for(var/T in temp_tech) + var/list/tech_item = list() + tech_list[++tech_list.len] = tech_item + tech_item["name"] = CallTechName(T) + tech_item["object_level"] = temp_tech[T] + for(var/datum/tech/F in files.known_tech) + if(F.name == CallTechName(T)) + tech_item["current_level"] = F.level + break + + if(menu == 4 && linked_lathe) + data["total_materials"] = linked_lathe.materials.total_amount + data["max_materials"] = linked_lathe.materials.max_amount + data["total_chemicals"] = linked_lathe.reagents.total_volume + data["max_chemicals"] = linked_lathe.reagents.maximum_volume + data["categories"] = linked_lathe.categories + if(submenu == 1) + var/list/designs_list = list() + data["matching_designs"] = designs_list for(var/datum/design/D in matching_designs) - var/temp_material + var/list/design_list = list() + designs_list[++designs_list.len] = design_list + var/list/materials_list = list() + design_list["materials"] = materials_list + design_list["id"] = D.id + design_list["name"] = sanitize(D.name) var/c = 50 - var/t for(var/M in D.materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[D.materials[M]] [CallMaterialName(M)]" + var/list/material_list = list() + materials_list[++materials_list.len] = material_list + material_list["name"] = CallMaterialName(M) + material_list["amount"] = D.materials[M] + var/t = linked_lathe.check_mat(D, M) + + if(t < 1) + material_list["is_red"] = 1 else - temp_material += " [D.materials[M]] [CallMaterialName(M)]" - c = min(c,t) + material_list["is_red"] = 0 + c = min(c, t) for(var/R in D.reagents) - t = linked_lathe.check_mat(D, R) - temp_material += " | " - if (t < 1) - temp_material += "[D.reagents[R]] [CallMaterialName(R)]" + var/list/material_list = list() + materials_list[++materials_list.len] = material_list + material_list["name"] = CallMaterialName(R) + material_list["amount"] = D.reagents[R] + var/t = linked_lathe.check_mat(D, R) + + if(t < 1) + material_list["is_red"] = 1 else - temp_material += " [D.reagents[R]] [CallMaterialName(R)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - dat += "
" - dat += "
" - - if(3.2) //Protolathe Material Storage Sub-menu - dat += "Main Menu" - dat += "Protolathe Menu
" - dat += "

Material Storage:



" - //Metal - var/m_amount = linked_lathe.materials.amount(MAT_METAL) - dat += "* [m_amount] of Metal, [round(m_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(m_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(m_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(m_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Glass - var/g_amount = linked_lathe.materials.amount(MAT_GLASS) - dat += "* [g_amount] of Glass, [round(g_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(g_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(g_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Gold - var/gold_amount = linked_lathe.materials.amount(MAT_GOLD) - dat += "* [gold_amount] of Gold, [round(gold_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Silver - var/silver_amount = linked_lathe.materials.amount(MAT_SILVER) - dat += "* [silver_amount] of Silver, [round(silver_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(silver_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Plasma - var/plasma_amount = linked_lathe.materials.amount(MAT_PLASMA) - dat += "* [plasma_amount] of Solid Plasma, [round(plasma_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(plasma_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Uranium - var/uranium_amount = linked_lathe.materials.amount(MAT_URANIUM) - dat += "* [uranium_amount] of Uranium, [round(uranium_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(uranium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Diamond - var/diamond_amount = linked_lathe.materials.amount(MAT_DIAMOND) - dat += "* [diamond_amount] of Diamond, [round(diamond_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Bananium - var/bananium_amount = linked_lathe.materials.amount(MAT_BANANIUM) - dat += "* [bananium_amount] of Bananium, [round(bananium_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(bananium_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Tranquillite - var/tranquillite_amount = linked_lathe.materials.amount(MAT_TRANQUILLITE) - dat += "* [tranquillite_amount] of Tranquillite, [round(tranquillite_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(tranquillite_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(tranquillite_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(tranquillite_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - - if(3.3) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "Disposal All Chemicals in Storage
" - dat += "

Chemical Storage:



" + material_list["is_red"] = 0 + c = min(c, t) + design_list["can_build"] = c + if(submenu == 2) + var/list/materials_list = list() + data["loaded_materials"] = materials_list + materials_list[++materials_list.len] = list("name" = "Metal", "id" = MAT_METAL, "amount" = linked_lathe.materials.amount(MAT_METAL)) + materials_list[++materials_list.len] = list("name" = "Glass", "id" = MAT_GLASS, "amount" = linked_lathe.materials.amount(MAT_GLASS)) + materials_list[++materials_list.len] = list("name" = "Gold", "id" = MAT_GOLD, "amount" = linked_lathe.materials.amount(MAT_GOLD)) + materials_list[++materials_list.len] = list("name" = "Silver", "id" = MAT_SILVER, "amount" = linked_lathe.materials.amount(MAT_SILVER)) + materials_list[++materials_list.len] = list("name" = "Plasma", "id" = MAT_PLASMA, "amount" = linked_lathe.materials.amount(MAT_PLASMA)) + materials_list[++materials_list.len] = list("name" = "Uranium", "id" = MAT_URANIUM, "amount" = linked_lathe.materials.amount(MAT_URANIUM)) + materials_list[++materials_list.len] = list("name" = "Diamond", "id" = MAT_DIAMOND, "amount" = linked_lathe.materials.amount(MAT_DIAMOND)) + materials_list[++materials_list.len] = list("name" = "Bananium", "id" = MAT_BANANIUM, "amount" = linked_lathe.materials.amount(MAT_BANANIUM)) + materials_list[++materials_list.len] = list("name" = "Tranquillite", "id" = MAT_TRANQUILLITE, "amount" = linked_lathe.materials.amount(MAT_TRANQUILLITE)) + if(submenu == 3) + var/list/loaded_chemicals = list() + data["loaded_chemicals"] = loaded_chemicals for(var/datum/reagent/R in linked_lathe.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - - ///////////////////CIRCUIT IMPRINTER SCREENS//////////////////// - if(4.0) - dat += "Main Menu
" - dat += "
NO CIRCUIT IMPRINTER LINKED TO CONSOLE
" - - if(4.1) - dat += "Main Menu" - dat += "Material Storage" - dat += "Chemical Storage
" - dat += "

Circuit Imprinter Menu:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - - dat += "
\ - \ - \ - \ - \ - \ -

" - - dat += list_categories(linked_imprinter.categories, 4.15) - - if(4.15) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - - var/coeff = linked_imprinter.efficiency_coeff - for(var/datum/design/D in files.known_designs) - if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) - continue - var/temp_materials - var/check_materials = 1 - for(var/M in D.materials) - temp_materials += " | " - if (!linked_imprinter.check_mat(D, M)) - check_materials = 0 - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" - else - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
" - else - dat += "[D.name][temp_materials]
" - if(D.locked) - dat += " | LOCKED" - dat += "
" - - if(4.17) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

Search results:


" - dat += "Material Amount: [linked_imprinter.TotalMaterials()]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - + var/list/loaded_chemical = list() + loaded_chemicals[++loaded_chemicals.len] = loaded_chemical + loaded_chemical["name"] = R.name + loaded_chemical["volume"] = R.volume + loaded_chemical["id"] = R.id + + if(menu == 5 && linked_imprinter) + data["total_materials"] = linked_imprinter.TotalMaterials() + data["total_chemicals"] = linked_imprinter.reagents.total_volume + data["categories"] = linked_imprinter.categories + if(submenu == 1) + var/list/designs_list = list() + data["matching_designs"] = designs_list var/coeff = linked_imprinter.efficiency_coeff for(var/datum/design/D in matching_designs) - var/temp_materials + var/list/design_list = list() + designs_list[++designs_list.len] = design_list + var/list/materials_list = list() + design_list["materials"] = materials_list + design_list["id"] = D.id + design_list["name"] = sanitize(D.name) var/check_materials = 1 for(var/M in D.materials) - temp_materials += " | " + var/list/material_list = list() + materials_list[++materials_list.len] = material_list + material_list["name"] = CallMaterialName(M) + material_list["amount"] = D.materials[M] / coeff if (!linked_imprinter.check_mat(D, M)) check_materials = 0 - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" + material_list["is_red"] = 1 else - temp_materials += " [D.materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
" - else - dat += "[D.name][temp_materials]
" - dat += "
" - - if(4.2) - dat += "Main Menu" - dat += "Imprinter Menu" - dat += "Disposal All Chemicals in Storage
" - dat += "

Chemical Storage:



" + material_list["is_red"] = 0 + design_list["can_build"] = check_materials + if(submenu == 2) + var/list/materials_list = list() + data["loaded_materials"] = materials_list + materials_list[++materials_list.len] = list("name" = "Glass", "id" = MAT_GLASS, "amount" = linked_imprinter.g_amount) + materials_list[++materials_list.len] = list("name" = "Gold", "id" = MAT_GOLD, "amount" = linked_imprinter.gold_amount) + materials_list[++materials_list.len] = list("name" = "Diamond", "id" = MAT_DIAMOND, "amount" = linked_imprinter.diamond_amount) + if(submenu == 3) + var/list/loaded_chemicals = list() + data["loaded_chemicals"] = loaded_chemicals for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - - if(4.3) - dat += "Main Menu" - dat += "Circuit Imprinter Menu
" - dat += "

Material Storage:



" - //Glass - dat += "* [linked_imprinter.g_amount] glass, [round(linked_imprinter.g_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.g_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Gold - dat += "* [linked_imprinter.gold_amount] gold, [round(linked_imprinter.gold_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.gold_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - //Diamond - dat += "* [linked_imprinter.diamond_amount] diamond, [round(linked_imprinter.diamond_amount / MINERAL_MATERIAL_AMOUNT,0.1)] sheets: " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - dat += "C " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT*5) dat += "5x " - if(linked_imprinter.diamond_amount >= MINERAL_MATERIAL_AMOUNT) dat += "All" - dat += "
" - - var/datum/browser/popup = new(user, "rndconsole", name, 700, 550) - popup.set_content(dat) - popup.open() - return + var/list/loaded_chemical = list() + loaded_chemicals[++loaded_chemicals.len] = loaded_chemical + loaded_chemical["name"] = R.name + loaded_chemical["volume"] = R.volume + loaded_chemical["id"] = R.id + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "r_n_d.tmpl", src.name, 800, 550) + ui.set_initial_data(data) + ui.open() //helper proc, which return a table containing categories /obj/machinery/computer/rdconsole/proc/list_categories(var/list/categories, var/menu_num as num) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact.dm b/code/modules/research/xenoarchaeology/artifact/artifact.dm index 3087ad35a72..a29f8ce293a 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact.dm @@ -81,7 +81,7 @@ var/obj/item/device/measuring_tape/P = W user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].") if(do_after(user,40, target = src)) - to_chat(user, "\blue \icon[P] [src] has been excavated to a depth of [2*src.excavation_level]cm.") + to_chat(user, "\blue [bicon(P)] [src] has been excavated to a depth of [2*src.excavation_level]cm.") return if (istype(W, /obj/item/weapon/pickaxe)) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm index 8fb51c6f690..95489be4775 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm @@ -50,17 +50,17 @@ if(!previous_power_state) previous_power_state = 1 icon_state = "cellold1" - src.visible_message("\blue \icon[src] [src] suddenly comes to life!") + src.visible_message("\blue [bicon(src)] [src] suddenly comes to life!") //slowly grow a mob if(prob(5)) - src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].") + src.visible_message("\blue [bicon(src)] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].") //if we've finished growing... if(time_spent_spawning >= time_per_spawn) time_spent_spawning = 0 use_power = 1 - src.visible_message("\blue \icon[src] [src] pings!") + src.visible_message("\blue [bicon(src)] [src] pings!") icon_state = "cellold1" desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow." if(spawn_type) @@ -81,7 +81,7 @@ if(previous_power_state) previous_power_state = 0 icon_state = "cellold0" - src.visible_message("\blue \icon[src] [src] suddenly shuts down.") + src.visible_message("\blue [bicon(src)] [src] suddenly shuts down.") //cloned mob slowly breaks down time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm index b32bc190aee..b8c868237e3 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm @@ -78,7 +78,7 @@ viables.Remove(type) construction[button_desc] = type - fail_message = "\blue \icon[src] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \ + fail_message = "\blue [bicon(src)] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \ [pick("horn","beep","bing","bleep","blat","honk","hrumph","ding")] sounds and a \ [pick("yellow","purple","green","blue","red","orange","white")] \ [pick("light","dial","meter","window","protrusion","knob","antenna","swirly thing")] \ @@ -90,7 +90,7 @@ if(spawning_types.len && powered()) spawn_progress_time += world.time - last_process_time if(spawn_progress_time > max_spawn_time) - src.visible_message("\blue \icon[src] [src] pings!") + src.visible_message("\blue [bicon(src)] [src] pings!") var/obj/source_material = pop(stored_materials) var/spawn_type = pop(spawning_types) @@ -113,7 +113,7 @@ icon_state = "borgcharger0(old)" else if(prob(5)) - src.visible_message("\blue \icon[src] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") + src.visible_message("\blue [bicon(src)] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].") last_process_time = world.time @@ -141,9 +141,9 @@ if(index > 0 && index <= construction.len) if(stored_materials.len > spawning_types.len) if(spawning_types.len) - src.visible_message("\blue \icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") + src.visible_message("\blue [bicon(src)] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].") else - src.visible_message("\blue \icon[src] [src]'s front compartment slides shut.") + src.visible_message("\blue [bicon(src)] [src]'s front compartment slides shut.") spawning_types.Add(construction[construction[index]]) spawn_progress_time = 0 diff --git a/code/modules/research/xenoarchaeology/artifact/effect.dm b/code/modules/research/xenoarchaeology/artifact/effect.dm index 0518e677419..727c016849b 100644 --- a/code/modules/research/xenoarchaeology/artifact/effect.dm +++ b/code/modules/research/xenoarchaeology/artifact/effect.dm @@ -64,7 +64,7 @@ var/atom/toplevelholder = holder while(!istype(toplevelholder.loc, /turf)) toplevelholder = toplevelholder.loc - toplevelholder.visible_message("\red \icon[toplevelholder] [toplevelholder] [display_msg]") + toplevelholder.visible_message("\red [bicon(toplevelholder)] [toplevelholder] [display_msg]") /datum/artifact_effect/proc/DoEffectTouch(var/mob/user) /datum/artifact_effect/proc/DoEffectAura(var/atom/holder) diff --git a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm index 206280770e9..be176c114f4 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm @@ -80,7 +80,7 @@ ..() else if(istype(W,/obj/item/weapon/pen)) plaque_contents = input("What would you like to write on the plaque:","Skeleton plaque","") - user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src] [src].") + user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of [bicon(src)] [src].") if(src.contents.Find(/obj/item/weapon/fossil/skull/horned)) src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'." else diff --git a/code/modules/research/xenoarchaeology/finds/finds_special.dm b/code/modules/research/xenoarchaeology/finds/finds_special.dm index dc315b80640..ce6fb4c2663 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_special.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_special.dm @@ -99,7 +99,7 @@ if(charges >= 0.1) if(prob(5)) - src.visible_message("\red \icon[src] [src]'s eyes glow ruby red for a moment!") + src.visible_message("\red [bicon(src)] [src]'s eyes glow ruby red for a moment!") charges -= 0.1 //check on our shadow wights diff --git a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm index 9cea4d29494..637b1596294 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm @@ -57,7 +57,7 @@ var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\ "[holder_atom] seems to be focussing on [source]...",\ "[holder_atom] seems to turn it's attention to [source]...") - holder_atom.loc.visible_message("\blue \icon[holder_atom] [pick(options)]") + holder_atom.loc.visible_message("\blue [bicon(holder_atom)] [pick(options)]") if(prob(20)) spawn(2) @@ -121,5 +121,5 @@ listening|=M for(var/mob/M in listening) - to_chat(M, "\icon[holder_atom] [holder_atom] reverberates, \blue\"[msg]\"") + to_chat(M, "[bicon(holder_atom)] [holder_atom] reverberates, \blue\"[msg]\"") last_talk_time = world.time diff --git a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm index 1e491f1ac48..cb2130c76fc 100644 --- a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm +++ b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm @@ -54,11 +54,11 @@ datum/genesequence W.loc = src.loc switch(scan_fossil(W)) if(1) - src.visible_message("\red \icon[src] [src] scans the fossil and rejects it.") + src.visible_message("\red [bicon(src)] [src] scans the fossil and rejects it.") if(2) - visible_message("\red \icon[src] [src] can not extract any more genetic data from new fossils.") + visible_message("\red [bicon(src)] [src] can not extract any more genetic data from new fossils.") if(4) - src.visible_message("\blue \icon[src] [user] inserts [W] into [src], the fossil is consumed as [src] extracts genetic data from it.") + src.visible_message("\blue [bicon(src)] [user] inserts [W] into [src], the fossil is consumed as [src] extracts genetic data from it.") qdel(W) updateDialog() else if (istype(W, /obj/item/weapon/storage)) @@ -182,13 +182,13 @@ datum/genesequence var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num] if(pod1) if(pod1.occupant) - visible_message("\red \icon[src] The cloning pod is currently occupied.") + visible_message("\red [bicon(src)] The cloning pod is currently occupied.") else if(pod1.biomass < CLONE_BIOMASS) - visible_message("\red \icon[src] Not enough biomass in the cloning pod.") + visible_message("\red [bicon(src)] Not enough biomass in the cloning pod.") else if(pod1.mess) - visible_message("\red \icon[src] Error: clonepod malfunction.") + visible_message("\red [bicon(src)] Error: clonepod malfunction.") else - visible_message("\blue \icon[src] [src] clones something from a reconstituted gene sequence!") + visible_message("\blue [bicon(src)] [src] clones something from a reconstituted gene sequence!") playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3) pod1.occupant = new cloned_genesequence.spawned_type(pod1) pod1.locked = 1 @@ -196,7 +196,7 @@ datum/genesequence //pod1.occupant.name = "[pod1.occupant.name] ([rand(0,999)])" pod1.biomass -= CLONE_BIOMASS else - to_chat(usr, "\red \icon[src] Unable to locate cloning pod!") + to_chat(usr, "\red [bicon(src)] Unable to locate cloning pod!") else ..() @@ -240,7 +240,7 @@ datum/genesequence else if(href_list["clone"]) var/sequence_num = text2num(href_list["sequence_num"]) var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num] - visible_message("\blue \icon[src] [src] clones a packet of seeds from a reconstituted gene sequence!") + visible_message("\blue [bicon(src)] [src] clones a packet of seeds from a reconstituted gene sequence!") playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3) new cloned_genesequence.spawned_type(src.loc) diff --git a/code/modules/research/xenoarchaeology/machinery/artifact_analyser.dm b/code/modules/research/xenoarchaeology/machinery/artifact_analyser.dm index 77b6f688458..0e7c3736ca2 100644 --- a/code/modules/research/xenoarchaeology/machinery/artifact_analyser.dm +++ b/code/modules/research/xenoarchaeology/machinery/artifact_analyser.dm @@ -78,7 +78,7 @@ P.name = "[src] report #[++report_num]" P.info = "[src] analysis report #[report_num]
" P.info += "
" - P.info += "\icon[scanned_object] [results]" + P.info += "[bicon(scanned_object)] [results]" P.stamped = list(/obj/item/weapon/stamp) P.overlays = list("paper_stamped") diff --git a/code/modules/research/xenoarchaeology/machinery/coolant.dm b/code/modules/research/xenoarchaeology/machinery/coolant.dm index f6d844fb889..b2dd9ce2a9e 100644 --- a/code/modules/research/xenoarchaeology/machinery/coolant.dm +++ b/code/modules/research/xenoarchaeology/machinery/coolant.dm @@ -27,7 +27,7 @@ datum/chemical_reaction/coolant /obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj) if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) - if(!istype(Proj ,/obj/item/projectile/lasertag) && !istype(Proj ,/obj/item/projectile/practice) ) + if(!Proj.damage) explode() /obj/structure/reagent_dispensers/coolanttank/blob_act() diff --git a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm index 22d644b5aa5..75cc24e362a 100644 --- a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm +++ b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm @@ -228,16 +228,16 @@ //emergency stop if seal integrity reaches 0 if(scanner_seal_integrity <= 0 || (scanner_temperature >= 1273 && !rad_shield)) stop_scanning() - src.visible_message("\blue \icon[src] buzzes unhappily. It has failed mid-scan!", 2) + src.visible_message("\blue [bicon(src)] buzzes unhappily. It has failed mid-scan!", 2) if(prob(5)) - src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].", 2) + src.visible_message("\blue [bicon(src)] [pick("whirrs","chuffs","clicks")][pick(" excitedly"," energetically"," busily")].", 2) else //gradually cool down over time if(scanner_temperature > 0) scanner_temperature = max(scanner_temperature - 5 - 10 * rand(), 0) if(prob(0.75)) - src.visible_message("\blue \icon[src] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].", 2) + src.visible_message("\blue [bicon(src)] [pick("plinks","hisses")][pick(" quietly"," softly"," sadly"," plaintively")].", 2) last_process_worldtime = world.time /obj/machinery/radiocarbon_spectrometer/proc/stop_scanning() @@ -255,7 +255,7 @@ used_coolant = 0 /obj/machinery/radiocarbon_spectrometer/proc/complete_scan() - src.visible_message("\blue \icon[src] makes an insistent chime.", 2) + src.visible_message("\blue [bicon(src)] makes an insistent chime.", 2) if(scanned_item) //create report diff --git a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm index 9d6cf4fa460..a330e79c8bd 100644 --- a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm +++ b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm @@ -103,9 +103,9 @@ if(interval > 0) //apply the touch effect to the holder if(holder) - to_chat(holder, "the \icon[src] [src] held by [holder] shudders in your grasp.") + to_chat(holder, "the [bicon(src)] [src] held by [holder] shudders in your grasp.") else - src.loc.visible_message("the \icon[src] [src] shudders.") + src.loc.visible_message("the [bicon(src)] [src] shudders.") inserted_battery.battery_effect.DoEffectTouch(holder) //consume power @@ -131,13 +131,13 @@ //work out if we need to shutdown if(inserted_battery.stored_charge <= 0) - src.loc.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.") + src.loc.visible_message("\blue [bicon(src)] [src] buzzes.", "\blue [bicon(src)] You hear something buzz.") shutdown_emission() else if(world.time > time_end) - src.loc.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.") + src.loc.visible_message("\blue [bicon(src)] [src] chimes.", "\blue [bicon(src)] You hear something chime.") shutdown_emission() else - src.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.") + src.visible_message("\blue [bicon(src)] [src] buzzes.", "\blue [bicon(src)] You hear something buzz.") shutdown_emission() last_process = world.time @@ -164,7 +164,7 @@ if(href_list["startup"]) if(inserted_battery && inserted_battery.battery_effect && (inserted_battery.stored_charge > 0) ) activated = 1 - src.visible_message("\blue \icon[src] [src] whirrs.", "\icon[src]\blue You hear something whirr.") + src.visible_message("\blue [bicon(src)] [src] whirrs.", "[bicon(src)]\blue You hear something whirr.") if(!inserted_battery.battery_effect.activated) inserted_battery.battery_effect.ToggleActivate(1) time_end = world.time + duration diff --git a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm index c05eb88c8bb..3e7b4a05c12 100644 --- a/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm +++ b/code/modules/research/xenoarchaeology/tools/bunsen_burner.dm @@ -37,7 +37,7 @@ to_chat(user, "\red There is nothing on the [src].") /obj/machinery/bunsen_burner/proc/try_heating() - src.visible_message("\blue \icon[src] [src] hisses.") + src.visible_message("\blue [bicon(src)] [src] hisses.") if(held_container && heating) heated = 1 held_container.reagents.handle_reactions() diff --git a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm index 0a26c42a821..ec0a7462963 100644 --- a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm +++ b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm @@ -248,7 +248,7 @@ success = 1 for(var/mob/living/carbon/C in T) C.AdjustWeakened(5) - C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + C.visible_message("\blue [bicon(C)] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") if("nitrogen") success = 1 // @@ -271,19 +271,19 @@ success = 1 for(var/mob/living/silicon/R in T) R.AdjustWeakened(5) - R.visible_message("\blue \icon[R] [R] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + R.visible_message("\blue [bicon(R)] [R] begins to float in the air!","You feel tingly and light, but it is difficult to move.") // //in case we have a bad field type if(!success) return for(var/mob/living/simple_animal/C in T) - C.visible_message("\blue \icon[C] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") + C.visible_message("\blue [bicon(C)] [C] begins to float in the air!","You feel tingly and light, but it is difficult to move.") C.AdjustWeakened(5) suspension_field = new(T) suspension_field.field_type = field_type - src.visible_message("\blue \icon[src] [src] activates with a low hum.") + src.visible_message("\blue [bicon(src)] [src] activates with a low hum.") icon_state = "suspension3" for(var/obj/item/I in T) @@ -293,7 +293,7 @@ if(collected) suspension_field.icon_state = "energynet" suspension_field.overlays += "shield2" - src.visible_message("\blue \icon[suspension_field] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].") + src.visible_message("\blue [bicon(suspension_field)] [suspension_field] gently absconds [collected > 1 ? "something" : "several things"].") else if(istype(T,/turf/simulated/mineral) || istype(T,/turf/simulated/wall)) suspension_field.icon_state = "shieldsparkles" @@ -308,7 +308,7 @@ to_chat(M, "You no longer feel like floating.") M.SetWeakened(min(M.weakened, 3)) - src.visible_message("\blue \icon[src] [src] deactivates with a gentle shudder.") + src.visible_message("\blue [bicon(src)] [src] deactivates with a gentle shudder.") qdel(suspension_field) icon_state = "suspension2" diff --git a/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm b/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm index 6bf829ba220..03165b75655 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_depthscanner.dm @@ -46,7 +46,7 @@ positive_locations.Add(D) for(var/mob/L in range(src, 1)) - to_chat(L, "\blue \icon[src] [src] pings.") + to_chat(L, "\blue [bicon(src)] [src] pings.") else if(istype(A,/obj/structure/boulder)) var/obj/structure/boulder/B = A @@ -65,7 +65,7 @@ positive_locations.Add(D) for(var/mob/L in range(src, 1)) - to_chat(L, "\blue \icon[src] [src] pings [pick("madly","wildly","excitedly","crazily")]!.") + to_chat(L, "\blue [bicon(src)] [src] pings [pick("madly","wildly","excitedly","crazily")]!.") /obj/item/device/depth_scanner/attack_self(var/mob/user as mob) return src.interact(user) diff --git a/code/modules/research/xenoarchaeology/tools/tools_locater.dm b/code/modules/research/xenoarchaeology/tools/tools_locater.dm index 751476a6579..a4435dded28 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_locater.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_locater.dm @@ -52,9 +52,9 @@ scan_ticks = 0 var/turf/T = get_turf(src) if(target_radio) - T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] happily.") + T.visible_message("[bicon(src)] [src] [pick("chirps","chirrups","cheeps")] happily.") else - T.visible_message("\icon[src] [src] [pick("chirps","chirrups","cheeps")] sadly.") + T.visible_message("[bicon(src)] [src] [pick("chirps","chirrups","cheeps")] sadly.") else icon_state = "pinoff" diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index f34b727c354..de551e94b75 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -202,7 +202,8 @@ to_chat(user, "You offer [src] sentience potion to [SM]...") being_used = 1 - var/list/candidates = pollCandidates("Do you want to play as [SM.name]?", ROLE_SENTIENT, 0, 100) + var/ghostmsg = "Play as [SM.name], pet of [user.name]?" + var/list/candidates = pollCandidates(ghostmsg, ROLE_SENTIENT, 0, 100) if(!src) return diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index 273ccb67d0e..722c21e3ef3 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -60,7 +60,7 @@ return interpreter.container = src - + interpreter.CreateGlobalScope() // Reset the variables. interpreter.curScope = interpreter.globalScope @@ -242,7 +242,14 @@ /* Okay, so, the original 'sanitizing' code... did fucking nothing. Then PJB fixed it, which means no HTML. But I like HTML, so back to no sanitizing.*/ - signal.data["message"] = interpreter.GetVar("$content", signal.data["message"]) + var/message = interpreter.GetVar("$content") + var/regex/bannedTags = new ("( trade_dockrequest_timelimit && world.time > trade_dock_timelimit) + ..(user) + +/obj/machinery/computer/shuttle/trade/Topic(href, href_list) + ..() + if(href_list["request"]) + if(world.time < trade_dockrequest_timelimit || world.time < trade_dock_timelimit) + return + to_chat(usr, "Request sent.") + command_announcement.Announce(docking_request_message, "Docking Request") + trade_dockrequest_timelimit = world.time + 1200 // They have 2 minutes to approve the request. + +/obj/machinery/computer/shuttle/trade/sol + req_access = list(access_trade_sol) + possible_destinations_dock = "trade_sol_base;trade_sol_offstation;trade_dock" + possible_destinations_nodock = "trade_sol_base;trade_sol_offstation" + shuttleId = "trade_sol" + docking_request_message = "A trading ship of Sol origin has requested docking aboard the NSS Cyberiad for trading. This request can be accepted or denied using a communications console." + #undef DOCKING_PORT_HIGHLIGHT diff --git a/code/modules/spacepods/equipment.dm b/code/modules/spacepods/equipment.dm index 24c4fa5110b..07c49752d15 100644 --- a/code/modules/spacepods/equipment.dm +++ b/code/modules/spacepods/equipment.dm @@ -30,11 +30,9 @@ var/obj/item/projectile/projone = new proj_type(firstloc) var/obj/item/projectile/projtwo = new proj_type(secondloc) projone.starting = get_turf(my_atom) - projone.shot_from = src projone.firer = usr projone.def_zone = "chest" projtwo.starting = get_turf(my_atom) - projtwo.shot_from = src projtwo.firer = usr projtwo.def_zone = "chest" spawn() @@ -46,7 +44,7 @@ /datum/spacepod/equipment var/obj/spacepod/my_atom - var/list/obj/item/device/spacepod_equipment/installed_modules // holds an easy to access list of installed modules + var/list/obj/item/device/spacepod_equipment/installed_modules = list() // holds an easy to access list of installed modules var/obj/item/device/spacepod_equipment/weaponry/weapon_system // weapons system var/obj/item/device/spacepod_equipment/misc/misc_system // misc system diff --git a/code/modules/spacepods/pod_fabricator.dm b/code/modules/spacepods/pod_fabricator.dm index ed7f421f33e..666a793c496 100644 --- a/code/modules/spacepods/pod_fabricator.dm +++ b/code/modules/spacepods/pod_fabricator.dm @@ -166,7 +166,7 @@ I.loc = exit I.materials[MAT_METAL] = get_resource_cost_w_coeff(D,MAT_METAL) I.materials[MAT_GLASS] = get_resource_cost_w_coeff(D,MAT_GLASS) - visible_message("\icon[src] \The [src] beeps, \"\The [I] is complete.\"") + visible_message("[bicon(src)] \The [src] beeps, \"\The [I] is complete.\"") being_built = null updateUsrDialog() @@ -209,14 +209,14 @@ if(stat&(NOPOWER|BROKEN)) return 0 if(!check_resources(D)) - visible_message("\icon[src] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Not enough resources. Queue processing stopped.\"") temp = {"Not enough resources to build next part.
Try again | Return"} return 0 remove_from_queue(1) build_part(D) D = listgetindex(queue, 1) - visible_message("\icon[src] \The [src] beeps, \"Queue processing finished successfully.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Queue processing finished successfully.\"") /obj/machinery/spod_part_fabricator/proc/list_queue() var/output = "Queue contains:" @@ -277,7 +277,7 @@ temp += "Return" updateUsrDialog() - visible_message("\icon[src] \The [src] beeps, \"Successfully synchronized with R&D server.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Successfully synchronized with R&D server.\"") return temp = "Unable to connect to local R&D Database.
Please check your connections and try again.
Return" @@ -301,7 +301,7 @@ return user.set_machine(src) if(exit.density) - visible_message("\icon[src] \The [src] beeps, \"Error! Part outlet is obstructed.\"") + visible_message("[bicon(src)] \The [src] beeps, \"Error! Part outlet is obstructed.\"") return if(temp) left_part = temp diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 4d6393b3348..2156977d6fe 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -73,6 +73,7 @@ pr_int_temp_processor = new /datum/global_iterator/pod_preserve_temp(list(src)) pr_give_air = new /datum/global_iterator/pod_tank_give_air(list(src)) equipment_system = new(src) + equipment_system.installed_modules += battery spacepods_list += src cargo_hold = new/obj/item/weapon/storage/internal(src) cargo_hold.w_class = 5 //so you can put bags in @@ -491,21 +492,25 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/device/spacepod_equipment T.loc = equipment_system equipment_system.weapon_system = T equipment_system.weapon_system.my_atom = src + equipment_system.installed_modules += T var/obj/item/device/spacepod_equipment/misc/tracker/L = new /obj/item/device/spacepod_equipment/misc/tracker L.loc = equipment_system equipment_system.misc_system = L equipment_system.misc_system.my_atom = src equipment_system.misc_system.enabled = 1 + equipment_system.installed_modules += L var/obj/item/device/spacepod_equipment/sec_cargo/chair/C = new /obj/item/device/spacepod_equipment/sec_cargo/chair C.loc = equipment_system equipment_system.sec_cargo_system = C equipment_system.sec_cargo_system.my_atom = src + equipment_system.installed_modules += C max_passengers = 1 var/obj/item/device/spacepod_equipment/lock/keyed/K = new /obj/item/device/spacepod_equipment/lock/keyed K.loc = equipment_system equipment_system.lock_system = K equipment_system.lock_system.my_atom = src equipment_system.lock_system.id = 100000 + equipment_system.installed_modules += K /obj/spacepod/random/New() ..() diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index a5af2caca3d..b753bcf71a5 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -144,6 +144,13 @@ spawn(90 / severity) crit_fail = 0 +/obj/item/organ/internal/cyberimp/brain/clown_voice + name = "Comical implant" + desc = "Uh oh." + implant_color = "#DEDE00" + slot = "brain_clownvoice" + origin_tech = "materials=2;biotech=2" + //[[[[CHEST]]]] /obj/item/organ/internal/cyberimp/chest name = "cybernetic torso implant" @@ -315,7 +322,7 @@ organ_action_name = "Toggle Arm Cannon Taser" /obj/item/organ/internal/cyberimp/chest/arm_mod/tase/New()//when the implant is created... - holder = new /obj/item/weapon/gun/energy/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun) + holder = new /obj/item/weapon/gun/energy/gun/advtaser/mounted(src)//assign a brand new item to it. (in this case, a gun) /obj/item/organ/internal/cyberimp/chest/arm_mod/lase//mounted, self-charging laser! name = "Arm-cannon laser implant" @@ -351,4 +358,4 @@ var/implant while(contents.len <= amount + 1) // +1 for the autoimplanter. implant = pick(boxed) - new implant(src) \ No newline at end of file + new implant(src) diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index d0245c224d9..c5d19ac2509 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -29,7 +29,7 @@ var/disfigured = 0 var/cannot_amputate var/cannot_break - var/s_tone + var/s_tone = null var/list/s_col = null // If this is instantiated, it should be a list of length 3 var/list/wounds = list() var/list/child_icons = list() diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index 0488d768adf..bd57c059d41 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -14,32 +14,33 @@ var/global/list/limb_icon_cache = list() overlays += organ.mob_icon child_icons += organ.mob_icon -/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) +/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/H) if(status & ORGAN_ROBOT && !(species && species.name == "Machine")) //machine people get skin color return - if(species && human.species && species.name != human.species.name) + if(species && H.species && species.name != H.species.name) return - if(dna.unique_enzymes != human.dna.unique_enzymes) // This isn't MY arm - sync_colour_to_dna() - return - if(!isnull(human.s_tone) && (human.species.bodyflags & HAS_SKIN_TONE)) + if(dna.unique_enzymes != H.dna.unique_enzymes) // This isn't MY arm + if(!(H.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))) s_col = null - s_tone = human.s_tone - if(human.species.bodyflags & HAS_SKIN_COLOR) + s_tone = H.s_tone + if(H.species.bodyflags & HAS_SKIN_COLOR) s_tone = null - s_col = list(human.r_skin, human.g_skin, human.b_skin) + s_col = list(H.r_skin, H.g_skin, H.b_skin) /obj/item/organ/external/proc/sync_colour_to_dna() if(status & ORGAN_ROBOT) return - if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && (species.flags & HAS_SKIN_TONE)) + if(!isnull(dna.GetUIValue(DNA_UI_SKIN_TONE)) && ((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE))) s_col = null s_tone = dna.GetUIValue(DNA_UI_SKIN_TONE) if(species.flags & HAS_SKIN_COLOR) s_tone = null s_col = list(dna.GetUIValue(DNA_UI_SKIN_R), dna.GetUIValue(DNA_UI_SKIN_G), dna.GetUIValue(DNA_UI_SKIN_B)) -/obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/human) +/obj/item/organ/external/head/sync_colour_to_human(var/mob/living/carbon/human/H) ..() var/obj/item/organ/internal/eyes/eyes = owner.get_int_organ(/obj/item/organ/internal/eyes)//owner.internal_organs_by_name["eyes"] if(eyes) eyes.update_colour() diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 57e2934dbb4..f4a47c595cb 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -81,7 +81,7 @@ return ..() /obj/item/organ/internal/proc/prepare_eat() - if(robotic) + if(status == ORGAN_ROBOT) return //no eating cybernetic implants! var/obj/item/weapon/reagent_containers/food/snacks/organ/S = new S.name = name diff --git a/code/modules/surgery/organs/robolimbs.dm b/code/modules/surgery/organs/robolimbs.dm index 0229ee80cae..c3d7f1c3828 100644 --- a/code/modules/surgery/organs/robolimbs.dm +++ b/code/modules/surgery/organs/robolimbs.dm @@ -1,5 +1,4 @@ var/global/list/all_robolimbs = list() -var/global/list/robolimb_data = list() var/global/list/chargen_robolimbs = list() var/global/datum/robolimb/basic_robolimb @@ -20,7 +19,7 @@ var/global/datum/robolimb/basic_robolimb var/unavailable_at_chargen // If set, not available at chargen. var/is_monitor // If set, limb is a monitor and should be getting monitor styles. var/has_subtypes = 2 // If null, object is a model. If 1, object is a brand (that serves as the default model) with child models. If 2, object is a brand that has no child models and thus also serves as the model.. - var/parts = list("chest", "groin", "head", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "l_arm", "l_hand") //Defines what parts said brand can replace on a body. + var/parts = list("chest", "groin", "head", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "l_arm", "l_hand") // Defines what parts said brand can replace on a body. /datum/robolimb/bishop company = "Bishop Cybernetics" diff --git a/code/modules/surgery/organs/subtypes/diona.dm b/code/modules/surgery/organs/subtypes/diona.dm index 5d2bf63035b..9cf0a1020cc 100644 --- a/code/modules/surgery/organs/subtypes/diona.dm +++ b/code/modules/surgery/organs/subtypes/diona.dm @@ -169,6 +169,7 @@ icon = 'icons/mob/alien.dmi' icon_state = "claw" slot = "liver" + alcohol_intensity = 0.5 //TODO:Make absorb light on insert. diff --git a/code/modules/surgery/organs/subtypes/drask.dm b/code/modules/surgery/organs/subtypes/drask.dm index 3e9b37cebe8..e76f557088e 100644 --- a/code/modules/surgery/organs/subtypes/drask.dm +++ b/code/modules/surgery/organs/subtypes/drask.dm @@ -31,6 +31,7 @@ organ_tag = "kidneys" parent_organ = "groin" slot = "kidneys" + alcohol_intensity = 0.8 /obj/item/organ/internal/brain/drask name = "brain" @@ -49,4 +50,4 @@ organ_tag = "eyes" parent_organ = "head" slot = "eyes" - desc = "Drask eyes. They look even stranger disembodied" \ No newline at end of file + desc = "Drask eyes. They look even stranger disembodied" diff --git a/code/modules/surgery/organs/subtypes/grey.dm b/code/modules/surgery/organs/subtypes/grey.dm new file mode 100644 index 00000000000..45798486d4f --- /dev/null +++ b/code/modules/surgery/organs/subtypes/grey.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/grey + alcohol_intensity = 1.6 diff --git a/code/modules/surgery/organs/subtypes/kidan.dm b/code/modules/surgery/organs/subtypes/kidan.dm new file mode 100644 index 00000000000..2866e3904fb --- /dev/null +++ b/code/modules/surgery/organs/subtypes/kidan.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/kidan + alcohol_intensity = 0.5 diff --git a/code/modules/surgery/organs/subtypes/skrell.dm b/code/modules/surgery/organs/subtypes/skrell.dm index faf58b7a3ef..78c43c3a370 100644 --- a/code/modules/surgery/organs/subtypes/skrell.dm +++ b/code/modules/surgery/organs/subtypes/skrell.dm @@ -1,2 +1,2 @@ /obj/item/organ/internal/liver/skrell - alcohol_intensity = 5 \ No newline at end of file + alcohol_intensity = 4 diff --git a/code/modules/surgery/organs/subtypes/tajaran.dm b/code/modules/surgery/organs/subtypes/tajaran.dm new file mode 100644 index 00000000000..462c94be822 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/tajaran.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/tajaran + alcohol_intensity = 1.4 diff --git a/code/modules/surgery/organs/subtypes/unathi.dm b/code/modules/surgery/organs/subtypes/unathi.dm new file mode 100644 index 00000000000..5f204ab1750 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/unathi.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/unathi + alcohol_intensity = 0.8 diff --git a/code/modules/surgery/organs/subtypes/vox.dm b/code/modules/surgery/organs/subtypes/vox.dm new file mode 100644 index 00000000000..c5e86640364 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/vox.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/vox + alcohol_intensity = 1.6 diff --git a/code/modules/surgery/organs/subtypes/vulpkanin.dm b/code/modules/surgery/organs/subtypes/vulpkanin.dm new file mode 100644 index 00000000000..30b8d51f667 --- /dev/null +++ b/code/modules/surgery/organs/subtypes/vulpkanin.dm @@ -0,0 +1,2 @@ +/obj/item/organ/internal/liver/vulpkanin + alcohol_intensity = 1.4 diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index f8051575b05..8e3ff02b091 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -264,6 +264,9 @@ playsound(S, 'sound/effects/bang.ogg', 50, 1) return 0 user.visible_message("[user] shines light onto the tumor in [target]'s head!", "You cleanse the contamination from [target]'s brain!") + if(target.vision_type) //Turns off their darksight if it's still active. + to_chat(target, "Your eyes are suddenly wrought with immense pain as your darksight is forcibly dismissed!") + target.vision_type = null ticker.mode.remove_thrall(target.mind, 0) target.visible_message("A strange black mass falls from [target]'s head!") new /obj/item/organ/internal/shadowtumor(get_turf(target)) diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index 2640b61bd33..b542f968516 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -24,7 +24,7 @@ // Based on the power used var/teleport_cooldown = 0 // every index requires a bluespace crystal - var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80, 100) + var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80) var/teleporting = 0 var/starting_crystals = 0 var/max_crystals = 4 @@ -396,4 +396,4 @@ teles_left = rand(30, 40) //angle_off = rand(-25, 25) power_off = rand(-4, 0) - rotation_off = rand(-10, 10) \ No newline at end of file + rotation_off = rand(-10, 10) diff --git a/dm.sh b/dm.sh index 3d04531b3f4..9585e2f1ce3 100644 --- a/dm.sh +++ b/dm.sh @@ -70,7 +70,7 @@ then "$dm" $dmepath.mdme 2>&1 | tee result.log retval=$? - if ! grep '0 errors, 0 warnings' result.log + if ! grep '\- 0 errors, 0 warnings' result.log then retval=1 #hard fail, due to warnings or errors fi @@ -79,7 +79,7 @@ else then DreamMaker $dmepath.mdme 2>&1 | tee result.log retval=$? - if ! grep '0 errors, 0 warnings' result.log + if ! grep '\- 0 errors, 0 warnings' result.log then retval=1 #hard fail, due to warnings or errors fi @@ -94,4 +94,4 @@ mv $dmepath.mdme.rsc $dmepath.rsc rm $dmepath.mdme -exit $retval \ No newline at end of file +exit $retval diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css new file mode 100644 index 00000000000..51530c0ba1f --- /dev/null +++ b/goon/browserassets/css/browserOutput.css @@ -0,0 +1,364 @@ +/***************************************** +* +* GLOBAL STYLES +* +******************************************/ +html, body { + padding: 0; + margin: 0; + height: 100%; + color: #000000; +} +body { + background: #fff; + font-family: Verdana, "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 9pt; + line-height: 1.2; + overflow-x: hidden; + overflow-y: scroll; + word-wrap: break-word; +} +h1, h2, h3, h4, h5, h6 {color: #00f; font-family: Georgia, Verdana, sans-serif;} +img { + margin: 0; + padding: 0; + line-height: 1; +} +img.icon { + width: 16px; + height: 16px; +} +a {color: #0000ff;} +a:visited {color: #ff00ff;} +a.popt {text-decoration: none;} + + +/***************************************** +* +* OUTPUT NOT RELATED TO ACTUAL MESSAGES +* +******************************************/ +#loading { + position: fixed; + width: 300px; + height: 150px; + text-align: center; + left: 50%; + top: 50%; + margin: -75px 0 0 -150px; +} +#loading i {display: block; padding-bottom: 3px;} + +#messages { + font-size: 14px; + padding: 3px; + margin: 0; + word-wrap: break-word; +} +#newMessages { + position: fixed; + display: block; + bottom: 0; + right: 0; + padding: 8px; + background: #ddd; + text-decoration: none; + font-variant: small-caps; + font-size: 1.1em; + font-weight: bold; + color: #333; +} +#newMessages:hover {background: #ccc;} +#newMessages i {vertical-align: middle; padding-left: 3px;} +#ping { + position: fixed; + top: 0; + right: 40px; + width: 45px; + background: #ddd; + height: 30px; + padding: 8px 0 2px 0; +} +#ping i {display: block; text-align: center;} +#ping .ms { + display: block; + text-align: center; + font-size: 8pt; + padding-top: 2px; +} +#options { + position: fixed; + top: 0; + right: 0; +} +#options a { + background: #ddd; + height: 30px; + padding: 5px 0; + display: block; + color: #333; + text-decoration: none; + line-height: 28px; + border-top: 1px solid #b4b4b4; +} +#options a:hover {background: #ccc;} +#options .toggle { + width: 40px; + background: #ccc; + border-top: 0; + float: right; + text-align: center; +} +#options .sub {clear: both; display: none; width: 160px;} +#options .sub.scroll {overflow-y: scroll;} +#options .sub a {padding: 5px 0 5px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#options .sub span { + display: block; + line-height: 30px; + float: left; +} +#options .sub i { + display: block; + padding: 0 5px; + font-size: 1.1em; + width: 22px; + text-align: center; + line-height: 30px; + float: right; +} +#options .decreaseFont {border-top: 0;} + +/* POPUPS */ +.popup { + position: fixed; + top: 50%; + left: 50%; + background: #ddd; +} +.popup .close { + position: absolute; + background: #aaa; + top: 0; + right: 0; + color: #333; + text-decoration: none; + z-index: 2; + padding: 0 10px; + height: 30px; + line-height: 30px; +} +.popup .close:hover {background: #999;} +.popup .head { + background: #999; + color: #ddd; + padding: 0 10px; + height: 30px; + line-height: 30px; + text-transform: uppercase; + font-size: 0.9em; + font-weight: bold; + border-bottom: 2px solid green; +} +.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;} +.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;} +.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;} +.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;} + +.changeFont {padding: 10px;} +.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;} +.changeFont a:hover {background: #ccc;} + +.highlightPopup {padding: 10px; text-align: center;} +.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;} +.highlightPopup input.highlightColor {background-color: #FFFF00;} +.highlightPopup input.highlightTermSubmit {margin-top: 5px;} + +/* ADMIN CONTEXT MENU */ +.contextMenu { + background-color: #ddd; + position: fixed; + margin: 2px; + width: 150px; +} +.contextMenu a { + display: block; + padding: 2px 5px; + text-decoration: none; + color: #333; +} + +.contextMenu a:hover { + background-color: #ccc; +} + +/* ADMIN FILTER MESSAGES MENU */ +.filterMessages {padding: 5px;} +.filterMessages div {padding: 2px 0;} +.filterMessages input {} +.filterMessages label {} + +.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;} + + +/***************************************** +* +* OUTPUT ACTUALLY RELATED TO MESSAGES +* +******************************************/ + +/* MOTD */ +.motd {color: #638500;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;} + +/* ADD HERE FOR BOLD */ +.bold, .name, .prefix, .ooc, .looc, .adminooc, .adminlooc, .admin, .gfartooc, .gfartlooc, .gfartadmin, .mentorooc, .mentorlooc, .medal {font-weight: bold;} + +/* ADD HERE FOR ITALIC */ +.italic, .ghostdronesay.broadcast {font-style: italic;} + +/* OUTPUT COLORS */ +.highlight {background: yellow;} +h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;} +em {font-style: normal; font-weight: bold;} +.motd {color: #638500; font-family: Verdana, sans-serif;} +.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 + {color: #638500; text-decoration: underline;} +.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover + {color: #638500;} +.prefix { font-weight: bold;} +.ooc { font-weight: bold;} +.looc {color: #6699CC;} +.adminobserverooc {color: #0099cc; font-weight: bold;} +.adminooc {color: #b82e00; font-weight: bold;} +.adminobserver {color: #996600; font-weight: bold;} +.admin {color: #386aff; font-weight: bold;} +.adminsay {color: #9611D4; font-weight: bold;} +.mentorhelp {color: #0077bb; font-weight: bold;} +.adminhelp {color: #aa0000; font-weight: bold;} +.playerreply {color: #8800bb; font-weight: bold;} +.name { font-weight: bold;} +.say {} +.siliconsay {font-family: 'Courier New', Courier, monospace;} +.deadsay {color: #5c00e6;} +.radio {color: #008000;} +.deptradio {color: #993399;} +.comradio {color: #193A7A;} +.syndradio {color: #6d3f40;} +.dsquadradio {color: #686868;} +.resteamradio {color: #18BC46;} +.airadio {color: #FF00FF;} +.centradio {color: #5C5C8A;} +.secradio {color: #A30000;} +.engradio {color: #A66300;} +.medradio {color: #008160;} +.sciradio {color: #993399;} +.supradio {color: #5F4519;} +.srvradio {color: #6eaa2c;} +.admin_channel {color: #9A04D1; font-weight: bold;} +.mod_channel {color: #402A14; font-weight: bold;} +.mod_channel_admin {color: #402A14; font-weight: bold;} +.djradio {color: #663300;} +.binaryradio {color: #0B0050; font-family: 'Courier New', Courier, monospace;} +.mommiradio {color: navy;} +.alert {color: #ff0000;} +h1.alert, h2.alert {color: #000000;} +.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} +.emote { font-style: italic;} +.selecteddna {color: #FFFFFF; background-color: #001B1B} + +.attack {color: #ff0000;} +.moderate {color: #CC0000;} +.disarm {color: #990000;} +.passive {color: #660000;} + +.warning {color: #ff0000; font-style: italic;} +.danger {color: #ff0000; font-weight: bold;} +.userdanger {color: #ff0000; font-weight: bold; font-size: 120%;} +.biggerdanger {color: #ff0000; font-weight: bold; font-size: 150%;} + +.info {color: #0000CC;} +.notice {color: #000099;} +.bnotice {color: #000099; font-weight: bold;} +.boldnotice {color: #000099; font-weight: bold;} +.suicide {color: #ff5050; font-style: italic;} + +.announce {color: #228b22; font-weight: bold;} +.boldannounce {color: #ff0000; font-weight: bold;} +.greenannounce {color: #00ff00; font-weight: bold;} + +.alien {color: #543354;} +.noticealien {color: #00c000;} +.alertalien {color: #00c000; font-weight: bold;} + +.sinister {color: #800080; font-weight: bold; font-style: italic;} /* /vg/ */ +.blob {color: #006221; font-weight: bold; font-style: italic;} +.confirm {color: #00af3b;} +.rose {color: #ff5050;} +.sans {font-family: 'Comic Sans MS', cursive, sans-serif;} +.ancient {color: #008B8B; font-stye: italic;} +.newscaster {color: #800000;} +.mod {color: #735638; font-weight: bold;} +.modooc {color: #184880; font-weight: bold;} +.adminmod {color: #402A14; font-weight: bold;} +.tajaran {color: #803B56;} +.skrell {color: #00CED1;} +.solcom {color: #22228B;} +.soghun {color: #228B22;} +.changeling {color: #800080;} +.vox {color: #AA00AA;} +.trinary {color: #727272;} +.kidan {color: #664205;} +.slime {color: #0077AA;} +.drask {color: #a3d4eb; font-family: "Arial Black";} +.clown {color: #ff0000;} +.shadowling {color: #3b2769;} +.vulpkanin {color: #B97A57;} +.abductor {color: #800080;} +.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;} +.cultspeech {color: #7F0000; font-style: italic;} +.interface {color: #330033;} +.big {font-size: 150%;} +.reallybig {font-size: 175%;} +.greentext {color: #00FF00; font-size: 150%;} +.redtext {color: #FF0000; font-size: 150%;} +.bold {font-weight: bold;} +.center {text-align: center;} +.red {color: #FF0000;} +.grey {font-family: "Wingdings", cursive, sans-serif;} +.skeleton {color: #585858; font-weight: bold; font-style: italic;} +.gutter {color: #61380B; font-style: italic;} +.orange {color: #ffa500;} +.orangei {color: #ffa500; font-style: italic;} +.orangeb {color: #ffa500; font-weight: bold;} + +.revennotice {color: #1d2953;} +.revenboldnotice {color: #1d2953; font-weight: bold;} +.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;} +.revenminor {color: #823abb} +.revenwarning {color: #760fbb; font-style: italic;} +.revendanger {color: #760fbb; font-weight: bold; font-size: 3;} + +/* /vg/ */ +.good {color: green;} +.average {color: #FF8000;} +.bad {color: #FF0000;} +/* /vg/ Saycode Rewrite */ +.italics, .talkinto {font-style:italic;} +.whisper {font-style:italic;color:#333333;} +/* Recruiting stuff */ +.recruit {color: #5c00e6; font-weight: bold; font-style: italic;} +"} + +.memo {color: #638500; text-align: center;} +.memoedit {text-align: center; font-size: 2;} + +.connectionClosed, .fatalError {background: red; color: white; padding: 5px;} +.connectionClosed.restored {background: green;} +.internal.boldnshit {color: blue; font-weight: bold;} + +/* HELPER CLASSES */ +.text-normal {font-weight: normal; font-style: normal;} +.hidden {display: none; visibility: hidden;} diff --git a/goon/browserassets/css/font-awesome.css b/goon/browserassets/css/font-awesome.css new file mode 100644 index 00000000000..956b4cbafd8 --- /dev/null +++ b/goon/browserassets/css/font-awesome.css @@ -0,0 +1,788 @@ +@font-face{font-family:'FontAwesome';src:url('fontawesome-webfont.eot');src:url('fontawesome-webfont.eot') format('embedded-opentype'),url('fontawesome-webfont.woff') format('woff'),url('fontawesome-webfont.ttf') format('truetype'),url('fontawesome-webfont.svg') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*=" icon-"]{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;} +[class^="icon-"]:before,[class*=" icon-"]:before{text-decoration:inherit;display:inline-block;speak:none;} +.icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;} +a [class^="icon-"],a [class*=" icon-"]{display:inline;} +[class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;} +.icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;} +.icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;} +[class^="icon-"].hide,[class*=" icon-"].hide{display:none;} +.icon-muted{color:#eeeeee;} +.icon-light{color:#ffffff;} +.icon-dark{color:#333333;} +.icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;} +.pull-right{float:right;} +.pull-left{float:left;} +[class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;} +[class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;} +[class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;} +.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;} +.btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;} +.btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;} +.nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;} +.btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;} +.btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;} +.btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;} +.btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;} +.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;} +.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;} +.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;} +.icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;} +.icon-stack .icon-stack-base{font-size:2em;*line-height:1em;} +.icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;} +a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;} +@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);} +.icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);} +.icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);} +.icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);} +.icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);} +a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;} +.icon-glass:before{content:"\f000";} +.icon-music:before{content:"\f001";} +.icon-search:before{content:"\f002";} +.icon-envelope-alt:before{content:"\f003";} +.icon-heart:before{content:"\f004";} +.icon-star:before{content:"\f005";} +.icon-star-empty:before{content:"\f006";} +.icon-user:before{content:"\f007";} +.icon-film:before{content:"\f008";} +.icon-th-large:before{content:"\f009";} +.icon-th:before{content:"\f00a";} +.icon-th-list:before{content:"\f00b";} +.icon-ok:before{content:"\f00c";} +.icon-remove:before{content:"\f00d";} +.icon-zoom-in:before{content:"\f00e";} +.icon-zoom-out:before{content:"\f010";} +.icon-power-off:before,.icon-off:before{content:"\f011";} +.icon-signal:before{content:"\f012";} +.icon-gear:before,.icon-cog:before{content:"\f013";} +.icon-trash:before{content:"\f014";} +.icon-home:before{content:"\f015";} +.icon-file-alt:before{content:"\f016";} +.icon-time:before{content:"\f017";} +.icon-road:before{content:"\f018";} +.icon-download-alt:before{content:"\f019";} +.icon-download:before{content:"\f01a";} +.icon-upload:before{content:"\f01b";} +.icon-inbox:before{content:"\f01c";} +.icon-play-circle:before{content:"\f01d";} +.icon-rotate-right:before,.icon-repeat:before{content:"\f01e";} +.icon-refresh:before{content:"\f021";} +.icon-list-alt:before{content:"\f022";} +.icon-lock:before{content:"\f023";} +.icon-flag:before{content:"\f024";} +.icon-headphones:before{content:"\f025";} +.icon-volume-off:before{content:"\f026";} +.icon-volume-down:before{content:"\f027";} +.icon-volume-up:before{content:"\f028";} +.icon-qrcode:before{content:"\f029";} +.icon-barcode:before{content:"\f02a";} +.icon-tag:before{content:"\f02b";} +.icon-tags:before{content:"\f02c";} +.icon-book:before{content:"\f02d";} +.icon-bookmark:before{content:"\f02e";} +.icon-print:before{content:"\f02f";} +.icon-camera:before{content:"\f030";} +.icon-font:before{content:"\f031";} +.icon-bold:before{content:"\f032";} +.icon-italic:before{content:"\f033";} +.icon-text-height:before{content:"\f034";} +.icon-text-width:before{content:"\f035";} +.icon-align-left:before{content:"\f036";} +.icon-align-center:before{content:"\f037";} +.icon-align-right:before{content:"\f038";} +.icon-align-justify:before{content:"\f039";} +.icon-list:before{content:"\f03a";} +.icon-indent-left:before{content:"\f03b";} +.icon-indent-right:before{content:"\f03c";} +.icon-facetime-video:before{content:"\f03d";} +.icon-picture:before{content:"\f03e";} +.icon-pencil:before{content:"\f040";} +.icon-map-marker:before{content:"\f041";} +.icon-adjust:before{content:"\f042";} +.icon-tint:before{content:"\f043";} +.icon-edit:before{content:"\f044";} +.icon-share:before{content:"\f045";} +.icon-check:before{content:"\f046";} +.icon-move:before{content:"\f047";} +.icon-step-backward:before{content:"\f048";} +.icon-fast-backward:before{content:"\f049";} +.icon-backward:before{content:"\f04a";} +.icon-play:before{content:"\f04b";} +.icon-pause:before{content:"\f04c";} +.icon-stop:before{content:"\f04d";} +.icon-forward:before{content:"\f04e";} +.icon-fast-forward:before{content:"\f050";} +.icon-step-forward:before{content:"\f051";} +.icon-eject:before{content:"\f052";} +.icon-chevron-left:before{content:"\f053";} +.icon-chevron-right:before{content:"\f054";} +.icon-plus-sign:before{content:"\f055";} +.icon-minus-sign:before{content:"\f056";} +.icon-remove-sign:before{content:"\f057";} +.icon-ok-sign:before{content:"\f058";} +.icon-question-sign:before{content:"\f059";} +.icon-info-sign:before{content:"\f05a";} +.icon-screenshot:before{content:"\f05b";} +.icon-remove-circle:before{content:"\f05c";} +.icon-ok-circle:before{content:"\f05d";} +.icon-ban-circle:before{content:"\f05e";} +.icon-arrow-left:before{content:"\f060";} +.icon-arrow-right:before{content:"\f061";} +.icon-arrow-up:before{content:"\f062";} +.icon-arrow-down:before{content:"\f063";} +.icon-mail-forward:before,.icon-share-alt:before{content:"\f064";} +.icon-resize-full:before{content:"\f065";} +.icon-resize-small:before{content:"\f066";} +.icon-plus:before{content:"\f067";} +.icon-minus:before{content:"\f068";} +.icon-asterisk:before{content:"\f069";} +.icon-exclamation-sign:before{content:"\f06a";} +.icon-gift:before{content:"\f06b";} +.icon-leaf:before{content:"\f06c";} +.icon-fire:before{content:"\f06d";} +.icon-eye-open:before{content:"\f06e";} +.icon-eye-close:before{content:"\f070";} +.icon-warning-sign:before{content:"\f071";} +.icon-plane:before{content:"\f072";} +.icon-calendar:before{content:"\f073";} +.icon-random:before{content:"\f074";} +.icon-comment:before{content:"\f075";} +.icon-magnet:before{content:"\f076";} +.icon-chevron-up:before{content:"\f077";} +.icon-chevron-down:before{content:"\f078";} +.icon-retweet:before{content:"\f079";} +.icon-shopping-cart:before{content:"\f07a";} +.icon-folder-close:before{content:"\f07b";} +.icon-folder-open:before{content:"\f07c";} +.icon-resize-vertical:before{content:"\f07d";} +.icon-resize-horizontal:before{content:"\f07e";} +.icon-bar-chart:before{content:"\f080";} +.icon-twitter-sign:before{content:"\f081";} +.icon-facebook-sign:before{content:"\f082";} +.icon-camera-retro:before{content:"\f083";} +.icon-key:before{content:"\f084";} +.icon-gears:before,.icon-cogs:before{content:"\f085";} +.icon-comments:before{content:"\f086";} +.icon-thumbs-up-alt:before{content:"\f087";} +.icon-thumbs-down-alt:before{content:"\f088";} +.icon-star-half:before{content:"\f089";} +.icon-heart-empty:before{content:"\f08a";} +.icon-signout:before{content:"\f08b";} +.icon-linkedin-sign:before{content:"\f08c";} +.icon-pushpin:before{content:"\f08d";} +.icon-external-link:before{content:"\f08e";} +.icon-signin:before{content:"\f090";} +.icon-trophy:before{content:"\f091";} +.icon-github-sign:before{content:"\f092";} +.icon-upload-alt:before{content:"\f093";} +.icon-lemon:before{content:"\f094";} +.icon-phone:before{content:"\f095";} +.icon-unchecked:before,.icon-check-empty:before{content:"\f096";} +.icon-bookmark-empty:before{content:"\f097";} +.icon-phone-sign:before{content:"\f098";} +.icon-twitter:before{content:"\f099";} +.icon-facebook:before{content:"\f09a";} +.icon-github:before{content:"\f09b";} +.icon-unlock:before{content:"\f09c";} +.icon-credit-card:before{content:"\f09d";} +.icon-rss:before{content:"\f09e";} +.icon-hdd:before{content:"\f0a0";} +.icon-bullhorn:before{content:"\f0a1";} +.icon-bell:before{content:"\f0a2";} +.icon-certificate:before{content:"\f0a3";} +.icon-hand-right:before{content:"\f0a4";} +.icon-hand-left:before{content:"\f0a5";} +.icon-hand-up:before{content:"\f0a6";} +.icon-hand-down:before{content:"\f0a7";} +.icon-circle-arrow-left:before{content:"\f0a8";} +.icon-circle-arrow-right:before{content:"\f0a9";} +.icon-circle-arrow-up:before{content:"\f0aa";} +.icon-circle-arrow-down:before{content:"\f0ab";} +.icon-globe:before{content:"\f0ac";} +.icon-wrench:before{content:"\f0ad";} +.icon-tasks:before{content:"\f0ae";} +.icon-filter:before{content:"\f0b0";} +.icon-briefcase:before{content:"\f0b1";} +.icon-fullscreen:before{content:"\f0b2";} +.icon-group:before{content:"\f0c0";} +.icon-link:before{content:"\f0c1";} +.icon-cloud:before{content:"\f0c2";} +.icon-beaker:before{content:"\f0c3";} +.icon-cut:before{content:"\f0c4";} +.icon-copy:before{content:"\f0c5";} +.icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";} +.icon-save:before{content:"\f0c7";} +.icon-sign-blank:before{content:"\f0c8";} +.icon-reorder:before{content:"\f0c9";} +.icon-list-ul:before{content:"\f0ca";} +.icon-list-ol:before{content:"\f0cb";} +.icon-strikethrough:before{content:"\f0cc";} +.icon-underline:before{content:"\f0cd";} +.icon-table:before{content:"\f0ce";} +.icon-magic:before{content:"\f0d0";} +.icon-truck:before{content:"\f0d1";} +.icon-pinterest:before{content:"\f0d2";} +.icon-pinterest-sign:before{content:"\f0d3";} +.icon-google-plus-sign:before{content:"\f0d4";} +.icon-google-plus:before{content:"\f0d5";} +.icon-money:before{content:"\f0d6";} +.icon-caret-down:before{content:"\f0d7";} +.icon-caret-up:before{content:"\f0d8";} +.icon-caret-left:before{content:"\f0d9";} +.icon-caret-right:before{content:"\f0da";} +.icon-columns:before{content:"\f0db";} +.icon-sort:before{content:"\f0dc";} +.icon-sort-down:before{content:"\f0dd";} +.icon-sort-up:before{content:"\f0de";} +.icon-envelope:before{content:"\f0e0";} +.icon-linkedin:before{content:"\f0e1";} +.icon-rotate-left:before,.icon-undo:before{content:"\f0e2";} +.icon-legal:before{content:"\f0e3";} +.icon-dashboard:before{content:"\f0e4";} +.icon-comment-alt:before{content:"\f0e5";} +.icon-comments-alt:before{content:"\f0e6";} +.icon-bolt:before{content:"\f0e7";} +.icon-sitemap:before{content:"\f0e8";} +.icon-umbrella:before{content:"\f0e9";} +.icon-paste:before{content:"\f0ea";} +.icon-lightbulb:before{content:"\f0eb";} +.icon-exchange:before{content:"\f0ec";} +.icon-cloud-download:before{content:"\f0ed";} +.icon-cloud-upload:before{content:"\f0ee";} +.icon-user-md:before{content:"\f0f0";} +.icon-stethoscope:before{content:"\f0f1";} +.icon-suitcase:before{content:"\f0f2";} +.icon-bell-alt:before{content:"\f0f3";} +.icon-coffee:before{content:"\f0f4";} +.icon-food:before{content:"\f0f5";} +.icon-file-text-alt:before{content:"\f0f6";} +.icon-building:before{content:"\f0f7";} +.icon-hospital:before{content:"\f0f8";} +.icon-ambulance:before{content:"\f0f9";} +.icon-medkit:before{content:"\f0fa";} +.icon-fighter-jet:before{content:"\f0fb";} +.icon-beer:before{content:"\f0fc";} +.icon-h-sign:before{content:"\f0fd";} +.icon-plus-sign-alt:before{content:"\f0fe";} +.icon-double-angle-left:before{content:"\f100";} +.icon-double-angle-right:before{content:"\f101";} +.icon-double-angle-up:before{content:"\f102";} +.icon-double-angle-down:before{content:"\f103";} +.icon-angle-left:before{content:"\f104";} +.icon-angle-right:before{content:"\f105";} +.icon-angle-up:before{content:"\f106";} +.icon-angle-down:before{content:"\f107";} +.icon-desktop:before{content:"\f108";} +.icon-laptop:before{content:"\f109";} +.icon-tablet:before{content:"\f10a";} +.icon-mobile-phone:before{content:"\f10b";} +.icon-circle-blank:before{content:"\f10c";} +.icon-quote-left:before{content:"\f10d";} +.icon-quote-right:before{content:"\f10e";} +.icon-spinner:before{content:"\f110";} +.icon-circle:before{content:"\f111";} +.icon-mail-reply:before,.icon-reply:before{content:"\f112";} +.icon-github-alt:before{content:"\f113";} +.icon-folder-close-alt:before{content:"\f114";} +.icon-folder-open-alt:before{content:"\f115";} +.icon-expand-alt:before{content:"\f116";} +.icon-collapse-alt:before{content:"\f117";} +.icon-smile:before{content:"\f118";} +.icon-frown:before{content:"\f119";} +.icon-meh:before{content:"\f11a";} +.icon-gamepad:before{content:"\f11b";} +.icon-keyboard:before{content:"\f11c";} +.icon-flag-alt:before{content:"\f11d";} +.icon-flag-checkered:before{content:"\f11e";} +.icon-terminal:before{content:"\f120";} +.icon-code:before{content:"\f121";} +.icon-reply-all:before{content:"\f122";} +.icon-mail-reply-all:before{content:"\f122";} +.icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";} +.icon-location-arrow:before{content:"\f124";} +.icon-crop:before{content:"\f125";} +.icon-code-fork:before{content:"\f126";} +.icon-unlink:before{content:"\f127";} +.icon-question:before{content:"\f128";} +.icon-info:before{content:"\f129";} +.icon-exclamation:before{content:"\f12a";} +.icon-superscript:before{content:"\f12b";} +.icon-subscript:before{content:"\f12c";} +.icon-eraser:before{content:"\f12d";} +.icon-puzzle-piece:before{content:"\f12e";} +.icon-microphone:before{content:"\f130";} +.icon-microphone-off:before{content:"\f131";} +.icon-shield:before{content:"\f132";} +.icon-calendar-empty:before{content:"\f133";} +.icon-fire-extinguisher:before{content:"\f134";} +.icon-rocket:before{content:"\f135";} +.icon-maxcdn:before{content:"\f136";} +.icon-chevron-sign-left:before{content:"\f137";} +.icon-chevron-sign-right:before{content:"\f138";} +.icon-chevron-sign-up:before{content:"\f139";} +.icon-chevron-sign-down:before{content:"\f13a";} +.icon-html5:before{content:"\f13b";} +.icon-css3:before{content:"\f13c";} +.icon-anchor:before{content:"\f13d";} +.icon-unlock-alt:before{content:"\f13e";} +.icon-bullseye:before{content:"\f140";} +.icon-ellipsis-horizontal:before{content:"\f141";} +.icon-ellipsis-vertical:before{content:"\f142";} +.icon-rss-sign:before{content:"\f143";} +.icon-play-sign:before{content:"\f144";} +.icon-ticket:before{content:"\f145";} +.icon-minus-sign-alt:before{content:"\f146";} +.icon-check-minus:before{content:"\f147";} +.icon-level-up:before{content:"\f148";} +.icon-level-down:before{content:"\f149";} +.icon-check-sign:before{content:"\f14a";} +.icon-edit-sign:before{content:"\f14b";} +.icon-external-link-sign:before{content:"\f14c";} +.icon-share-sign:before{content:"\f14d";} +.icon-compass:before{content:"\f14e";} +.icon-collapse:before{content:"\f150";} +.icon-collapse-top:before{content:"\f151";} +.icon-expand:before{content:"\f152";} +.icon-euro:before,.icon-eur:before{content:"\f153";} +.icon-gbp:before{content:"\f154";} +.icon-dollar:before,.icon-usd:before{content:"\f155";} +.icon-rupee:before,.icon-inr:before{content:"\f156";} +.icon-yen:before,.icon-jpy:before{content:"\f157";} +.icon-renminbi:before,.icon-cny:before{content:"\f158";} +.icon-won:before,.icon-krw:before{content:"\f159";} +.icon-bitcoin:before,.icon-btc:before{content:"\f15a";} +.icon-file:before{content:"\f15b";} +.icon-file-text:before{content:"\f15c";} +.icon-sort-by-alphabet:before{content:"\f15d";} +.icon-sort-by-alphabet-alt:before{content:"\f15e";} +.icon-sort-by-attributes:before{content:"\f160";} +.icon-sort-by-attributes-alt:before{content:"\f161";} +.icon-sort-by-order:before{content:"\f162";} +.icon-sort-by-order-alt:before{content:"\f163";} +.icon-thumbs-up:before{content:"\f164";} +.icon-thumbs-down:before{content:"\f165";} +.icon-youtube-sign:before{content:"\f166";} +.icon-youtube:before{content:"\f167";} +.icon-xing:before{content:"\f168";} +.icon-xing-sign:before{content:"\f169";} +.icon-youtube-play:before{content:"\f16a";} +.icon-dropbox:before{content:"\f16b";} +.icon-stackexchange:before{content:"\f16c";} +.icon-instagram:before{content:"\f16d";} +.icon-flickr:before{content:"\f16e";} +.icon-adn:before{content:"\f170";} +.icon-bitbucket:before{content:"\f171";} +.icon-bitbucket-sign:before{content:"\f172";} +.icon-tumblr:before{content:"\f173";} +.icon-tumblr-sign:before{content:"\f174";} +.icon-long-arrow-down:before{content:"\f175";} +.icon-long-arrow-up:before{content:"\f176";} +.icon-long-arrow-left:before{content:"\f177";} +.icon-long-arrow-right:before{content:"\f178";} +.icon-apple:before{content:"\f179";} +.icon-windows:before{content:"\f17a";} +.icon-android:before{content:"\f17b";} +.icon-linux:before{content:"\f17c";} +.icon-dribbble:before{content:"\f17d";} +.icon-skype:before{content:"\f17e";} +.icon-foursquare:before{content:"\f180";} +.icon-trello:before{content:"\f181";} +.icon-female:before{content:"\f182";} +.icon-male:before{content:"\f183";} +.icon-gittip:before{content:"\f184";} +.icon-sun:before{content:"\f185";} +.icon-moon:before{content:"\f186";} +.icon-archive:before{content:"\f187";} +.icon-bug:before{content:"\f188";} +.icon-vk:before{content:"\f189";} +.icon-weibo:before{content:"\f18a";} +.icon-renren:before{content:"\f18b";} + +.icon-large{font-size:1.3333333333333333em;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;vertical-align:middle;} +.nav [class^="icon-"],.nav [class*=" icon-"]{vertical-align:inherit;margin-top:-4px;padding-top:3px;margin-bottom:-4px;padding-bottom:3px;}.nav [class^="icon-"].icon-large,.nav [class*=" icon-"].icon-large{vertical-align:-25%;} +.nav-pills [class^="icon-"].icon-large,.nav-tabs [class^="icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large{line-height:.75em;margin-top:-7px;padding-top:5px;margin-bottom:-5px;padding-bottom:4px;} +.btn [class^="icon-"].pull-left,.btn [class*=" icon-"].pull-left,.btn [class^="icon-"].pull-right,.btn [class*=" icon-"].pull-right{vertical-align:inherit;} +.btn [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large{margin-top:-0.5em;} +a [class^="icon-"],a [class*=" icon-"]{cursor:pointer;} +.icon-glass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-music{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-search{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-envelope-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-heart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-star{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-star-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-user{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-film{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-th-large{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-th{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-th-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ok{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-remove{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-zoom-in{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-zoom-out{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-power-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-signal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cog{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gear{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-trash{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-home{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-file-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-time{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-road{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-download-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-inbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-play-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-repeat{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rotate-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-refresh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-list-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-lock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-flag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-headphones{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-volume-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-volume-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-volume-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-qrcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-barcode{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tag{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tags{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-book{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bookmark{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-print{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-camera{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-font{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bold{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-italic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-text-height{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-text-width{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-align-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-align-center{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-align-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-align-justify{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-list{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-indent-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-indent-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-facetime-video{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-picture{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-pencil{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-map-marker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-adjust{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tint{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-edit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-share{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-check{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-move{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-step-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fast-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-backward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-pause{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-stop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fast-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-step-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-eject{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-minus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-remove-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ok-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-question-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-info-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-screenshot{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-remove-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ok-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ban-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-share-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-mail-forward{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-resize-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-resize-small{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-asterisk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-exclamation-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gift{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-leaf{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fire{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-eye-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-eye-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-warning-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-plane{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-calendar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-random{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-comment{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-magnet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-retweet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-shopping-cart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-folder-close{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-folder-open{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-resize-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-resize-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bar-chart{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-twitter-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-facebook-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-camera-retro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-key{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cogs{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gears{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-comments{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-thumbs-up-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-thumbs-down-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-star-half{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-heart-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-signout{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-linkedin-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-pushpin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-external-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-signin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-trophy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-github-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-upload-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-lemon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-check-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-unchecked{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bookmark-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-phone-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-twitter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-facebook{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-github{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-unlock{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-credit-card{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rss{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hdd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bullhorn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bell{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-certificate{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hand-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hand-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hand-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hand-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-globe{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-wrench{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tasks{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-filter{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-briefcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fullscreen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-group{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-link{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cloud{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-beaker{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cut{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-copy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-paper-clip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-paperclip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-save{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sign-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-reorder{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-list-ul{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-list-ol{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-strikethrough{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-underline{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-table{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-magic{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-truck{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-pinterest{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-pinterest-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-google-plus-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-google-plus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-money{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-caret-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-caret-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-caret-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-caret-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-columns{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-envelope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-linkedin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-undo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rotate-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-legal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-dashboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-comment-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-comments-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bolt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sitemap{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-umbrella{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-paste{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-lightbulb{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-exchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cloud-download{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cloud-upload{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-user-md{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-stethoscope{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-suitcase{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bell-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-coffee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-food{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-file-text-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-building{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-hospital{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ambulance{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-medkit{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fighter-jet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-beer{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-h-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-plus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-double-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-double-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-double-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-double-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-angle-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-angle-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-angle-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-angle-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-desktop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-laptop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tablet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-mobile-phone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle-blank{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-quote-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-quote-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-spinner{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-circle{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-mail-reply{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-github-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-folder-close-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-folder-open-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-expand-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-collapse-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-smile{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-frown{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-meh{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gamepad{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-keyboard{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-flag-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-flag-checkered{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-terminal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-code{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-mail-reply-all{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-star-half-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-star-half-full{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-location-arrow{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-crop{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-code-fork{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-unlink{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-question{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-info{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-exclamation{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-superscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-subscript{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-eraser{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-puzzle-piece{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-microphone{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-microphone-off{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-shield{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-calendar-empty{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-fire-extinguisher{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rocket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-maxcdn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-sign-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-sign-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-sign-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-chevron-sign-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-html5{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-css3{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-anchor{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-unlock-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bullseye{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ellipsis-horizontal{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ellipsis-vertical{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rss-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-play-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-ticket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-minus-sign-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-check-minus{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-level-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-level-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-check-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-edit-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-external-link-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-share-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-compass{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-collapse{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-collapse-top{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-expand{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-eur{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-euro{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gbp{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-usd{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-dollar{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-inr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-rupee{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-jpy{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-yen{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-cny{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-renminbi{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-krw{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-won{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-btc{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bitcoin{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-file{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-file-text{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-alphabet{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-alphabet-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-attributes{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-attributes-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-order{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sort-by-order-alt{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-thumbs-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-thumbs-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-youtube-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-youtube{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-xing{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-xing-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-youtube-play{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-dropbox{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-stackexchange{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-instagram{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-flickr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-adn{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bitbucket{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bitbucket-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tumblr{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-tumblr-sign{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-long-arrow-down{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-long-arrow-up{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-long-arrow-left{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-long-arrow-right{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-apple{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-windows{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-android{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-linux{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-dribbble{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-skype{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-foursquare{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-trello{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-female{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-male{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-gittip{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-sun{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-moon{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-archive{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-bug{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-vk{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-weibo{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} +.icon-renren{*zoom:expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '');} diff --git a/goon/browserassets/css/fonts/fontawesome-webfont.eot b/goon/browserassets/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000000..0662cb96bfb Binary files /dev/null and b/goon/browserassets/css/fonts/fontawesome-webfont.eot differ diff --git a/goon/browserassets/css/fonts/fontawesome-webfont.svg b/goon/browserassets/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000000..2edb4ec34cb --- /dev/null +++ b/goon/browserassets/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/goon/browserassets/css/fonts/fontawesome-webfont.ttf b/goon/browserassets/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000000..d3659246915 Binary files /dev/null and b/goon/browserassets/css/fonts/fontawesome-webfont.ttf differ diff --git a/goon/browserassets/css/fonts/fontawesome-webfont.woff b/goon/browserassets/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000000..b9bd17e158d Binary files /dev/null and b/goon/browserassets/css/fonts/fontawesome-webfont.woff differ diff --git a/goon/browserassets/html/browserOutput.html b/goon/browserassets/html/browserOutput.html new file mode 100644 index 00000000000..74212fd8156 --- /dev/null +++ b/goon/browserassets/html/browserOutput.html @@ -0,0 +1,44 @@ + + + + Chat + + + + + + + + +
+ +
+ Loading...

+ If this takes longer than 30 seconds, it will automatically reload a maximum of 5 times.
+ If it still doesn't work, use the bug report button at the top right of the window. +
+
+
+ +
+ + + + \ No newline at end of file diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js new file mode 100644 index 00000000000..9d605ab4915 --- /dev/null +++ b/goon/browserassets/js/browserOutput.js @@ -0,0 +1,919 @@ +/***************************************** +* +* FUNCTION AND VAR DECLARATIONS +* +******************************************/ + +//DEBUG STUFF +var escaper = encodeURIComponent || escape; +var decoder = decodeURIComponent || unescape; +window.onerror = function(msg, url, line, col, error) { + if (document.location.href.indexOf("proc=debug") <= 0) { + var extra = !col ? '' : ' | column: ' + col; + extra += !error ? '' : ' | error: ' + error; + extra += !navigator.userAgent ? '' : ' | user agent: ' + navigator.userAgent; + var debugLine = 'Error: ' + msg + ' | url: ' + url + ' | line: ' + line + extra; + window.location = '?_src_=chat&proc=debug¶m[error]='+escaper(debugLine); + } + return true; +}; + +//Globals +window.status = 'Output'; +var $messages, $subOptions, $contextMenu, $filterMessages; +var opts = { + //General + 'messageCount': 0, //A count...of messages... + 'messageLimit': 2053, //A limit...for the messages... + 'scrollSnapTolerance': 5, //If within x pixels of bottom + 'clickTolerance': 10, //Keep focus if outside x pixels of mousedown position on mouseup + 'popups': 0, //Amount of popups opened ever + 'wasd': false, //Is the user in wasd mode? + 'chatMode': 'default', //The mode the chat is in + 'priorChatHeight': 0, //Thing for height-resizing detection + 'restarting': false, //Is the round restarting? + + //Options menu + 'subOptionsLoop': null, //Contains the interval loop for closing the options menu + 'suppressOptionsClose': false, //Whether or not we should be hiding the suboptions menu + 'highlightTerms': [], + 'highlightLimit': 5, + 'highlightColor': '#FFFF00', //The color of the highlighted message + 'pingDisabled': false, //Has the user disabled the ping counter + + //Ping display + 'lastPang': 0, //Timestamp of the last response from the server. + 'pangLimit': 35000, + 'pingTime': 0, //Timestamp of when ping sent + 'pongTime': 0, //Timestamp of when ping received + 'noResponse': false, //Tracks the state of the previous ping request + 'noResponseCount': 0, //How many failed pings? + + //Clicks + 'mouseDownX': null, + 'mouseDownY': null, + 'preventFocus': false, //Prevents switching focus to the game window + + //Admin stuff + 'adminLoaded': false, //Has the admin loaded his shit? + + //Client Connection Data + 'clientDataLimit': 5, + 'clientData': [], + + // List of macros in the 'hotkeymode' macro set. + 'macros': {} +}; + +function outerHTML(el) { + var wrap = document.createElement('div'); + wrap.appendChild(el.cloneNode(true)); + return wrap.innerHTML; +} + +//Polyfill for fucking date now because of course IE8 and below don't support it +if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; +} +//Polyfill for trim() (IE8 and below) +if (typeof String.prototype.trim !== 'function') { + String.prototype.trim = function () { + return this.replace(/^\s+|\s+$/g, ''); + }; +} + +//Shit fucking piece of crap that doesn't work god fuckin damn it +function linkify(text) { + var rex = /((?:'+$0+''; + } + else { + return $1 ? $0: ''+$0+''; + } + }); +} + +//Actually turns the highlight term match into appropriate html +function addHighlightMarkup(match) { + var extra = ''; + if (opts.highlightColor) { + extra += ' style="background-color: '+opts.highlightColor+'"'; + } + return ''+match+''; +} + +//Highlights words based on user settings +function highlightTerms(el) { + if (el.children.length > 0) { + for(var h = 0; h < el.children.length; h++){ + highlightTerms(el.children[h]); + } + } + if (el.childNodes.length > 0 && typeof el.childNodes[0].data !== 'undefined' && el.childNodes[0].data.length > 0) { //If element actually has text + var newText = ''; + for (var c = 0; c < el.childNodes.length; c++) { //Each child element + if (el.childNodes[c].nodeType === 3) { //Is it text only? + var words = el.childNodes[c].data.split(' '); + for (var w = 0; w < words.length; w++) { //Each word in the text + var newWord = null; + for (var i = 0; i < opts.highlightTerms.length; i++) { //Each highlight term + if (opts.highlightTerms[i] && words[w].toLowerCase().indexOf(opts.highlightTerms[i].toLowerCase()) > -1) { //If a match is found + newWord = words[w].replace(new RegExp(opts.highlightTerms[i], 'gi'), addHighlightMarkup); + break; + } + } + newText += newWord ? newWord : words[w]; + newText += w >= words.length ? '' : ' '; + } + } else { //Every other type of element + newText += outerHTML(el.childNodes[c]); + } + } + el.innerHTML = newText; + } +} + +//Send a message to the client +function output(message, flag) { + if (typeof message === 'undefined') { + return; + } + if (typeof flag === 'undefined') { + flag = ''; + } + + if (flag !== 'internal') + opts.lastPang = Date.now(); + + //The behemoth of filter-code (for Admin message filters) + //Note: This is proooobably hella inefficient + var filteredOut = false; + if (opts.hasOwnProperty('showMessagesFilters') && !opts.showMessagesFilters['All'].show) { + //Get this filter type (defined by class on message) + var messageHtml = $.parseHTML(message), + messageClasses; + if (opts.hasOwnProperty('filterHideAll') && opts.filterHideAll) { + var internal = false; + messageClasses = (!!$(messageHtml).attr('class') ? $(messageHtml).attr('class').split(/\s+/) : false); + if (messageClasses) { + for (var i = 0; i < messageClasses.length; i++) { //Every class + if (messageClasses[i] == 'internal') { + internal = true; + break; + } + } + } + if (!internal) { + filteredOut = 'All'; + } + } else { + //If the element or it's child have any classes + if (!!$(messageHtml).attr('class') || !!$(messageHtml).children().attr('class')) { + messageClasses = $(messageHtml).attr('class').split(/\s+/); + if (!!$(messageHtml).children().attr('class')) { + messageClasses = messageClasses.concat($(messageHtml).children().attr('class').split(/\s+/)); + } + var tempCount = 0; + for (var i = 0; i < messageClasses.length; i++) { //Every class + var thisClass = messageClasses[i]; + $.each(opts.showMessagesFilters, function(key, val) { //Every filter + if (key !== 'All' && val.show === false && typeof val.match != 'undefined') { + for (var i = 0; i < val.match.length; i++) { + var matchClass = val.match[i]; + if (matchClass == thisClass) { + filteredOut = key; + break; + } + } + } + if (filteredOut) return false; + }); + if (filteredOut) break; + tempCount++; + } + } else { + if (!opts.showMessagesFilters['Misc'].show) { + filteredOut = 'Misc'; + } + } + } + } + + //Stuff we do along with appending a message + var atBottom = false; + if (!filteredOut) { + var bodyHeight = $('body').height(); + var messagesHeight = $messages.outerHeight(); + var scrollPos = $('body,html').scrollTop(); + + //Should we snap the output to the bottom? + if (bodyHeight + scrollPos >= messagesHeight - opts.scrollSnapTolerance) { + atBottom = true; + if ($('#newMessages').length) { + $('#newMessages').remove(); + } + //If not, put the new messages box in + } else { + if ($('#newMessages').length) { + var messages = $('#newMessages .number').text(); + messages = parseInt(messages); + messages++; + $('#newMessages .number').text(messages); + if (messages == 2) { + $('#newMessages .messageWord').append('s'); + } + } else { + $messages.after('1 new message '); + } + } + } + + //Url stuff + if (message.length && flag != 'preventLink') { + message = linkify(message); + } + + opts.messageCount++; + + //Pop the top message off if history limit reached + if (opts.messageCount >= opts.messageLimit) { + $messages.children('div.entry:first-child').remove(); + opts.messageCount--; //I guess the count should only ever equal the limit + } + + //Actually append the message + var entry = document.createElement('div'); + entry.className = 'entry'; + + if (filteredOut) { + entry.className += ' hidden'; + entry.setAttribute('data-filter', filteredOut); + } + + entry.innerHTML = message; + $messages[0].appendChild(entry); + + //Actually do the snap + if (!filteredOut && atBottom) { + $('body,html').scrollTop($messages.outerHeight()); + } + + //Stuff we can do after the message shows can go here, in the interests of responsiveness + if (opts.highlightTerms && opts.highlightTerms.length > 0) { + highlightTerms(entry); + } +} + +//Runs a route within byond, client or server side. Consider this "ehjax" for byond. +function runByond(uri) { + window.location = uri; +} + +function setCookie(cname, cvalue, exdays) { + cvalue = escaper(cvalue); + var d = new Date(); + d.setTime(d.getTime() + (exdays*24*60*60*1000)); + var expires = 'expires='+d.toUTCString(); + document.cookie = "paradise-" + cname + '=' + cvalue + '; ' + expires; +} + +function getCookie(cname) { + var name = "paradise-" + cname + '='; + var ca = document.cookie.split(';'); + for(var i=0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1); + if (c.indexOf(name) === 0) { + return decoder(c.substring(name.length,c.length)); + } + } + return ''; +} + +function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);} +function toHex(n) { + n = parseInt(n,10); + if (isNaN(n)) return "00"; + n = Math.max(0,Math.min(n,255)); + return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16); +} + +function changeMode(mode) { + switch (mode) { + case 'geocities': + //switch in stylesheet + opts.chatMode = mode; + break; + case 'console': + + opts.chatMode = mode; + break; + case 'default': + default: + //remove loaded stylesheet/s + opts.chatMode = 'default'; + } +} + +function handleClientData(ckey, ip, compid) { + //byond sends player info to here + var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid}; + if (opts.clientData && !$.isEmptyObject(opts.clientData)) { + runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]='+JSON.stringify({'connData': opts.clientData})); + + for (var i = 0; i < opts.clientData.length; i++) { + var saved = opts.clientData[i]; + if (currentData.ckey == saved.ckey && currentData.ip == saved.ip && currentData.compid == saved.compid) { + return; //Record already exists + } + } + + if (opts.clientData.length >= opts.clientDataLimit) { + opts.clientData.shift(); + } + } else { + runByond('?_src_=chat&proc=analyzeClientData¶m[cookie]=none'); + } + + //Update the cookie with current details + opts.clientData.push(currentData); + setCookie('connData', JSON.stringify(opts.clientData), 365); +} + +//Server calls this on ehjax response +//Or, y'know, whenever really +function ehjaxCallback(data) { + opts.lastPang = Date.now(); + if (data == 'softPang') { + return; + } else if (data == "pang") { + opts.pingCounter = 0; + opts.pingTime = Date.now(); + runByond('?_src_=chat&proc=ping'); + } else if (data == 'pong') { + if (opts.pingDisabled) {return;} + opts.pongTime = Date.now(); + var pingDuration = Math.ceil((opts.pongTime - opts.pingTime) / 2); + $('#pingMs').text(pingDuration+'ms'); + pingDuration = Math.min(pingDuration, 255); + var red = pingDuration; + var green = 255 - pingDuration; + var blue = 0; + var hex = rgbToHex(red, green, blue); + $('#pingDot').css('color', '#'+hex); + } else if (data == 'roundrestart') { + opts.restarting = true; + output('
The connection has been closed because the server is restarting. Please wait while you automatically reconnect.
', 'internal'); + } else if (data == 'stopaudio') { + $('.dectalk').remove(); + } else { + //Oh we're actually being sent data instead of an instruction + var dataJ; + try { + dataJ = $.parseJSON(data); + } catch (e) { + //But...incorrect :sadtrombone: + window.onerror('JSON: '+e+'. '+data, 'browserOutput.html', 327); + return; + } + data = dataJ; + + if (data.clientData) { + if (opts.restarting) { + opts.restarting = false; + $('.connectionClosed.restarting:not(.restored)').addClass('restored').text('The round restarted and you successfully reconnected!'); + } + if (!data.clientData.ckey && !data.clientData.ip && !data.clientData.compid) { + //TODO: Call shutdown perhaps + return; + } else { + handleClientData(data.clientData.ckey, data.clientData.ip, data.clientData.compid); + } + } else if (data.loadAdminCode) { + if (opts.adminLoaded) {return;} + var adminCode = data.loadAdminCode; + $('body').append(adminCode); + opts.adminLoaded = true; + } else if (data.modeChange) { + changeMode(data.modeChange); + } else if (data.firebug) { + if (data.trigger) { + output('Loading firebug console, triggered by '+data.trigger+'...', 'internal'); + } else { + output('Loading firebug console...', 'internal'); + } + var firebugEl = document.createElement('script'); + firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; + document.body.appendChild(firebugEl); + } else if (data.dectalk) { + var message = ''; + if (data.decTalkTrigger) { + message = ' '+ + 'You hear a strange robotic voice...' + message; + } + output(message, 'preventLink'); + } + } +} + +function createPopup(contents, width) { + opts.popups++; + $('body').append(''); + + //Attach close popup event + var $popup = $('#popup'+opts.popups); + var height = $popup.outerHeight(); + $popup.css({'height': height+'px', 'margin': '-'+(height/2)+'px 0 0 -'+(width/2)+'px'}); + + $popup.on('click', '.close', function(e) { + e.preventDefault(); + $popup.remove(); + }); +} + +function toggleWasd(state) { + opts.wasd = (state == 'on' ? true : false); +} + +/***************************************** +* +* MAKE MACRO DICTIONARY +* +******************************************/ + +// Callback for winget. +function wingetMacros(macros) { + var idRegex = /.*?\.(?!(?:CRTL|ALT|SHIFT)\+)(.*?)(?:\+REP)?\.command/; // Do NOT match macros which need crtl, alt or shift to be held down (saves a ton of headache because I don't give enough of a fuck). + for (key in macros) { + match = idRegex.exec(key) + if (match === null) + continue + macroID = match[1].toUpperCase(); + + opts.macros[macroID] = macros[key]; + } +} + +/***************************************** +* +* DOM READY +* +******************************************/ + +if (typeof $ === 'undefined') { + var div = document.getElementById('loading').childNodes[1]; + div += '

ERROR: Jquery did not load.'; +} + +$(function() { + $messages = $('#messages'); + $subOptions = $('#subOptions'); + + //Hey look it's a controller loop! + setInterval(function() { + if (opts.lastPang + opts.pangLimit < Date.now() && !opts.restarting) { //Every pingLimit + if (!opts.noResponse) { //Only actually append a message if the previous ping didn't also fail (to prevent spam) + opts.noResponse = true; + opts.noResponseCount++; + output('
You are either AFK, experiencing lag or the connection has closed.
', 'internal'); + } + } else if (opts.noResponse) { //Previous ping attempt failed ohno + $('.connectionClosed[data-count="'+opts.noResponseCount+'"]:not(.restored)').addClass('restored').text('Your connection has been restored (probably)!'); + opts.noResponse = false; + } + }, 2000); //2 seconds + + + + /***************************************** + * + * LOAD SAVED CONFIG + * + ******************************************/ + var savedConfig = { + 'sfontSize': getCookie('fontsize'), + 'sfontType': getCookie('fonttype'), + 'spingDisabled': getCookie('pingdisabled'), + 'shighlightTerms': getCookie('highlightterms'), + 'shighlightColor': getCookie('highlightcolor'), + }; + + if (savedConfig.sfontSize) { + $messages.css('font-size', savedConfig.sfontSize); + output('Loaded font size setting of: '+savedConfig.sfontSize+'', 'internal'); + } + if (savedConfig.sfontType) { + $messages.css('font-family', savedConfig.sfontType); + output('Loaded font type setting of: '+savedConfig.sfontType+'', 'internal'); + } + if (savedConfig.spingDisabled) { + if (savedConfig.spingDisabled == 'true') { + opts.pingDisabled = true; + $('#ping').hide(); + } + output('Loaded ping display of: '+(opts.pingDisabled ? 'hidden' : 'visible')+'', 'internal'); + } + if (savedConfig.shighlightTerms) { + var savedTerms = $.parseJSON(savedConfig.shighlightTerms); + var actualTerms = ''; + for (var i = 0; i < savedTerms.length; i++) { + if (savedTerms[i]) { + actualTerms += savedTerms[i] + ', '; + } + } + if (actualTerms) { + actualTerms = actualTerms.substring(0, actualTerms.length - 2); + output('Loaded highlight strings of: ' + actualTerms+'', 'internal'); + opts.highlightTerms = savedTerms; + } + } + if (savedConfig.shighlightColor) { + opts.highlightColor = savedConfig.shighlightColor; + output('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); + } + + (function() { + var dataCookie = getCookie('connData'); + if (dataCookie) { + var dataJ; + try { + dataJ = $.parseJSON(dataCookie); + } catch (e) { + window.onerror('JSON '+e+'. '+dataCookie, 'browserOutput.html', 434); + return; + } + opts.clientData = dataJ; + } + })(); + + + /***************************************** + * + * BASE CHAT OUTPUT EVENTS + * + ******************************************/ + + $('body').on('click', 'a', function(e) { + e.preventDefault(); + }); + + $('body').on('mousedown', function(e) { + var $target = $(e.target); + + if ($contextMenu && opts.hasOwnProperty('contextMenuTarget') && opts.contextMenuTarget) { + hideContextMenu(); + return false; + } + + if ($target.is('a') || $target.parent('a').length || $target.is('input') || $target.is('textarea')) { + opts.preventFocus = true; + } else { + opts.preventFocus = false; + opts.mouseDownX = e.pageX; + opts.mouseDownY = e.pageY; + } + }); + + $messages.on('mousedown', function(e) { + if ($subOptions && $subOptions.is(':visible')) { + $subOptions.slideUp('fast', function() { + $(this).removeClass('scroll'); + $(this).css('height', ''); + }); + clearInterval(opts.subOptionsLoop); + } + }); + + $('body').on('mouseup', function(e) { + if (!opts.preventFocus && + (e.pageX >= opts.mouseDownX - opts.clickTolerance && e.pageX <= opts.mouseDownX + opts.clickTolerance) && + (e.pageY >= opts.mouseDownY - opts.clickTolerance && e.pageY <= opts.mouseDownY + opts.clickTolerance) + ) { + opts.mouseDownX = null; + opts.mouseDownY = null; + runByond('byond://winset?mapwindow.map.focus=true'); + } + }); + + $messages.on('click', 'a', function(e) { + var href = $(this).attr('href'); + if (href[0] == '?' || (href.length >= 8 && href.substring(0,8) == 'byond://')) { + runByond(href); + } else { + href = escaper(href); + runByond('?action=openLink&link='+href); + } + }); + + //Fuck everything about this event. Will look into alternatives. + $('body').on('keydown', function(e) { + if (e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA') { + return; + } + + if (e.ctrlKey || e.altKey || e.shiftKey) { //Band-aid "fix" for allowing ctrl+c copy paste etc. Needs a proper fix. + return; + } + + e.preventDefault() + + var k = e.which; + var command; // Command to execute through winset. + + // Hardcoded because else there would be no feedback message. + if (k == 113) { // F2 + runByond('byond://winset?screenshot=auto'); + output('Screenshot taken', 'internal'); + } + + var c = ""; + switch (k) { + case 8: + c = 'BACK'; + case 9: + c = 'TAB'; + case 13: + c = 'ENTER'; + case 19: + c = 'PAUSE'; + case 27: + c = 'ESCAPE'; + case 33: // Page up + c = 'NORTHEAST'; + case 34: // Page down + c = 'SOUTHEAST'; + case 35: // End + c = 'SOUTHWEST'; + case 36: // Home + c = 'NORTHWEST'; + case 37: + c = 'WEST'; + case 38: + c = 'NORTH'; + case 39: + c = 'EAST'; + case 40: + c = 'SOUTH'; + case 45: + c = 'INSERT'; + case 46: + c = 'DELETE'; + case 93: // That weird thing to the right of alt gr. + c = 'APPS'; + + default: + c = String.fromCharCode(k); + } + + if(opts.macros.hasOwnProperty(c.toUpperCase())) + command = opts.macros[c]; + + if (command) { + runByond('byond://winset?mapwindow.map.focus=true;command='+command); + return false; + } + else if (c.length == 0) { + if (!e.shiftKey) { + c = c.toLowerCase(); + } + runByond('byond://winset?mapwindow.map.focus=true;mainwindow.input.text='+c); + return false; + } else { + runByond('byond://winset?mapwindow.map.focus=true'); + return false; + } + }); + + //Mildly hacky fix for scroll issues on mob change (interface gets resized sometimes, messing up snap-scroll) + $(window).on('resize', function(e) { + if ($(this).height() !== opts.priorChatHeight) { + $('body,html').scrollTop($messages.outerHeight()); + opts.priorChatHeight = $(this).height(); + } + }); + + //Audio sound prevention + $messages.on('click', '.stopAudio', function() { + var $audio = $(this).parent().children('audio'); + if ($audio) { + $audio.remove(); + } + }); + + + /***************************************** + * + * OPTIONS INTERFACE EVENTS + * + ******************************************/ + + $('body').on('click', '#newMessages', function(e) { + var messagesHeight = $messages.outerHeight(); + $('body,html').scrollTop(messagesHeight); + $('#newMessages').remove(); + }); + + $('#toggleOptions').click(function(e) { + if ($subOptions.is(':visible')) { + $subOptions.slideUp('fast', function() { + $(this).removeClass('scroll'); + $(this).css('height', ''); + }); + clearInterval(opts.subOptionsLoop); + } else { + $subOptions.slideDown('fast', function() { + var windowHeight = $(window).height(); + var toggleHeight = $('#toggleOptions').outerHeight(); + var priorSubHeight = $subOptions.outerHeight(); + var newSubHeight = windowHeight - toggleHeight; + $(this).height(newSubHeight); + if (priorSubHeight > (windowHeight - toggleHeight)) { + $(this).addClass('scroll'); + } + }); + opts.subOptionsLoop = setInterval(function() { + if (!opts.suppressOptionsClose && $('#subOptions').is(':visible')) { + $subOptions.slideUp('fast', function() { + $(this).removeClass('scroll'); + $(this).css('height', ''); + }); + clearInterval(opts.subOptionsLoop); + } + }, 5000); //Every 5 seconds + } + }); + + $('#subOptions, #toggleOptions').mouseenter(function() { + opts.suppressOptionsClose = true; + }); + + $('#subOptions, #toggleOptions').mouseleave(function() { + opts.suppressOptionsClose = false; + }); + + $('#decreaseFont').click(function(e) { + var fontSize = parseInt($messages.css('font-size')); + fontSize = fontSize - 1 + 'px'; + $messages.css({'font-size': fontSize}); + setCookie('fontsize', fontSize, 365); + output('Font size set to '+fontSize+'', 'internal'); + }); + + $('#increaseFont').click(function(e) { + var fontSize = parseInt($messages.css('font-size')); + fontSize = fontSize + 1 + 'px'; + $messages.css({'font-size': fontSize}); + setCookie('fontsize', fontSize, 365); + output('Font size set to '+fontSize+'', 'internal'); + }); + + $('#chooseFont').click(function(e) { + if ($('.popup .changeFont').is(':visible')) {return;} + var popupContent = '
Change Font
' + + ''; + createPopup(popupContent, 200); + }); + + $('body').on('click', '#changeFont a', function(e) { + var font = $(this).attr('data-font'); + $messages.css('font-family', font); + setCookie('fonttype', font, 365); + }); + + $('#togglePing').click(function(e) { + if (opts.pingDisabled) { + $('#ping').slideDown('fast'); + opts.pingDisabled = false; + } else { + $('#ping').slideUp('fast'); + opts.pingDisabled = true; + } + setCookie('pingdisabled', (opts.pingDisabled ? 'true' : 'false'), 365); + }); + + $('#saveLog').click(function(e) { + var saved = ''; + + if (window.XMLHtpRequest) { + xmlHttp = new XMLHttpRequest(); + } else { + xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + xmlHttp.open('GET', 'browserOutput.css', false); + xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xmlHttp.send(); + saved += ''; + + saved += $messages.html(); + saved = saved.replace(/&/g, '&'); + saved = saved.replace(/
'; + } + var popupContent = '
String Highlighting
' + + '
' + + '
Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
' + + '
' + + termInputs + + '
' + + '
' + + '
' + + '
'; + createPopup(popupContent, 250); + }); + + $('body').on('keyup', '#highlightColor', function() { + var color = $('#highlightColor').val(); + color = color.trim(); + if (!color || color.charAt(0) != '#') return; + $('#highlightColor').css('background-color', color); + }); + + $('body').on('submit', '#highlightTermForm', function(e) { + e.preventDefault(); + + var count = 0; + while (count < opts.highlightLimit) { + var term = $('#highlightTermInput'+count).val(); + if (term) { + term = term.trim(); + if (term === '') { + opts.highlightTerms[count] = null; + } else { + opts.highlightTerms[count] = term.toLowerCase(); + } + } else { + opts.highlightTerms[count] = null; + } + count++; + } + + var color = $('#highlightColor').val(); + color = color.trim(); + if (color == '' || color.charAt(0) != '#') { + opts.highlightColor = '#FFFF00'; + } else { + opts.highlightColor = color; + } + var $popup = $('#highlightPopup').closest('.popup'); + $popup.remove(); + + setCookie('highlightterms', JSON.stringify(opts.highlightTerms), 365); + setCookie('highlightcolor', opts.highlightColor, 365); + }); + + $('#clearMessages').click(function() { + $messages.empty(); + opts.messageCount = 0; + }); + + // Tell BYOND to give us a macro list. + // I don't know why but for some retarded reason, + // You need to activate hotkeymode before you can winget the macros in it. + runByond('byond://winset?id=mainwindow¯o=hotkeymode') + runByond('byond://winset?id=mainwindow¯o=macro') + + runByond('byond://winget?callback=wingetMacros&id=hotkeymode.*&property=command'); + + /***************************************** + * + * KICK EVERYTHING OFF + * + ******************************************/ + + runByond('?_src_=chat&proc=doneLoading'); + if ($('#loading').is(':visible')) { + $('#loading').remove(); + } + $('#userBar').show(); + opts.priorChatHeight = $(window).height(); +}); diff --git a/goon/browserassets/js/jquery.min.js b/goon/browserassets/js/jquery.min.js new file mode 100644 index 00000000000..c5c648255c1 --- /dev/null +++ b/goon/browserassets/js/jquery.min.js @@ -0,0 +1,9789 @@ +/*! + * jQuery JavaScript Library v1.10.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:48Z + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<10 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.10.2", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( jQuery.support.ownLast ) { + for ( key in obj ) { + return core_hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.10.2 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + + var all, a, input, select, fragment, opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Finish early in limited (non-browser) environments + all = div.getElementsByTagName("*") || []; + a = div.getElementsByTagName("a")[ 0 ]; + if ( !a || !a.style || !all.length ) { + return support; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName("tbody").length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName("link").length; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + support.opacity = /^0.5/.test( a.style.opacity ); + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!a.style.cssFloat; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; + + // Will be defined later + support.inlineBlockNeedsLayout = false; + support.shrinkWrapBlocks = false; + support.pixelPosition = false; + support.deleteExpando = true; + support.noCloneEvent = true; + support.reliableMarginRight = true; + support.boxSizingReliable = true; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: IE<9 + // Iteration over object's inherited properties before its own. + for ( i in jQuery( support ) ) { + break; + } + support.ownLast = i !== "0"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior. + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})({}); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "applet": true, + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + data = null, + i = 0, + elem = this[0]; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( name.indexOf("data-") === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // Use proper attribute retrieval(#6932, #12072) + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + jQuery.expr.attrHandle[ name ] = fn; + return ret; + } : + function( elem, name, isXML ) { + return isXML ? + undefined : + elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = + // Some attributes are constructed with empty-string values when not defined + function( elem, name, isXML ) { + var ret; + return isXML ? + undefined : + (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + }; + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ret.specified ? + ret.value : + undefined; + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = ret.push( cur ); + break; + } + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery("